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 A227C371860 for ; Sun, 12 Jul 2026 08:43: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=1783845813; cv=none; b=rJncLNkvQ2LKoPYl7TGRq+wUaskKwaoT/jK4u4P19kH8I/u0W8yWsvMMZXwRQ5nH1fcgqC6r8hTA7DD0n3S3ywinjoGEqLS3JqXR30P79/Wlxg8vJq9+EcF7aBnzJHH6+PpBY2TcPmZU+lcKQI/qsvdjHEAkro+yAf5nD7RukDE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783845813; c=relaxed/simple; bh=sFfekQ29iKCWrtRToeGJG9nqLikOPr8mQSz5Hsb33LM=; h=From:To:Cc:Subject:In-Reply-To:References:Date:Message-ID: MIME-Version:Content-Type; b=LeTouQ8YiBPROkwLsnlRQ1uwD3TrtkpboyAJ1UmfJ4Q86XqYSxaRPZWugdQ9m3/hYqnQ03l1iypnalT5AedJP0XxS8BpD7pKzyLnDcVk17NEsKL2JDxpLxWlc8lZ80P+L/2TPlevwJatv3E29/KmQL1++vVyCbrKO7QOc2QnUcc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kY6U/KCA; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kY6U/KCA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A3FD1F000E9; Sun, 12 Jul 2026 08:43:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1783845812; bh=oip8/L74rePX2kCOX9iUEXROqX3ZFpWrMwHT4YHp2mI=; h=From:To:Cc:Subject:In-Reply-To:References:Date; b=kY6U/KCAOMBDsMm89Apzuf6levNSIlhw3O32oTCKrYEr63zQ52LCoaTop2h+6CKKc 4SjauLHkova8qYu85Ru55QA6IpQbZ8ripGCMcmbtfG4KlPDm1k2hERb+LZ2Se2mXwf woLVRZm6b4iY3XkOZBcyt34vZRcZmI7aPCSwGfsjFK3OT6eO6UME/+zxfDU34YP+kz DQlXlK4KLmzTL8MwbOPhyuzEb9vNrspf3o31zlCmf/YTa4ENgO2DzQlhYxQK++/Mr2 mZGe9VR+gH6IfRKXUddKno3nnnSMgKy9B391cyyNaKK9J30NqFFpheyK2f3QQTvd/f OwII0S5DYsM1A== X-Mailer: emacs 30.2 (via feedmail 11-beta-1 I) From: Aneesh Kumar K.V To: Joshua Hahn , linux-mm@kvack.org Cc: Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , linux-kernel@vger.kernel.org, kernel-team@meta.com Subject: Re: [PATCH] mm/memory-tiers: cache top tier nodes In-Reply-To: <20260706204507.98522-1-joshua.hahnjy@gmail.com> References: <20260706204507.98522-1-joshua.hahnjy@gmail.com> Date: Sun, 12 Jul 2026 14:13:24 +0530 Message-ID: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain Joshua Hahn writes: > node_is_toptier() is called in a few hot paths: task_numa_fault(), > should_numa_migrate_memory(), folio_migrate_flags(), etc. Each call > takes an RCU read section and performs the tier distance check again. > > Tieredness for all nodes only changes on memory node hotplugs. Instead > of recomputing toptier nodes inside each of the hot paths above, compute > it only on memory node hotplug events and cache the results. > > Signed-off-by: Joshua Hahn > --- > mm/memory-tiers.c | 36 ++++++++++-------------------------- > 1 file changed, 10 insertions(+), 26 deletions(-) > > diff --git a/mm/memory-tiers.c b/mm/memory-tiers.c > index 54851d8a195b0..2e6e02ec1fce4 100644 > --- a/mm/memory-tiers.c > +++ b/mm/memory-tiers.c > @@ -71,6 +71,7 @@ bool folio_use_access_time(struct folio *folio) > > #ifdef CONFIG_NUMA_MIGRATION > static int top_tier_adistance; > +static nodemask_t toptier_nodes __read_mostly = NODE_MASK_ALL; > /* > * node_demotion[] examples: > * > @@ -276,27 +277,7 @@ static struct memory_tier *__node_get_memory_tier(int node) > #ifdef CONFIG_NUMA_MIGRATION > bool node_is_toptier(int node) > { > - bool toptier; > - pg_data_t *pgdat; > - struct memory_tier *memtier; > - > - pgdat = NODE_DATA(node); > - if (!pgdat) > - return false; > - > - rcu_read_lock(); > - memtier = rcu_dereference(pgdat->memtier); > - if (!memtier) { > - toptier = true; > - goto out; > - } > - if (memtier->adistance_start <= top_tier_adistance) > - toptier = true; > - else > - toptier = false; > -out: > - rcu_read_unlock(); > - return toptier; > + return node_isset(node, toptier_nodes); > } > > void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets) > @@ -497,19 +478,22 @@ static void establish_demotion_targets(void) > } > } > /* > - * Now build the lower_tier mask for each node collecting node mask from > - * all memory tier below it. This allows us to fallback demotion page > - * allocation to a set of nodes that is closer the above selected > - * preferred node. > + * A node stays toptier unless it belongs to a tier below > + * top_tier_adistance, while each tier's lower_tier_mask collects the > + * nodes of every tier below it so demotion page allocation can fall > + * back to nodes closer to the selected preferred node. > */ > + toptier_nodes = node_states[N_MEMORY]; > Won't this result in a larger window where every node_is_toptier() call can return an incorrect result? This change would make every memory node a top-tier node until the loop below clears them from the toptier_nodes nodemask. I assume an incorrect result from node_is_toptier() is not too bad, but is the performance impact large enough to make this change? > lower_tier = node_states[N_MEMORY]; > list_for_each_entry(memtier, &memory_tiers, list) { > + tier_nodes = get_memtier_nodemask(memtier); > + if (memtier->adistance_start > top_tier_adistance) > + nodes_andnot(toptier_nodes, toptier_nodes, tier_nodes); > /* > * Keep removing current tier from lower_tier nodes, > * This will remove all nodes in current and above > * memory tier from the lower_tier mask. > */ > - tier_nodes = get_memtier_nodemask(memtier); > nodes_andnot(lower_tier, lower_tier, tier_nodes); > memtier->lower_tier_mask = lower_tier; > } > -- > 2.53.0-Meta -aneesh