On Tue, May 21, 2024 at 10:43:16AM +0800, Oliver Sang wrote: > hi, Shakeel, > [...] > > we reported regression on a 2-node Skylake server. so I found a 1-node Skylake > desktop (we don't have 1 node server) to check. > Please try the following patch on both single node and dual node machines: >From 00a84b489b9e18abd1b8ec575ea31afacaf0734b Mon Sep 17 00:00:00 2001 From: Shakeel Butt <shakeel.butt@xxxxxxxxx> Date: Tue, 21 May 2024 20:27:11 -0700 Subject: [PATCH] memcg: rearrage fields of mem_cgroup_per_node At the moment the fields of mem_cgroup_per_node which get read on the performance critical path share the cacheline with the fields which might get updated. This cause contention of that cacheline for concurrent readers. Let's move all the read only pointers at the start of the struct, followed by memcg-v1 only fields and at the end fields which get updated often. Signed-off-by: Shakeel Butt <shakeel.butt@xxxxxxxxx> --- include/linux/memcontrol.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 030d34e9d117..16efd9737be9 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -96,23 +96,25 @@ struct mem_cgroup_reclaim_iter { * per-node information in memory controller. */ struct mem_cgroup_per_node { - struct lruvec lruvec; + /* Keep the read-only fields at the start */ + struct mem_cgroup *memcg; /* Back pointer, we cannot */ + /* use container_of */ struct lruvec_stats_percpu __percpu *lruvec_stats_percpu; struct lruvec_stats *lruvec_stats; - - unsigned long lru_zone_size[MAX_NR_ZONES][NR_LRU_LISTS]; - - struct mem_cgroup_reclaim_iter iter; - struct shrinker_info __rcu *shrinker_info; + /* memcg-v1 only stuff in middle */ + struct rb_node tree_node; /* RB tree node */ unsigned long usage_in_excess;/* Set to the value by which */ /* the soft limit is exceeded*/ bool on_tree; - struct mem_cgroup *memcg; /* Back pointer, we cannot */ - /* use container_of */ + + /* Fields which get updated often at the end. */ + struct lruvec lruvec; + unsigned long lru_zone_size[MAX_NR_ZONES][NR_LRU_LISTS]; + struct mem_cgroup_reclaim_iter iter; }; struct mem_cgroup_threshold { -- 2.43.0