History

mlock: fix mlock count can not decrease in race condition

Kefeng reported that when running the follow test, the mlock count in meminfo will increase permanently: [1] testcase linux:~ # cat test_mlockal grep Mlocked /proc/meminfo for j in `seq 0 10` do for i in `seq 4 15` do ./p_mlockall >> log & done sleep 0.2 done # wait some time to let mlock counter decrease and 5s may not enough sleep 5 grep Mlocked /proc/meminfo linux:~ # cat p_mlockall.c #include <sys/mman.h> #include <stdlib.h> #include <stdio.h> #define SPACE_LEN 4096 int main(int argc, char ** argv) { int ret; void *adr = malloc(SPACE_LEN); if (!adr) return -1; ret = mlockall(MCL_CURRENT | MCL_FUTURE); printf("mlcokall ret = %d\n", ret); ret = munlockall(); printf("munlcokall ret = %d\n", ret); free(adr); return 0; } In __munlock_pagevec() we should decrement NR_MLOCK for each page where we clear the PageMlocked flag. Commit 1ebb7cc6a583 ("mm: munlock: batch NR_MLOCK zone state updates") has introduced a bug where we don't decrement NR_MLOCK for pages where we clear the flag, but fail to isolate them from the lru list (e.g. when the pages are on some other cpu's percpu pagevec). Since PageMlocked stays cleared, the NR_MLOCK accounting gets permanently disrupted by this. Fix it by counting the number of page whose PageMlock flag is cleared.

Yisheng Xie committed 9 years ago

Commit 70feee01 parent 30809f51 file · +3 −2Browse files

Unified · Split

mm/mlock.c+3−2
@@ -284,7 +284,7 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone) · 283 unmodified lines
284{284{
285 int i;285 int i;
286 int nr = pagevec_count(pvec);286 int nr = pagevec_count(pvec);
287 int delta_munlocked;287 int delta_munlocked = -nr;
288 struct pagevec pvec_putback;288 struct pagevec pvec_putback;
289 int pgrescued = 0;289 int pgrescued = 0;
290 290
@@ -304,6 +304,8 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone) · 13 unmodified lines
304 continue;304 continue;
305 else305 else
306 __munlock_isolation_failed(page);306 __munlock_isolation_failed(page);
307 } else {
308 delta_munlocked++;
307 }309 }
308 310
309 /*311 /*
@@ -315,7 +317,6 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone) · 5 unmodified lines
315 pagevec_add(&pvec_putback, pvec->pages[i]);317 pagevec_add(&pvec_putback, pvec->pages[i]);
316 pvec->pages[i] = NULL;318 pvec->pages[i] = NULL;
317 }319 }
318 delta_munlocked = -nr + pagevec_count(&pvec_putback);
319 __mod_zone_page_state(zone, NR_MLOCK, delta_munlocked);320 __mod_zone_page_state(zone, NR_MLOCK, delta_munlocked);
320 spin_unlock_irq(zone_lru_lock(zone));321 spin_unlock_irq(zone_lru_lock(zone));
321 322

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t