thp: remove unnecessary tlb flush for mprotect
[platform/adaptation/renesas_rcar/renesas_kernel.git] / mm / huge_memory.c
index 36b3d98..964fc5a 100644 (file)
@@ -487,41 +487,68 @@ static struct attribute_group khugepaged_attr_group = {
        .attrs = khugepaged_attr,
        .name = "khugepaged",
 };
-#endif /* CONFIG_SYSFS */
 
-static int __init hugepage_init(void)
+static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj)
 {
        int err;
-#ifdef CONFIG_SYSFS
-       static struct kobject *hugepage_kobj;
-#endif
 
-       err = -EINVAL;
-       if (!has_transparent_hugepage()) {
-               transparent_hugepage_flags = 0;
-               goto out;
-       }
-
-#ifdef CONFIG_SYSFS
-       err = -ENOMEM;
-       hugepage_kobj = kobject_create_and_add("transparent_hugepage", mm_kobj);
-       if (unlikely(!hugepage_kobj)) {
+       *hugepage_kobj = kobject_create_and_add("transparent_hugepage", mm_kobj);
+       if (unlikely(!*hugepage_kobj)) {
                printk(KERN_ERR "hugepage: failed kobject create\n");
-               goto out;
+               return -ENOMEM;
        }
 
-       err = sysfs_create_group(hugepage_kobj, &hugepage_attr_group);
+       err = sysfs_create_group(*hugepage_kobj, &hugepage_attr_group);
        if (err) {
                printk(KERN_ERR "hugepage: failed register hugeage group\n");
-               goto out;
+               goto delete_obj;
        }
 
-       err = sysfs_create_group(hugepage_kobj, &khugepaged_attr_group);
+       err = sysfs_create_group(*hugepage_kobj, &khugepaged_attr_group);
        if (err) {
                printk(KERN_ERR "hugepage: failed register hugeage group\n");
-               goto out;
+               goto remove_hp_group;
        }
-#endif
+
+       return 0;
+
+remove_hp_group:
+       sysfs_remove_group(*hugepage_kobj, &hugepage_attr_group);
+delete_obj:
+       kobject_put(*hugepage_kobj);
+       return err;
+}
+
+static void __init hugepage_exit_sysfs(struct kobject *hugepage_kobj)
+{
+       sysfs_remove_group(hugepage_kobj, &khugepaged_attr_group);
+       sysfs_remove_group(hugepage_kobj, &hugepage_attr_group);
+       kobject_put(hugepage_kobj);
+}
+#else
+static inline int hugepage_init_sysfs(struct kobject **hugepage_kobj)
+{
+       return 0;
+}
+
+static inline void hugepage_exit_sysfs(struct kobject *hugepage_kobj)
+{
+}
+#endif /* CONFIG_SYSFS */
+
+static int __init hugepage_init(void)
+{
+       int err;
+       struct kobject *hugepage_kobj;
+
+       if (!has_transparent_hugepage()) {
+               transparent_hugepage_flags = 0;
+               return -EINVAL;
+       }
+
+       err = hugepage_init_sysfs(&hugepage_kobj);
+       if (err)
+               return err;
 
        err = khugepaged_slab_init();
        if (err)
@@ -545,7 +572,9 @@ static int __init hugepage_init(void)
 
        set_recommended_min_free_kbytes();
 
+       return 0;
 out:
+       hugepage_exit_sysfs(hugepage_kobj);
        return err;
 }
 module_init(hugepage_init)
@@ -1116,7 +1145,6 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
                        entry = pmd_modify(entry, newprot);
                        set_pmd_at(mm, addr, pmd, entry);
                        spin_unlock(&vma->vm_mm->page_table_lock);
-                       flush_tlb_range(vma, addr, addr + HPAGE_PMD_SIZE);
                        ret = 1;
                }
        } else
@@ -1207,6 +1235,8 @@ static void __split_huge_page_refcount(struct page *page)
        /* prevent PageLRU to go away from under us, and freeze lru stats */
        spin_lock_irq(&zone->lru_lock);
        compound_lock(page);
+       /* complete memcg works before add pages to LRU */
+       mem_cgroup_split_huge_fixup(page);
 
        for (i = 1; i < HPAGE_PMD_NR; i++) {
                struct page *page_tail = page + i;
@@ -1278,7 +1308,6 @@ static void __split_huge_page_refcount(struct page *page)
                BUG_ON(!PageDirty(page_tail));
                BUG_ON(!PageSwapBacked(page_tail));
 
-               mem_cgroup_split_huge_fixup(page, page_tail);
 
                lru_add_page_tail(zone, page, page_tail);
        }