From faf978cab1ef0d899a7e4b2bd96a16216b21ed8d Mon Sep 17 00:00:00 2001 From: Sultan Alsawaf Date: Fri, 9 Jul 2021 21:46:09 -0700 Subject: [PATCH] mm: vmpressure: Fix a race that would erroneously clear accumulated data Since the code that determines whether data should be cleared and the code that actually clears the data are in separate spin-locked critical sections, new data could be generated on another CPU after it is determined that the existing data should be cleared, but before the current CPU clears the existing data. This would cause the new data reported by the other CPU to be lost. Fix the race by clearing accumulated data within the same spin-locked critical section that determines whether or not data should be cleared. Signed-off-by: Sultan Alsawaf --- mm/vmpressure.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mm/vmpressure.c b/mm/vmpressure.c index df96c5b561ea..50f4134e65cf 100755 --- a/mm/vmpressure.c +++ b/mm/vmpressure.c @@ -353,8 +353,8 @@ static void vmpressure_global(gfp_t gfp, unsigned long scanned, bool critical, if (critical) scanned = calculate_vmpressure_win(); + spin_lock(&vmpr->sr_lock); if (scanned) { - spin_lock(&vmpr->sr_lock); vmpr->scanned += scanned; vmpr->reclaimed += reclaimed; @@ -364,13 +364,12 @@ static void vmpressure_global(gfp_t gfp, unsigned long scanned, bool critical, stall = vmpr->stall; scanned = vmpr->scanned; reclaimed = vmpr->reclaimed; - spin_unlock(&vmpr->sr_lock); - if (!critical && scanned < calculate_vmpressure_win()) + if (!critical && scanned < calculate_vmpressure_win()) { + spin_unlock(&vmpr->sr_lock); return; + } } - - spin_lock(&vmpr->sr_lock); vmpr->scanned = 0; vmpr->reclaimed = 0; vmpr->stall = 0;