diff options
Diffstat (limited to 'mm/hugetlb.c')
| -rw-r--r-- | mm/hugetlb.c | 20 | 
1 files changed, 17 insertions, 3 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 0a0be33bb19..1a12f5b9a0a 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2124,8 +2124,12 @@ int hugetlb_report_node_meminfo(int nid, char *buf)  /* Return the number pages of memory we physically have, in PAGE_SIZE units. */  unsigned long hugetlb_total_pages(void)  { -	struct hstate *h = &default_hstate; -	return h->nr_huge_pages * pages_per_huge_page(h); +	struct hstate *h; +	unsigned long nr_total_pages = 0; + +	for_each_hstate(h) +		nr_total_pages += h->nr_huge_pages * pages_per_huge_page(h); +	return nr_total_pages;  }  static int hugetlb_acct_memory(struct hstate *h, long delta) @@ -2957,7 +2961,17 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,  			break;  		} -		if (absent || +		/* +		 * We need call hugetlb_fault for both hugepages under migration +		 * (in which case hugetlb_fault waits for the migration,) and +		 * hwpoisoned hugepages (in which case we need to prevent the +		 * caller from accessing to them.) In order to do this, we use +		 * here is_swap_pte instead of is_hugetlb_entry_migration and +		 * is_hugetlb_entry_hwpoisoned. This is because it simply covers +		 * both cases, and because we can't follow correct pages +		 * directly from any kind of swap entries. +		 */ +		if (absent || is_swap_pte(huge_ptep_get(pte)) ||  		    ((flags & FOLL_WRITE) && !pte_write(huge_ptep_get(pte)))) {  			int ret;  |