diff options
author | Namhoon Kim <namhoonk@cs.unc.edu> | 2017-05-17 13:27:24 -0400 |
---|---|---|
committer | Namhoon Kim <namhoonk@cs.unc.edu> | 2017-05-17 13:27:24 -0400 |
commit | fa0a28ee893e8e698263b0bbddee8d541d4c86a6 (patch) | |
tree | d173c5d8e35c88d8f96786ce06e9ca11d207b1bc | |
parent | 66efd4423f46259c73f25ff36b35bf69b48ae30b (diff) |
bank_proc patch
-rw-r--r-- | litmus/bank_proc.c | 250 |
1 files changed, 150 insertions, 100 deletions
diff --git a/litmus/bank_proc.c b/litmus/bank_proc.c index 2fac8d06f242..097cff177a2d 100644 --- a/litmus/bank_proc.c +++ b/litmus/bank_proc.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * bank_proc.c -- Implementation of the page coloring for cache and bank partition. | 2 | * bank_proc.c -- Implementation of the page coloring for cache and bank partition. |
3 | * The file will keep a pool of colored pages. Users can require pages with | 3 | * The file will keep a pool of colored pages. Users can require pages with |
4 | * specific color or bank number. | 4 | * specific color or bank number. |
5 | * Part of the code is modified from Jonathan Herman's code | 5 | * Part of the code is modified from Jonathan Herman's code |
6 | */ | 6 | */ |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
@@ -24,12 +24,13 @@ | |||
24 | // This Address Decoding is used in imx6-sabredsd platform | 24 | // This Address Decoding is used in imx6-sabredsd platform |
25 | #define BANK_MASK 0x38000000 | 25 | #define BANK_MASK 0x38000000 |
26 | #define BANK_SHIFT 27 | 26 | #define BANK_SHIFT 27 |
27 | |||
28 | #define CACHE_MASK 0x0000f000 | 27 | #define CACHE_MASK 0x0000f000 |
29 | #define CACHE_SHIFT 12 | 28 | #define CACHE_SHIFT 12 |
30 | 29 | ||
31 | #define PAGES_PER_COLOR 2000 | 30 | #define PAGES_PER_COLOR 2000 |
32 | #define PAGES_PER_COLOR_HALF 1000 | 31 | #define NUM_BANKS 8 |
32 | #define NUM_COLORS 16 | ||
33 | |||
33 | unsigned int NUM_PAGE_LIST; //8*16 | 34 | unsigned int NUM_PAGE_LIST; //8*16 |
34 | 35 | ||
35 | unsigned int number_banks; | 36 | unsigned int number_banks; |
@@ -45,15 +46,15 @@ int refill_page_pool = 0; | |||
45 | spinlock_t reclaim_lock; | 46 | spinlock_t reclaim_lock; |
46 | 47 | ||
47 | unsigned int set_partition[9] = { | 48 | unsigned int set_partition[9] = { |
48 | 0x0000000f, /* Core 0, and Level A*/ | 49 | 0x00000003, /* Core 0, and Level A*/ |
49 | 0x0000000f, /* Core 0, and Level B*/ | 50 | 0x00000003, /* Core 0, and Level B*/ |
50 | 0x000000f0, /* Core 1, and Level A*/ | 51 | 0x0000000C, /* Core 1, and Level A*/ |
51 | 0x000000f0, /* Core 1, and Level B*/ | 52 | 0x0000000C, /* Core 1, and Level B*/ |
52 | 0x00000f00, /* Core 2, and Level A*/ | 53 | 0x00000030, /* Core 2, and Level A*/ |
53 | 0x00000f00, /* Core 2, and Level B*/ | 54 | 0x00000030, /* Core 2, and Level B*/ |
54 | 0x0000f000, /* Core 3, and Level A*/ | 55 | 0x000000C0, /* Core 3, and Level A*/ |
55 | 0x0000f000, /* Core 3, and Level B*/ | 56 | 0x000000C0, /* Core 3, and Level B*/ |
56 | 0x0000ffff, /* Level C */ | 57 | 0x0000ff00, /* Level C */ |
57 | }; | 58 | }; |
58 | 59 | ||
59 | unsigned int bank_partition[9] = { | 60 | unsigned int bank_partition[9] = { |
@@ -76,8 +77,11 @@ unsigned int bank_index[9] = { | |||
76 | 0, 0, 0, 0, 0, 0, 0, 0, 0 | 77 | 0, 0, 0, 0, 0, 0, 0, 0, 0 |
77 | }; | 78 | }; |
78 | 79 | ||
79 | struct mutex void_lockdown_proc; | 80 | int node_index[9] = { |
81 | -1, -1, -1, -1, -1, -1, -1, -1, -1 | ||
82 | }; | ||
80 | 83 | ||
84 | struct mutex void_lockdown_proc; | ||
81 | 85 | ||
82 | /* | 86 | /* |
83 | * Every page list should contain a lock, a list, and a number recording how many pages it store | 87 | * Every page list should contain a lock, a list, and a number recording how many pages it store |
@@ -97,7 +101,6 @@ static struct color_group *color_groups; | |||
97 | */ | 101 | */ |
98 | unsigned int counting_one_set(unsigned int v) | 102 | unsigned int counting_one_set(unsigned int v) |
99 | { | 103 | { |
100 | // unsigned int v; // count the number of bits set in v | ||
101 | unsigned int c; // c accumulates the total bits set in v | 104 | unsigned int c; // c accumulates the total bits set in v |
102 | 105 | ||
103 | for (c = 0; v; v >>= 1) | 106 | for (c = 0; v; v >>= 1) |
@@ -137,7 +140,101 @@ unsigned int num_by_bitmask_index(unsigned int bitmask, unsigned int index) | |||
137 | return pos; | 140 | return pos; |
138 | } | 141 | } |
139 | 142 | ||
143 | /* helper functions to find the next colored pool index */ | ||
144 | static inline unsigned int first_index(unsigned long node) | ||
145 | { | ||
146 | unsigned int bank_no = 0, color_no = 0; | ||
147 | |||
148 | while(bank_no < NUM_BANKS) { | ||
149 | if ((bank_partition[node]>>bank_no) & 0x1) | ||
150 | break; | ||
151 | bank_no++; | ||
152 | } | ||
153 | while(color_no < NUM_COLORS) { | ||
154 | if ((set_partition[node]>>color_no) & 0x1) | ||
155 | break; | ||
156 | color_no++; | ||
157 | } | ||
158 | return NUM_COLORS*bank_no + color_no; | ||
159 | } | ||
160 | |||
161 | static inline unsigned int last_index(unsigned long node) | ||
162 | { | ||
163 | unsigned int bank_no = 7, color_no = 15; | ||
164 | |||
165 | while(bank_no >= 0) { | ||
166 | if ((bank_partition[node]>>bank_no) & 0x1) | ||
167 | break; | ||
168 | bank_no--; | ||
169 | } | ||
170 | while(color_no >= 0) { | ||
171 | if ((set_partition[node]>>color_no) & 0x1) | ||
172 | break; | ||
173 | color_no--; | ||
174 | } | ||
175 | return NUM_COLORS*bank_no + color_no; | ||
176 | } | ||
140 | 177 | ||
178 | static inline unsigned int next_color(unsigned long node, unsigned int current_color) | ||
179 | { | ||
180 | int try = 0, ret = 0; | ||
181 | current_color++; | ||
182 | if (current_color == NUM_COLORS) { | ||
183 | current_color = 0; | ||
184 | ret = 1; | ||
185 | } | ||
186 | |||
187 | while (try < NUM_COLORS) { | ||
188 | if ((set_partition[node]>>current_color)&0x1) | ||
189 | break; | ||
190 | current_color++; | ||
191 | if (current_color == NUM_COLORS) { | ||
192 | current_color = 0; | ||
193 | ret = 1; | ||
194 | } | ||
195 | try++; | ||
196 | } | ||
197 | if (!ret) | ||
198 | return current_color; | ||
199 | else | ||
200 | return current_color + NUM_COLORS; | ||
201 | } | ||
202 | |||
203 | static inline unsigned int next_bank(unsigned long node, unsigned int current_bank) | ||
204 | { | ||
205 | int try = 0; | ||
206 | current_bank++; | ||
207 | if (current_bank == NUM_BANKS) { | ||
208 | current_bank = 0; | ||
209 | } | ||
210 | |||
211 | while (try < NUM_BANKS) { | ||
212 | if ((bank_partition[node]>>current_bank)&0x1) | ||
213 | break; | ||
214 | current_bank++; | ||
215 | if (current_bank == NUM_BANKS) { | ||
216 | current_bank = 0; | ||
217 | } | ||
218 | try++; | ||
219 | } | ||
220 | return current_bank; | ||
221 | } | ||
222 | |||
223 | static inline unsigned int get_next_index(unsigned long node, unsigned int current_index) | ||
224 | { | ||
225 | unsigned int bank_no, color_no, color_ret, bank_ret; | ||
226 | bank_no = current_index>>4; // 2^4 = 16 colors | ||
227 | color_no = current_index - bank_no*NUM_COLORS; | ||
228 | bank_ret = bank_no; | ||
229 | color_ret = next_color(node, color_no); | ||
230 | if (color_ret >= NUM_COLORS) { | ||
231 | // next bank | ||
232 | color_ret -= NUM_COLORS; | ||
233 | bank_ret = next_bank(node, bank_no); | ||
234 | } | ||
235 | |||
236 | return bank_ret * NUM_COLORS + color_ret; | ||
237 | } | ||
141 | 238 | ||
142 | /* Decoding page color, 0~15 */ | 239 | /* Decoding page color, 0~15 */ |
143 | static inline unsigned int page_color(struct page *page) | 240 | static inline unsigned int page_color(struct page *page) |
@@ -155,8 +252,6 @@ static inline unsigned int page_list_index(struct page *page) | |||
155 | { | 252 | { |
156 | unsigned int idx; | 253 | unsigned int idx; |
157 | idx = (page_color(page) + page_bank(page)*(number_cachecolors)); | 254 | idx = (page_color(page) + page_bank(page)*(number_cachecolors)); |
158 | // printk("address = %lx, ", page_to_phys(page)); | ||
159 | // printk("color(%d), bank(%d), indx = %d\n", page_color(page), page_bank(page), idx); | ||
160 | 255 | ||
161 | return idx; | 256 | return idx; |
162 | } | 257 | } |
@@ -187,10 +282,10 @@ static void show_nr_pages(void) | |||
187 | printk("show nr pages***************************************\n"); | 282 | printk("show nr pages***************************************\n"); |
188 | for (i = 0; i < NUM_PAGE_LIST; ++i) { | 283 | for (i = 0; i < NUM_PAGE_LIST; ++i) { |
189 | cgroup = &color_groups[i]; | 284 | cgroup = &color_groups[i]; |
190 | printk("(%03d) = %03d, ", i, atomic_read(&cgroup->nr_pages)); | 285 | printk("(%03ld) = %03d, ", i, atomic_read(&cgroup->nr_pages)); |
191 | if((i % 8) ==7){ | 286 | if((i % 8) ==7) { |
192 | printk("\n"); | 287 | printk("\n"); |
193 | } | 288 | } |
194 | } | 289 | } |
195 | } | 290 | } |
196 | 291 | ||
@@ -214,11 +309,10 @@ void add_page_to_color_list(struct page *page) | |||
214 | * Replenish the page pool. | 309 | * Replenish the page pool. |
215 | * If the newly allocate page is what we want, it will be pushed to the correct page list | 310 | * If the newly allocate page is what we want, it will be pushed to the correct page list |
216 | * otherwise, it will be freed. | 311 | * otherwise, it will be freed. |
312 | * A user needs to invoke this function until the page pool has enough pages. | ||
217 | */ | 313 | */ |
218 | static int do_add_pages(void) | 314 | static int do_add_pages(void) |
219 | { | 315 | { |
220 | //printk("LITMUS do add pages\n"); | ||
221 | |||
222 | struct page *page, *page_tmp; | 316 | struct page *page, *page_tmp; |
223 | LIST_HEAD(free_later); | 317 | LIST_HEAD(free_later); |
224 | unsigned long color; | 318 | unsigned long color; |
@@ -227,16 +321,9 @@ static int do_add_pages(void) | |||
227 | int free_counter = 0; | 321 | int free_counter = 0; |
228 | unsigned long counter[128]= {0}; | 322 | unsigned long counter[128]= {0}; |
229 | 323 | ||
230 | //printk("Before refill : \n"); | ||
231 | //show_nr_pages(); | ||
232 | |||
233 | // until all the page lists contain enough pages | 324 | // until all the page lists contain enough pages |
234 | //for (i =0; i<5; i++) { | 325 | for (i=0; i< 1024*20;i++) { |
235 | for (i=0; i< 1024*100;i++) { | ||
236 | //while (smallest_nr_pages() < PAGES_PER_COLOR) { | ||
237 | // printk("smallest = %d\n", smallest_nr_pages()); | ||
238 | page = alloc_page(GFP_HIGHUSER_MOVABLE); | 326 | page = alloc_page(GFP_HIGHUSER_MOVABLE); |
239 | // page = alloc_pages_exact_node(0, GFP_HIGHUSER_MOVABLE, 0); | ||
240 | 327 | ||
241 | if (unlikely(!page)) { | 328 | if (unlikely(!page)) { |
242 | printk(KERN_WARNING "Could not allocate pages.\n"); | 329 | printk(KERN_WARNING "Could not allocate pages.\n"); |
@@ -245,57 +332,20 @@ static int do_add_pages(void) | |||
245 | } | 332 | } |
246 | color = page_list_index(page); | 333 | color = page_list_index(page); |
247 | counter[color]++; | 334 | counter[color]++; |
248 | // printk("page(%d) = color %x, bank %x, [color] =%d \n", color, page_color(page), page_bank(page), atomic_read(&color_groups[color].nr_pages)); | 335 | if (atomic_read(&color_groups[color].nr_pages) < PAGES_PER_COLOR && color>=0) { |
249 | //show_nr_pages(); | ||
250 | //if (atomic_read(&color_groups[color].nr_pages) < PAGES_PER_COLOR && color>=32) { | ||
251 | //if (atomic_read(&color_groups[color].nr_pages) < PAGES_PER_COLOR) { | ||
252 | //if ( PAGES_PER_COLOR && color>=16*2) { | ||
253 | //if (color>=32) { | ||
254 | if (color>=16) { | ||
255 | add_page_to_color_list(page); | 336 | add_page_to_color_list(page); |
256 | // printk("add page(%d) = color %x, bank %x\n", color, page_color(page), page_bank(page)); | 337 | } else { |
257 | } else{ | ||
258 | // Pages here will be freed later | 338 | // Pages here will be freed later |
259 | list_add_tail(&page->lru, &free_later); | 339 | list_add_tail(&page->lru, &free_later); |
260 | free_counter++; | 340 | free_counter++; |
261 | //list_del(&page->lru); | ||
262 | // __free_page(page); | ||
263 | // printk("useless page(%d) = color %x, bank %x\n", color, page_color(page), page_bank(page)); | ||
264 | } | 341 | } |
265 | //show_nr_pages(); | 342 | } |
266 | /* | ||
267 | if(free_counter >= PAGES_PER_COLOR) | ||
268 | { | ||
269 | printk("free unwanted page list eariler"); | ||
270 | free_counter = 0; | ||
271 | list_for_each_entry_safe(page, page_tmp, &free_later, lru) { | ||
272 | list_del(&page->lru); | ||
273 | __free_page(page); | ||
274 | } | ||
275 | |||
276 | show_nr_pages(); | ||
277 | } | ||
278 | */ | ||
279 | } | ||
280 | /* printk("page counter = \n"); | ||
281 | for (i=0; i<128; i++) | ||
282 | { | ||
283 | printk("(%03d) = %4d, ", i , counter[i]); | ||
284 | if(i%8 == 7){ | ||
285 | printk("\n"); | ||
286 | } | ||
287 | 343 | ||
288 | } | ||
289 | */ | ||
290 | //printk("After refill : \n"); | ||
291 | //show_nr_pages(); | ||
292 | #if 1 | ||
293 | // Free the unwanted pages | 344 | // Free the unwanted pages |
294 | list_for_each_entry_safe(page, page_tmp, &free_later, lru) { | 345 | list_for_each_entry_safe(page, page_tmp, &free_later, lru) { |
295 | list_del(&page->lru); | 346 | list_del(&page->lru); |
296 | __free_page(page); | 347 | __free_page(page); |
297 | } | 348 | } |
298 | #endif | ||
299 | out: | 349 | out: |
300 | return ret; | 350 | return ret; |
301 | } | 351 | } |
@@ -306,7 +356,7 @@ out: | |||
306 | * This function should not be accessed by others directly. | 356 | * This function should not be accessed by others directly. |
307 | * | 357 | * |
308 | */ | 358 | */ |
309 | static struct page *new_alloc_page_color( unsigned long color, int do_refill) | 359 | static struct page *new_alloc_page_color( unsigned long color) |
310 | { | 360 | { |
311 | // printk("allocate new page color = %d\n", color); | 361 | // printk("allocate new page color = %d\n", color); |
312 | struct color_group *cgroup; | 362 | struct color_group *cgroup; |
@@ -314,7 +364,6 @@ static struct page *new_alloc_page_color( unsigned long color, int do_refill) | |||
314 | 364 | ||
315 | if( (color <0) || (color)>(number_cachecolors*number_banks -1)) { | 365 | if( (color <0) || (color)>(number_cachecolors*number_banks -1)) { |
316 | TRACE_CUR("Wrong color %lu\n", color); | 366 | TRACE_CUR("Wrong color %lu\n", color); |
317 | // printk(KERN_WARNING "Wrong color %lu\n", color); | ||
318 | goto out; | 367 | goto out; |
319 | } | 368 | } |
320 | 369 | ||
@@ -323,7 +372,6 @@ static struct page *new_alloc_page_color( unsigned long color, int do_refill) | |||
323 | spin_lock(&cgroup->lock); | 372 | spin_lock(&cgroup->lock); |
324 | if (unlikely(!atomic_read(&cgroup->nr_pages))) { | 373 | if (unlikely(!atomic_read(&cgroup->nr_pages))) { |
325 | TRACE_CUR("No free %lu colored pages.\n", color); | 374 | TRACE_CUR("No free %lu colored pages.\n", color); |
326 | // printk(KERN_WARNING "no free %lu colored pages.\n", color); | ||
327 | goto out_unlock; | 375 | goto out_unlock; |
328 | } | 376 | } |
329 | rPage = list_first_entry(&cgroup->list, struct page, lru); | 377 | rPage = list_first_entry(&cgroup->list, struct page, lru); |
@@ -335,19 +383,12 @@ static struct page *new_alloc_page_color( unsigned long color, int do_refill) | |||
335 | out_unlock: | 383 | out_unlock: |
336 | spin_unlock(&cgroup->lock); | 384 | spin_unlock(&cgroup->lock); |
337 | out: | 385 | out: |
338 | if( smallest_nr_pages() == 0 && do_refill == 1) | ||
339 | { | ||
340 | do_add_pages(); | ||
341 | // printk("ERROR(bank_proc.c) = We don't have enough pages in bank_proc.c\n"); | ||
342 | |||
343 | } | ||
344 | |||
345 | return rPage; | 386 | return rPage; |
346 | } | 387 | } |
347 | 388 | ||
348 | struct page* get_colored_page(unsigned long color) | 389 | struct page* get_colored_page(unsigned long color) |
349 | { | 390 | { |
350 | return new_alloc_page_color(color, 1); | 391 | return new_alloc_page_color(color); |
351 | } | 392 | } |
352 | 393 | ||
353 | /* | 394 | /* |
@@ -364,23 +405,32 @@ struct page* get_colored_page(unsigned long color) | |||
364 | */ | 405 | */ |
365 | struct page *new_alloc_page(struct page *page, unsigned long node, int **x) | 406 | struct page *new_alloc_page(struct page *page, unsigned long node, int **x) |
366 | { | 407 | { |
367 | // printk("allocate new page node = %d\n", node); | ||
368 | // return alloc_pages_exact_node(node, GFP_HIGHUSER_MOVABLE, 0); | ||
369 | struct color_group *cgroup; | ||
370 | struct page *rPage = NULL; | 408 | struct page *rPage = NULL; |
371 | unsigned int color; | 409 | int try = 0; |
410 | unsigned int idx; | ||
372 | 411 | ||
373 | 412 | if (node_index[node] == -1) | |
374 | unsigned int idx = 0; | 413 | idx = first_index(node); |
375 | do { | 414 | else |
376 | idx += num_by_bitmask_index(set_partition[node], set_index[node]); | 415 | idx = node_index[node]; |
377 | idx += number_cachecolors* num_by_bitmask_index(bank_partition[node], bank_index[node]); | 416 | |
378 | rPage = new_alloc_page_color(idx, 0); | 417 | BUG_ON(idx<0 || idx>127); |
379 | } while (rPage == NULL); | 418 | rPage = new_alloc_page_color(idx); |
380 | 419 | if (node_index[node] == last_index(node)) | |
381 | 420 | node_index[node] = first_index(node); | |
382 | set_index[node] = (set_index[node]+1) % counting_one_set(set_partition[node]); | 421 | else |
383 | bank_index[node] = (bank_index[node]+1) % counting_one_set(bank_partition[node]); | 422 | node_index[node]++; |
423 | |||
424 | while (!rPage) { | ||
425 | try++; | ||
426 | if (try>=256) | ||
427 | break; | ||
428 | idx = get_next_index(node, idx); | ||
429 | printk(KERN_ALERT "try = %d out of page! requesting node = %ld, idx = %d\n", try, node, idx); | ||
430 | BUG_ON(idx<0 || idx>127); | ||
431 | rPage = new_alloc_page_color(idx); | ||
432 | } | ||
433 | node_index[node] = idx; | ||
384 | return rPage; | 434 | return rPage; |
385 | } | 435 | } |
386 | 436 | ||
@@ -391,20 +441,19 @@ struct page *new_alloc_page(struct page *page, unsigned long node, int **x) | |||
391 | void reclaim_page(struct page *page) | 441 | void reclaim_page(struct page *page) |
392 | { | 442 | { |
393 | const unsigned long color = page_list_index(page); | 443 | const unsigned long color = page_list_index(page); |
394 | unsigned long nr_reclaimed = 0; | ||
395 | spin_lock(&reclaim_lock); | 444 | spin_lock(&reclaim_lock); |
396 | put_page(page); | 445 | put_page(page); |
397 | add_page_to_color_list(page); | 446 | add_page_to_color_list(page); |
398 | 447 | ||
399 | spin_unlock(&reclaim_lock); | 448 | spin_unlock(&reclaim_lock); |
400 | printk("Reclaimed page(%d) = color %x, bank %x, [color] =%d \n", color, page_color(page), page_bank(page), atomic_read(&color_groups[color].nr_pages)); | 449 | printk("Reclaimed page(%ld) = color %x, bank %x, [color] =%d \n", color, page_color(page), page_bank(page), atomic_read(&color_groups[color].nr_pages)); |
401 | } | 450 | } |
402 | 451 | ||
403 | 452 | ||
404 | /* | 453 | /* |
405 | * Initialize the numbers of banks and cache colors | 454 | * Initialize the numbers of banks and cache colors |
406 | */ | 455 | */ |
407 | static int __init init_variables(void) | 456 | static void __init init_variables(void) |
408 | { | 457 | { |
409 | number_banks = counting_one_set(BANK_MASK); | 458 | number_banks = counting_one_set(BANK_MASK); |
410 | number_banks = two_exp(number_banks); | 459 | number_banks = two_exp(number_banks); |
@@ -489,7 +538,7 @@ out: | |||
489 | int show_page_pool_handler(struct ctl_table *table, int write, void __user *buffer, | 538 | int show_page_pool_handler(struct ctl_table *table, int write, void __user *buffer, |
490 | size_t *lenp, loff_t *ppos) | 539 | size_t *lenp, loff_t *ppos) |
491 | { | 540 | { |
492 | int ret = 0, i = 0; | 541 | int ret = 0; |
493 | mutex_lock(&void_lockdown_proc); | 542 | mutex_lock(&void_lockdown_proc); |
494 | ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); | 543 | ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); |
495 | if (ret) | 544 | if (ret) |
@@ -505,13 +554,14 @@ out: | |||
505 | int refill_page_pool_handler(struct ctl_table *table, int write, void __user *buffer, | 554 | int refill_page_pool_handler(struct ctl_table *table, int write, void __user *buffer, |
506 | size_t *lenp, loff_t *ppos) | 555 | size_t *lenp, loff_t *ppos) |
507 | { | 556 | { |
508 | int ret = 0, i = 0; | 557 | int ret = 0; |
509 | mutex_lock(&void_lockdown_proc); | 558 | mutex_lock(&void_lockdown_proc); |
510 | ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); | 559 | ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); |
511 | if (ret) | 560 | if (ret) |
512 | goto out; | 561 | goto out; |
513 | if (write) { | 562 | if (write) { |
514 | do_add_pages(); | 563 | do_add_pages(); |
564 | show_nr_pages(); | ||
515 | } | 565 | } |
516 | out: | 566 | out: |
517 | mutex_unlock(&void_lockdown_proc); | 567 | mutex_unlock(&void_lockdown_proc); |