diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-06-20 07:40:51 -0700 | 
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-06-20 07:40:51 -0700 | 
| commit | bc71c2df45e5a861818b5ee173702883df07471a (patch) | |
| tree | cd008493efad9dc936d0d2574f26dc6c9c7cb785 /mm/hugetlb.c | |
| parent | 76d15c8fba655c9b2d60cf01834858f2c44483dc (diff) | |
| parent | 33688abb2802ff3a230bd2441f765477b94cc89e (diff) | |
Merge 4.7-rc4 into usb-next
We need the 4.7-rc4 fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'mm/hugetlb.c')
| -rw-r--r-- | mm/hugetlb.c | 42 | 
1 files changed, 40 insertions, 2 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index d26162e81fea..388c2bb9b55c 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -832,8 +832,27 @@ static bool vma_has_reserves(struct vm_area_struct *vma, long chg)  	 * Only the process that called mmap() has reserves for  	 * private mappings.  	 */ -	if (is_vma_resv_set(vma, HPAGE_RESV_OWNER)) -		return true; +	if (is_vma_resv_set(vma, HPAGE_RESV_OWNER)) { +		/* +		 * Like the shared case above, a hole punch or truncate +		 * could have been performed on the private mapping. +		 * Examine the value of chg to determine if reserves +		 * actually exist or were previously consumed. +		 * Very Subtle - The value of chg comes from a previous +		 * call to vma_needs_reserves().  The reserve map for +		 * private mappings has different (opposite) semantics +		 * than that of shared mappings.  vma_needs_reserves() +		 * has already taken this difference in semantics into +		 * account.  Therefore, the meaning of chg is the same +		 * as in the shared case above.  Code could easily be +		 * combined, but keeping it separate draws attention to +		 * subtle differences. +		 */ +		if (chg) +			return false; +		else +			return true; +	}  	return false;  } @@ -1816,6 +1835,25 @@ static long __vma_reservation_common(struct hstate *h,  	if (vma->vm_flags & VM_MAYSHARE)  		return ret; +	else if (is_vma_resv_set(vma, HPAGE_RESV_OWNER) && ret >= 0) { +		/* +		 * In most cases, reserves always exist for private mappings. +		 * However, a file associated with mapping could have been +		 * hole punched or truncated after reserves were consumed. +		 * As subsequent fault on such a range will not use reserves. +		 * Subtle - The reserve map for private mappings has the +		 * opposite meaning than that of shared mappings.  If NO +		 * entry is in the reserve map, it means a reservation exists. +		 * If an entry exists in the reserve map, it means the +		 * reservation has already been consumed.  As a result, the +		 * return value of this routine is the opposite of the +		 * value returned from reserve map manipulation routines above. +		 */ +		if (ret) +			return 0; +		else +			return 1; +	}  	else  		return ret < 0 ? ret : 0;  }  | 
