Merge remote-tracking branch 'regmap/fix/debugfs' into tmp
[cascardo/linux.git] / mm / hugetlb.c
index 88e7293..4f3ea0b 100644 (file)
@@ -1906,14 +1906,12 @@ static int __init hugetlb_init(void)
                default_hstate.max_huge_pages = default_hstate_max_huge_pages;
 
        hugetlb_init_hstates();
-
        gather_bootmem_prealloc();
-
        report_hugepages();
 
        hugetlb_sysfs_init();
-
        hugetlb_register_all_nodes();
+       hugetlb_cgroup_file_init();
 
        return 0;
 }
@@ -1943,13 +1941,6 @@ void __init hugetlb_add_hstate(unsigned order)
        h->next_nid_to_free = first_node(node_states[N_MEMORY]);
        snprintf(h->name, HSTATE_NAME_LEN, "hugepages-%lukB",
                                        huge_page_size(h)/1024);
-       /*
-        * Add cgroup control files only if the huge page consists
-        * of more than two normal pages. This is because we use
-        * page[2].lru.next for storing cgoup details.
-        */
-       if (order >= HUGETLB_CGROUP_MIN_ORDER)
-               hugetlb_cgroup_file_init(hugetlb_max_hstate - 1);
 
        parsed_hstate = h;
 }
@@ -3016,7 +3007,7 @@ same_page:
        return i ? i : -EFAULT;
 }
 
-void hugetlb_change_protection(struct vm_area_struct *vma,
+unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
                unsigned long address, unsigned long end, pgprot_t newprot)
 {
        struct mm_struct *mm = vma->vm_mm;
@@ -3024,6 +3015,7 @@ void hugetlb_change_protection(struct vm_area_struct *vma,
        pte_t *ptep;
        pte_t pte;
        struct hstate *h = hstate_vma(vma);
+       unsigned long pages = 0;
 
        BUG_ON(address >= end);
        flush_cache_range(vma, address, end);
@@ -3034,12 +3026,15 @@ void hugetlb_change_protection(struct vm_area_struct *vma,
                ptep = huge_pte_offset(mm, address);
                if (!ptep)
                        continue;
-               if (huge_pmd_unshare(mm, &address, ptep))
+               if (huge_pmd_unshare(mm, &address, ptep)) {
+                       pages++;
                        continue;
+               }
                if (!huge_pte_none(huge_ptep_get(ptep))) {
                        pte = huge_ptep_get_and_clear(mm, address, ptep);
                        pte = pte_mkhuge(pte_modify(pte, newprot));
                        set_huge_pte_at(mm, address, ptep, pte);
+                       pages++;
                }
        }
        spin_unlock(&mm->page_table_lock);
@@ -3051,6 +3046,8 @@ void hugetlb_change_protection(struct vm_area_struct *vma,
         */
        flush_tlb_range(vma, start, end);
        mutex_unlock(&vma->vm_file->f_mapping->i_mmap_mutex);
+
+       return pages << h->order;
 }
 
 int hugetlb_reserve_pages(struct inode *inode,