The patch titled Subject: mlock: fix mlock count can not decrease in race condition has been added to the -mm tree. Its filename is mlock-fix-mlock-count-can-not-decrease-in-race-condition.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/mlock-fix-mlock-count-can-not-decrease-in-race-condition.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/mlock-fix-mlock-count-can-not-decrease-in-race-condition.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Yisheng Xie <xieyisheng1@xxxxxxxxxx> Subject: mlock: fix mlock count can not decrease in race condition Kefeng reported that when running the follow test the mlock count in meminfo cannot be decreased: [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 ClearPageMlock but isolation_failed is in a race condition, and we do not count these pages into delta_munlocked, which causes the mlock counter to be incorrect for we cleared the PageMlock and cannot count down the number in the future. Fix it by countin the number of pages whose PageMlock flag is cleared. Fixes: 1ebb7cc6a583 (" mm: munlock: batch NR_MLOCK zone state updates") Link: http://lkml.kernel.org/r/1495678405-54569-1-git-send-email-xieyisheng1@xxxxxxxxxx Signed-off-by: Yisheng Xie <xieyisheng1@xxxxxxxxxx> Reported-by: Kefeng Wang <wangkefeng.wang@xxxxxxxxxx> Tested-by: Kefeng Wang <wangkefeng.wang@xxxxxxxxxx> Cc: Vlastimil Babka <vbabka@xxxxxxx> Cc: Joern Engel <joern@xxxxxxxxx> Cc: Mel Gorman <mgorman@xxxxxxx> Cc: Michel Lespinasse <walken@xxxxxxxxxx> Cc: Hugh Dickins <hughd@xxxxxxxxxx> Cc: Rik van Riel <riel@xxxxxxxxxx> Cc: Johannes Weiner <hannes@xxxxxxxxxxx> Cc: Michal Hocko <mhocko@xxxxxxx> Cc: Xishi Qiu <qiuxishi@xxxxxxxxxx> Cc: zhongjiang <zhongjiang@xxxxxxxxxx> Cc: Hanjun Guo <guohanjun@xxxxxxxxxx> Cc: <stable@xxxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/mlock.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff -puN mm/mlock.c~mlock-fix-mlock-count-can-not-decrease-in-race-condition mm/mlock.c --- a/mm/mlock.c~mlock-fix-mlock-count-can-not-decrease-in-race-condition +++ a/mm/mlock.c @@ -284,7 +284,7 @@ static void __munlock_pagevec(struct pag { int i; int nr = pagevec_count(pvec); - int delta_munlocked; + int delta_munlocked = -nr; struct pagevec pvec_putback; int pgrescued = 0; @@ -304,6 +304,8 @@ static void __munlock_pagevec(struct pag continue; else __munlock_isolation_failed(page); + } else { + delta_munlocked++; } /* @@ -315,7 +317,6 @@ static void __munlock_pagevec(struct pag pagevec_add(&pvec_putback, pvec->pages[i]); pvec->pages[i] = NULL; } - delta_munlocked = -nr + pagevec_count(&pvec_putback); __mod_zone_page_state(zone, NR_MLOCK, delta_munlocked); spin_unlock_irq(zone_lru_lock(zone)); _ Patches currently in -mm which might be from xieyisheng1@xxxxxxxxxx are mlock-fix-mlock-count-can-not-decrease-in-race-condition.patch