From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-177.mta0.migadu.com (out-177.mta0.migadu.com [91.218.175.177]) (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 7DF7B331221 for ; Wed, 18 Mar 2026 17:57:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.177 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773856625; cv=none; b=boL4MlwbCKG7me/fbMsHh3qT4l1Qf2DgTz5ZEIgiVw9PkZsEpZyyvQAreFYJtcb5gemerXxqxiXayMlXgTyH4cZ5PuxEknAdw0xRnxCIuAkdEKuxV95vLTy5yUuQhyNsVlMoy3mx5UPHD4v9mjPTkY8svt0rbnlgH+CpDgoGfxI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773856625; c=relaxed/simple; bh=vAZ68uMAESRXeWwWt6ZubHianIjbqUuOZmQx/FGvdD4=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=dQ9DHf1YqjsNHGGWow4WalF/YUoWLeQBGF7fj45JanmzOTglCGb52WbqdMLjlpGYwqV3PoqNkU35vwrFO25x61vsR8Uyqb49KJ8f5LDQiBO/3dsZIcLtwBWTLKeU5o0kb5Yj5ikoc/QIrTo7ys1xLht9N7PslmKzea+PniGLGtE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=QJwTNINT; arc=none smtp.client-ip=91.218.175.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="QJwTNINT" Date: Wed, 18 Mar 2026 10:56:55 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1773856620; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=GkJmm1x6RQPn/UFRPa7/2straKzSBCtOE1HckM7TXds=; b=QJwTNINTQL+jMZFdoubsJO40Gl+9oi6Z6gTZUpMTv94GJR4Uyuy1JqE88syGHOSxP4F6oP Bgva392i/tNsGGYmW4zJfhjU5+iarpthTuco3W4RmluY18hUBjZLfXMnd5wsMhfHxn7LmC 4R9WA7WtCQzbh9dI02FZSBI/4Fhx5uo= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Shakeel Butt To: Johannes Weiner 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: <20260312205321.638053-2-hannes@cmpxchg.org> X-Migadu-Flow: FLOW_OUT 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 --- mm/list_lru.c | 53 ++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/mm/list_lru.c b/mm/list_lru.c index 26463ae29c64..062394c598d4 100644 --- a/mm/list_lru.c +++ b/mm/list_lru.c @@ -77,27 +77,30 @@ static inline bool lock_list_lru(struct list_lru_one *l, bool irq) } static inline struct list_lru_one * -lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg, - bool irq, bool skip_empty) +__lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg, + bool irq) { 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)) { - rcu_read_unlock(); + if (likely(l) && !lock_list_lru(l, irq)) + l = NULL; + rcu_read_unlock(); + + return l; +} + +static inline struct list_lru_one * +lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg) +{ + struct list_lru_one *l; +again: + l = __lock_list_lru_of_memcg(lru, nid, memcg, false); + if (likely(l)) return l; - } - /* - * 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; - } - VM_WARN_ON(!css_is_dying(&memcg->css)); + + VM_WARN_ON_ONCE(!css_is_dying(&memcg->css)); memcg = parent_mem_cgroup(memcg); goto again; } @@ -135,8 +138,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, bool skip_empty) +__lock_list_lru_of_memcg(struct list_lru *lru, int nid, struct mem_cgroup *memcg, + bool irq) { struct list_lru_one *l = &lru->node[nid].lru; @@ -148,6 +151,12 @@ 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) +{ + return __lock_list_lru_of_memcg(lru, nid, memcg, false); +} + static inline void unlock_list_lru(struct list_lru_one *l, bool irq_off) { if (irq_off) @@ -164,9 +173,7 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid, struct list_lru_node *nlru = &lru->node[nid]; struct list_lru_one *l; - l = lock_list_lru_of_memcg(lru, nid, memcg, false, false); - if (!l) - return false; + l = lock_list_lru_of_memcg(lru, nid, memcg); if (list_empty(item)) { list_add_tail(item, &l->list); /* Set shrinker bit if the first element was added */ @@ -203,9 +210,7 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid, { struct list_lru_node *nlru = &lru->node[nid]; struct list_lru_one *l; - l = lock_list_lru_of_memcg(lru, nid, memcg, false, false); - if (!l) - return false; + l = lock_list_lru_of_memcg(lru, nid, memcg); if (!list_empty(item)) { list_del_init(item); l->nr_items--; @@ -287,7 +292,7 @@ __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_off, true); + l = __lock_list_lru_of_memcg(lru, nid, memcg, irq_off); if (!l) return isolated; list_for_each_safe(item, n, &l->list) { -- 2.52.0