From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qt1-f181.google.com (mail-qt1-f181.google.com [209.85.160.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D06352ED872 for ; Wed, 18 Mar 2026 19:25:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.181 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773861937; cv=none; b=RgFmQw3xt3amFPufHyDkktEGnMpaQCFXWMCneyn1OKT3XklCA4K11AwthuToAMoGujWhpeBvSL+wXdoPPhCBE8jLcMgx//dunZnXx3+ETCx28lqb90n3Nj1yPxLzhbjRUt0V9jzb8OG3sAx1DiLyNHK42wZ7hRH2wDSuFzv75yA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773861937; c=relaxed/simple; bh=nn3aWZP0nqyE0vqbyWLE5V0/ft6F8h7JdgJaYleSowM=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=Sf2ICGQiMI4CCnqgd5zQMMZsjz3LQPi7kTjTMRf8cJ4o/IcYK24DIX15geZWkII+M6a/8EtEaJa/jvuKEQr/HkP/cTXmUpmls0Biv8giCICTkmHtg8Awv+iHsFiX8km+QdY/BOfZps9zlo1cOs+CvW2IQnfAnR+Tn9VoT6IIJIA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cmpxchg.org; spf=pass smtp.mailfrom=cmpxchg.org; dkim=pass (2048-bit key) header.d=cmpxchg.org header.i=@cmpxchg.org header.b=hLhMFhxc; arc=none smtp.client-ip=209.85.160.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cmpxchg.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cmpxchg.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cmpxchg.org header.i=@cmpxchg.org header.b="hLhMFhxc" Received: by mail-qt1-f181.google.com with SMTP id d75a77b69052e-506aa685d62so1393411cf.0 for ; Wed, 18 Mar 2026 12:25:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cmpxchg.org; s=google; t=1773861933; x=1774466733; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=NducLCjpH3d8vRwvCq6m5Mw1JAEaZRFw3raao9vqHxw=; b=hLhMFhxcQWWOxDrFtyOLt84TJ7fuxO9iuc+hK3nEIppf68tCuk1tf2GIeVSJG6V01q KBFEFzhS9o57o1keMrG8dLIU9g1bkUy0qcoOO2lCfn1G+GnMlZ0i2uOtw+74USxDUUou DIm512hVvKQyUBhnXBpqVBXiloz79G/M1SUlFGHQEO9+ZF0INsZG6cCLgQTlDRxtmtj4 2mCAyZ2axHi3eAFTGwwQ+njEnL+1QzWk9LaQM7176IddbJAus4rtPczWqUnAl8jcLdMm YYr2vAQ98O4ctpMPW3hEKD4+uskWHucbJ/ZCGcYxDRpB20CDnnRLSP2cGeyKnGX5gGNw 1uLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773861933; x=1774466733; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NducLCjpH3d8vRwvCq6m5Mw1JAEaZRFw3raao9vqHxw=; b=EefebhY7fqv/Fw6fCFHlxhfGZGRYXrA2n3cPprhXdVCi/NisaTPhRo7UWXb7H4jntU 0R+ME+ot+9P8N4XPHshKKLaxNoRB0e6r3VabU1v/ZSwrXjemP5eq7g2tgUh7sbmagYk0 f5fREFediJp803YfOCMUlYyf5X3Y4SV/umk7BVr365P1cxOa5r20a/qs3p7jIKcMDghN Tmlv0EpT/RWWuLNqX3Y5u3ldb7lz67y5CUCvRM2JtGLgLnuP0cw7TJU50dEoG6Ayt5d+ mTsJjkERXr1v92+cRc0+hwFBzI7MnQ1ehK3lFaMGPJEbJlipggb6Qg8Kfjm9aUTwLgls Fgkg== X-Forwarded-Encrypted: i=1; AJvYcCWcZNZRydmduFBY93UVMa79EE2nGTgT20oCcTJC/NmdIQQHhY4hMgL8plFnooWhHI3pJ5XEQkw7wgT12Is=@vger.kernel.org X-Gm-Message-State: AOJu0YzYRfRVHXPSPRTulnLzsn8AdrutMjiZaDEEK3pXJcMl/7Qicbv+ bIKRz9aiOKmKNjh+SAOki2Lzp0g22llflTAwFPQsw6ZWgbGPHZNo2MapTbsiteZFH6c= X-Gm-Gg: ATEYQzy1WQ26bWb/bNld0ElV24JiBncXPpPHMtcQnEFLv9YXhPmIMlWkyARz0ei+K36 8jHjiqKbDh+zWSbmBn78grE+3Qg3u4IBRTHeGZlvuPsjl5l0nRCXPL6+bAtIJqIFI6j04ztvbNG PNxX+kZL/krEdOkOT7frOr9RTE+yNBOnmBpOQT961y4Hvz5+TBodxmbOj03SEiFRpjLaiYLc9dV DJImLJCIbBWIziD17A0k1sXKpx6aeQVgx/bjjttPPo0Vw+fewMOn4JAky1ZqA5pNIR4n/n+JpSV KKK4n6zTK1l3Yrvgz9U8b7CU61iUUcuyM9v36CNSCtwPbGAjEy8JfYw3+S9JqnaO0Tajhiy0r9Q x4xDENdOsB72VpTpTzN1UR5V2kyj86z+1r9NJ/OrdoJY6kTl2kGowiOk/1bayuP3P7PwuZZnf55 T3iELvbk/zBgVtyyGRhnXpwQ== X-Received: by 2002:a05:622a:589:b0:506:a075:b247 with SMTP id d75a77b69052e-50b14743959mr59908331cf.14.1773861933453; Wed, 18 Mar 2026 12:25:33 -0700 (PDT) Received: from localhost ([2603:7000:c00:3a00:365a:60ff:fe62:ff29]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-89c6b9ce61bsm32260176d6.23.2026.03.18.12.25.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Mar 2026 12:25:32 -0700 (PDT) Date: Wed, 18 Mar 2026 15:25:29 -0400 From: Johannes Weiner To: Shakeel Butt Cc: Andrew Morton , David Hildenbrand , Yosry Ahmed , Zi Yan , "Liam R. Howlett" , Usama Arif , Kiryl Shutsemau , Dave Chinner , Roman Gushchin , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v2 1/7] mm: list_lru: lock_list_lru_of_memcg() cannot return NULL if !skip_empty Message-ID: References: <20260312205321.638053-1-hannes@cmpxchg.org> <20260312205321.638053-2-hannes@cmpxchg.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: On Wed, Mar 18, 2026 at 10:56:55AM -0700, Shakeel Butt wrote: > On Thu, Mar 12, 2026 at 04:51:49PM -0400, Johannes Weiner wrote: > > skip_empty is only for the shrinker to abort and skip a list that's > > empty or whose cgroup is being deleted. > > > > For list additions and deletions, the cgroup hierarchy is walked > > upwards until a valid list_lru head is found, or it will fall back to > > the node list. Acquiring the lock won't fail. Remove the NULL checks > > in those callers. > > > > Signed-off-by: Johannes Weiner > > --- > > What do you think about squashing the following into this patch? > > From bd56ea4505f792e00079b1a8dd98cb6f7a5e7215 Mon Sep 17 00:00:00 2001 > From: Shakeel Butt > Date: Wed, 18 Mar 2026 10:43:53 -0700 > Subject: [PATCH] list_lru: cleanup > > Signed-off-by: Shakeel Butt Thanks for taking a look! There is some overlap and conflict between your delta and what later patches in the series do. AFAICS, the main thing left over would be: to have __lock_list_lru_of_memcg() for the reclaimer (which does not walk the parents during a cgroup deletion race) and lock_list_lru_of_memcg() which does. Thereby eliminating the @skip_empty bool. The downside would be to have another level in the lock function stack which is duplicated for CONFIG_MEMCG and !CONFIG_MEMCG, and the !CONFIG_MEMCG versions are identical. I'm not sure that's worth it? --- mm/list_lru.c | 50 +++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/mm/list_lru.c b/mm/list_lru.c index 1ccdd45b1d14..cab716d94ac5 100644 --- a/mm/list_lru.c +++ b/mm/list_lru.c @@ -83,13 +83,12 @@ list_lru_from_memcg_idx(struct list_lru *lru, int nid, int idx) } static inline struct list_lru_one * -lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg, - bool irq, unsigned long *irq_flags, bool skip_empty) +__lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg, + bool irq, unsigned long *irq_flags) { struct list_lru_one *l; rcu_read_lock(); -again: l = list_lru_from_memcg_idx(lru, nid, memcg_kmem_id(memcg)); if (likely(l)) { lock_list_lru(l, irq, irq_flags); @@ -99,18 +98,24 @@ lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg, } unlock_list_lru(l, irq, irq_flags); } - /* - * Caller may simply bail out if raced with reparenting or - * may iterate through the list_lru and expect empty slots. - */ - if (skip_empty) { - rcu_read_unlock(); - return NULL; + return NULL; +} + +static inline struct list_lru_one * +lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg, + bool irq, unsigned long *irq_flags) +{ + struct list_lru_one *l; + + for (;;) { + l = __lock_list_lru_of_memcg(lru, nid, memcg, irq, irq_flags); + if (likely(l)) + return l; + VM_WARN_ON(!css_is_dying(&memcg->css)); + memcg = parent_mem_cgroup(memcg); } - VM_WARN_ON(!css_is_dying(&memcg->css)); - memcg = parent_mem_cgroup(memcg); - goto again; } + #else static void list_lru_register(struct list_lru *lru) { @@ -137,8 +142,8 @@ list_lru_from_memcg_idx(struct list_lru *lru, int nid, int idx) } static inline struct list_lru_one * -lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg, - bool irq, unsigned long *irq_flags, bool skip_empty) +__lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg, + bool irq, unsigned long *irq_flags) { struct list_lru_one *l = &lru->node[nid].lru; @@ -146,13 +151,20 @@ lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg, return l; } + +static inline struct list_lru_one * +lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg, + bool irq, unsigned long *irq_flags) +{ + return __lock_list_lru_of_memcg(lru, nid, memcg, irq, irq_flags); +} #endif /* CONFIG_MEMCG */ struct list_lru_one *list_lru_lock(struct list_lru *lru, int nid, struct mem_cgroup *memcg) { return lock_list_lru_of_memcg(lru, nid, memcg, /*irq=*/false, - /*irq_flags=*/NULL, /*skip_empty=*/false); + /*irq_flags=*/NULL); } void list_lru_unlock(struct list_lru_one *l) @@ -165,7 +177,7 @@ struct list_lru_one *list_lru_lock_irqsave(struct list_lru *lru, int nid, unsigned long *flags) { return lock_list_lru_of_memcg(lru, nid, memcg, /*irq=*/true, - /*irq_flags=*/flags, /*skip_empty=*/false); + /*irq_flags=*/flags); } void list_lru_unlock_irqrestore(struct list_lru_one *l, unsigned long *flags) @@ -313,8 +325,8 @@ __list_lru_walk_one(struct list_lru *lru, int nid, struct mem_cgroup *memcg, unsigned long isolated = 0; restart: - l = lock_list_lru_of_memcg(lru, nid, memcg, /*irq=*/irq_off, - /*irq_flags=*/NULL, /*skip_empty=*/true); + l = __lock_list_lru_of_memcg(lru, nid, memcg, /*irq=*/irq_off, + /*irq_flags=*/NULL); if (!l) return isolated; list_for_each_safe(item, n, &l->list) { -- 2.53.0