@@ -85,6 +85,47 @@ struct khugepaged_scan {
85
85
.mm_head = LIST_HEAD_INIT (khugepaged_scan .mm_head ),
86
86
};
87
87
88
+
89
+ static int set_recommended_min_free_kbytes (void )
90
+ {
91
+ struct zone * zone ;
92
+ int nr_zones = 0 ;
93
+ unsigned long recommended_min ;
94
+ extern int min_free_kbytes ;
95
+
96
+ if (!test_bit (TRANSPARENT_HUGEPAGE_FLAG ,
97
+ & transparent_hugepage_flags ) &&
98
+ !test_bit (TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG ,
99
+ & transparent_hugepage_flags ))
100
+ return 0 ;
101
+
102
+ for_each_populated_zone (zone )
103
+ nr_zones ++ ;
104
+
105
+ /* Make sure at least 2 hugepages are free for MIGRATE_RESERVE */
106
+ recommended_min = pageblock_nr_pages * nr_zones * 2 ;
107
+
108
+ /*
109
+ * Make sure that on average at least two pageblocks are almost free
110
+ * of another type, one for a migratetype to fall back to and a
111
+ * second to avoid subsequent fallbacks of other types There are 3
112
+ * MIGRATE_TYPES we care about.
113
+ */
114
+ recommended_min += pageblock_nr_pages * nr_zones *
115
+ MIGRATE_PCPTYPES * MIGRATE_PCPTYPES ;
116
+
117
+ /* don't ever allow to reserve more than 5% of the lowmem */
118
+ recommended_min = min (recommended_min ,
119
+ (unsigned long ) nr_free_buffer_pages () / 20 );
120
+ recommended_min <<= (PAGE_SHIFT - 10 );
121
+
122
+ if (recommended_min > min_free_kbytes )
123
+ min_free_kbytes = recommended_min ;
124
+ setup_per_zone_wmarks ();
125
+ return 0 ;
126
+ }
127
+ late_initcall (set_recommended_min_free_kbytes );
128
+
88
129
static int start_khugepaged (void )
89
130
{
90
131
int err = 0 ;
@@ -108,6 +149,8 @@ static int start_khugepaged(void)
108
149
mutex_unlock (& khugepaged_mutex );
109
150
if (wakeup )
110
151
wake_up_interruptible (& khugepaged_wait );
152
+
153
+ set_recommended_min_free_kbytes ();
111
154
} else
112
155
/* wakeup to exit */
113
156
wake_up_interruptible (& khugepaged_wait );
@@ -177,6 +220,13 @@ static ssize_t enabled_store(struct kobject *kobj,
177
220
ret = err ;
178
221
}
179
222
223
+ if (ret > 0 &&
224
+ (test_bit (TRANSPARENT_HUGEPAGE_FLAG ,
225
+ & transparent_hugepage_flags ) ||
226
+ test_bit (TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG ,
227
+ & transparent_hugepage_flags )))
228
+ set_recommended_min_free_kbytes ();
229
+
180
230
return ret ;
181
231
}
182
232
static struct kobj_attribute enabled_attr =
@@ -464,6 +514,8 @@ static int __init hugepage_init(void)
464
514
465
515
start_khugepaged ();
466
516
517
+ set_recommended_min_free_kbytes ();
518
+
467
519
out :
468
520
return err ;
469
521
}
0 commit comments