From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D54812E0901; Mon, 1 Jun 2026 22:35:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780353334; cv=none; b=MrX6TIPHYn7/3wbziTLsm2Rch+AoxEcoZCHi9VxMX+4un0j3QplyM16WMJJQZc+G5ne0y69t/bb/fVFuuNrTBanz+ILVUrUKHPdZ+I8ceakkAjZHqRmwkUMXbyLZIqBJ/Tpny/gE4epPBS71BiQYSNayASVVF6Zv10Yb6p+OdqA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780353334; c=relaxed/simple; bh=A4FleZSqg+rPoPGPfeoksdbXKLCmutHC499UCBy/RNA=; h=Date:To:From:Subject:Message-Id; b=FQrg/xormoWaH0QHBUX9tT9FJTUhI7dMX1uKm1XsUzj+nfGWQm9iDh+aHSTqXZPp5TEqU8VQ9m+fzIqjmG6mR6YUTv0rOokPyBFx3bh5AnolMxL3yVYZ37S+q1MVMfR3t3E0DwATkMfwfrDM5CViqXxIpn/4qtz0apOwxyqD2e4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=Bn3Fw8Pu; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="Bn3Fw8Pu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4D2101F00893; Mon, 1 Jun 2026 22:35:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux-foundation.org; s=korg; t=1780353332; bh=8er/3vP7bHilypvLbWFTZP14tRaMOfVRhucokUYgb1A=; h=Date:To:From:Subject; b=Bn3Fw8PuxaM02DXsGPtBBRkeF0wQNhZRMNPXA9G3iPUifD4m/hvTARdldxH85AzZF ZoQObHVrw0YIQQuj5EuobgOTWXY0L1M/LuiTS/ClkRJLRFxCx65sOY986Aqbsbz5Vs ARdGSNfX/1DSp4CYNQhyAV5EbsOstsbeKN8M7rlg= Date: Mon, 01 Jun 2026 15:35:31 -0700 To: mm-commits@vger.kernel.org,stable@vger.kernel.org,roman.gushchin@linux.dev,muchun.song@linux.dev,kasong@tencent.com,hannes@cmpxchg.org,david@fromorbit.com,clm@fb.com,shakeel.butt@linux.dev,akpm@linux-foundation.org From: Andrew Morton Subject: + mm-list_lru-drain-before-clearing-xarray-entry-on-reparent.patch added to mm-hotfixes-unstable branch Message-Id: <20260601223532.4D2101F00893@smtp.kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: The patch titled Subject: mm/list_lru: drain before clearing xarray entry on reparent has been added to the -mm mm-hotfixes-unstable branch. Its filename is mm-list_lru-drain-before-clearing-xarray-entry-on-reparent.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-list_lru-drain-before-clearing-xarray-entry-on-reparent.patch This patch will later appear in the mm-hotfixes-unstable branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm 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/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via various branches at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there most days ------------------------------------------------------ From: Shakeel Butt Subject: mm/list_lru: drain before clearing xarray entry on reparent Date: Mon, 1 Jun 2026 09:15:01 -0700 memcg_reparent_list_lrus() clears the dying memcg's xarray entry with xas_store(&xas, NULL) before reparenting its per-node lists into the parent. This opens a window where a concurrent list_lru_del() arriving for the dying memcg sees xa_load() == NULL, walks to the parent in lock_list_lru_of_memcg(), takes the parent's per-node lock, and calls list_del_init() on an item still physically linked on the dying memcg's list. If another in-flight thread holds the dying memcg's per-node lock at the same moment (another list_lru_del, or a list_lru_walk_one running an isolate callback), both threads modify ->next/->prev pointers on the same physical list under different locks. Adjacent items can corrupt each other's links. Fix it by reversing the order: reparent each per-node list and mark the child's list lru dead and then clear the xarray entry. Any concurrent list_lru op that finds the still-set xarray entry either takes the dying memcg's per-node lock (synchronizing with the drain) or sees LONG_MIN and walks to the parent, where the items now live. Link: https://lore.kernel.org/20260601161501.1444829-1-shakeel.butt@linux.dev Fixes: fb56fdf8b9a2 ("mm/list_lru: split the lock to per-cgroup scope") Signed-off-by: Shakeel Butt Reported-by: Chris Mason Reviewed-by: Kairui Song Cc: Dave Chinner Cc: Johannes Weiner Cc: Muchun Song Cc: Roman Gushchin Cc: Signed-off-by: Andrew Morton --- mm/list_lru.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) --- a/mm/list_lru.c~mm-list_lru-drain-before-clearing-xarray-entry-on-reparent +++ a/mm/list_lru.c @@ -473,26 +473,29 @@ void memcg_reparent_list_lrus(struct mem mutex_lock(&list_lrus_mutex); list_for_each_entry(lru, &memcg_list_lrus, list) { struct list_lru_memcg *mlru; - XA_STATE(xas, &lru->xa, memcg->kmemcg_id); /* - * Lock the Xarray to ensure no on going list_lru_memcg - * allocation and further allocation will see css_is_dying(). + * css_is_dying() check in memcg_list_lru_alloc() avoids + * allocating a new mlru since CSS_DYING is already set for this + * memcg a rcu grace period ago. */ - xas_lock_irq(&xas); - mlru = xas_store(&xas, NULL); - xas_unlock_irq(&xas); + mlru = xa_load(&lru->xa, memcg->kmemcg_id); if (!mlru) continue; /* - * With Xarray value set to NULL, holding the lru lock below - * prevents list_lru_{add,del,isolate} from touching the lru, - * safe to reparent. + * Reparent each per-node list and mark the child dead + * (LONG_MIN) before clearing xarray entry otherwise a + * concurrent list_lru_del() may corrupt the list if it arrives + * after xarray clear but before reparenting as + * lock_list_lru_of_memcg will acquire parent's lock while the + * item is still on child's list. */ for_each_node(i) memcg_reparent_list_lru_one(lru, i, &mlru->node[i], parent); + xa_erase_irq(&lru->xa, memcg->kmemcg_id); + /* * Here all list_lrus corresponding to the cgroup are guaranteed * to remain empty, we can safely free this lru, any further _ Patches currently in -mm which might be from shakeel.butt@linux.dev are mm-list_lru-drain-before-clearing-xarray-entry-on-reparent.patch memcg-store-node_id-instead-of-pglist_data-pointer.patch memcg-uint16_t-for-nr_bytes-in-obj_stock_pcp.patch memcg-int16_t-for-cached-slab-stats.patch memcg-multi-objcg-charge-support.patch