| From: Nhat Pham <nphamcs@gmail.com> |
| Subject: memcontrol: add a new function to traverse online-only memcg hierarchy |
| Date: Mon, 27 Nov 2023 15:45:56 -0800 |
| |
| The new zswap writeback scheme requires an online-only memcg hierarchy |
| traversal. Add this functionality via the new mem_cgroup_iter_online() |
| function - the old mem_cgroup_iter() is a special case of this new |
| function. |
| |
| Link: https://lkml.kernel.org/r/20231127234600.2971029-3-nphamcs@gmail.com |
| Signed-off-by: Nhat Pham <nphamcs@gmail.com> |
| Suggested-by: Andrew Morton <akpm@linux-foundation.org> |
| Acked-by: Johannes Weiner <hannes@cmpxchg.org> |
| Cc: Chris Li <chrisl@kernel.org> |
| Cc: Dan Streetman <ddstreet@ieee.org> |
| Cc: Domenico Cerasuolo <cerasuolodomenico@gmail.com> |
| Cc: Michal Hocko <mhocko@kernel.org> |
| Cc: Muchun Song <muchun.song@linux.dev> |
| Cc: Roman Gushchin <roman.gushchin@linux.dev> |
| Cc: Seth Jennings <sjenning@redhat.com> |
| Cc: Shakeel Butt <shakeelb@google.com> |
| Cc: Shuah Khan <shuah@kernel.org> |
| Cc: Vitaly Wool <vitaly.wool@konsulko.com> |
| Cc: Yosry Ahmed <yosryahmed@google.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| include/linux/memcontrol.h | 13 +++++++++++++ |
| mm/memcontrol.c | 29 +++++++++++++++++++++++++---- |
| 2 files changed, 38 insertions(+), 4 deletions(-) |
| |
| --- a/include/linux/memcontrol.h~memcontrol-add-a-new-function-to-traverse-online-only-memcg-hierarchy |
| +++ a/include/linux/memcontrol.h |
| @@ -833,6 +833,10 @@ static inline void mem_cgroup_put(struct |
| struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *, |
| struct mem_cgroup *, |
| struct mem_cgroup_reclaim_cookie *); |
| +struct mem_cgroup *mem_cgroup_iter_online(struct mem_cgroup *root, |
| + struct mem_cgroup *prev, |
| + struct mem_cgroup_reclaim_cookie *reclaim, |
| + bool online); |
| void mem_cgroup_iter_break(struct mem_cgroup *, struct mem_cgroup *); |
| void mem_cgroup_scan_tasks(struct mem_cgroup *memcg, |
| int (*)(struct task_struct *, void *), void *arg); |
| @@ -1385,6 +1389,15 @@ mem_cgroup_iter(struct mem_cgroup *root, |
| { |
| return NULL; |
| } |
| + |
| +static inline struct mem_cgroup * |
| +mem_cgroup_iter_online(struct mem_cgroup *root, |
| + struct mem_cgroup *prev, |
| + struct mem_cgroup_reclaim_cookie *reclaim, |
| + bool online) |
| +{ |
| + return NULL; |
| +} |
| |
| static inline void mem_cgroup_iter_break(struct mem_cgroup *root, |
| struct mem_cgroup *prev) |
| --- a/mm/memcontrol.c~memcontrol-add-a-new-function-to-traverse-online-only-memcg-hierarchy |
| +++ a/mm/memcontrol.c |
| @@ -1111,10 +1111,11 @@ again: |
| } |
| |
| /** |
| - * mem_cgroup_iter - iterate over memory cgroup hierarchy |
| + * mem_cgroup_iter_online - iterate over memory cgroup hierarchy |
| * @root: hierarchy root |
| * @prev: previously returned memcg, NULL on first invocation |
| * @reclaim: cookie for shared reclaim walks, NULL for full walks |
| + * @online: whether to skip offline memcgs |
| * |
| * Returns references to children of the hierarchy below @root, or |
| * @root itself, or %NULL after a full round-trip. |
| @@ -1123,13 +1124,16 @@ again: |
| * invocations for reference counting, or use mem_cgroup_iter_break() |
| * to cancel a hierarchy walk before the round-trip is complete. |
| * |
| + * Caller can skip offline memcgs by passing true for @online. |
| + * |
| * Reclaimers can specify a node in @reclaim to divide up the memcgs |
| * in the hierarchy among all concurrent reclaimers operating on the |
| * same node. |
| */ |
| -struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root, |
| +struct mem_cgroup *mem_cgroup_iter_online(struct mem_cgroup *root, |
| struct mem_cgroup *prev, |
| - struct mem_cgroup_reclaim_cookie *reclaim) |
| + struct mem_cgroup_reclaim_cookie *reclaim, |
| + bool online) |
| { |
| struct mem_cgroup_reclaim_iter *iter; |
| struct cgroup_subsys_state *css = NULL; |
| @@ -1199,7 +1203,8 @@ struct mem_cgroup *mem_cgroup_iter(struc |
| * is provided by the caller, so we know it's alive |
| * and kicking, and don't take an extra reference. |
| */ |
| - if (css == &root->css || css_tryget(css)) { |
| + if (css == &root->css || (!online && css_tryget(css)) || |
| + css_tryget_online(css)) { |
| memcg = mem_cgroup_from_css(css); |
| break; |
| } |
| @@ -1229,6 +1234,22 @@ out_unlock: |
| } |
| |
| /** |
| + * mem_cgroup_iter - iterate over memory cgroup hierarchy |
| + * @root: hierarchy root |
| + * @prev: previously returned memcg, NULL on first invocation |
| + * @reclaim: cookie for shared reclaim walks, NULL for full walks |
| + * |
| + * Perform an iteration on the memory cgroup hierarchy without skipping |
| + * offline memcgs. |
| + */ |
| +struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root, |
| + struct mem_cgroup *prev, |
| + struct mem_cgroup_reclaim_cookie *reclaim) |
| +{ |
| + return mem_cgroup_iter_online(root, prev, reclaim, false); |
| +} |
| + |
| +/** |
| * mem_cgroup_iter_break - abort a hierarchy walk prematurely |
| * @root: hierarchy root |
| * @prev: last visited hierarchy member as returned by mem_cgroup_iter() |
| _ |