From patchwork Tue Feb 18 03:14:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JP Kobryn X-Patchwork-Id: 13978853 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id DCBB3C021A9 for ; Tue, 18 Feb 2025 03:15:13 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 39E622800BB; Mon, 17 Feb 2025 22:15:10 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 327632800A4; Mon, 17 Feb 2025 22:15:10 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 17A662800BB; Mon, 17 Feb 2025 22:15:10 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id EA7BA2800A4 for ; Mon, 17 Feb 2025 22:15:09 -0500 (EST) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id A8F6950008 for ; Tue, 18 Feb 2025 03:15:09 +0000 (UTC) X-FDA: 83131599138.05.01A94B4 Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) by imf01.hostedemail.com (Postfix) with ESMTP id CC54A40007 for ; Tue, 18 Feb 2025 03:15:07 +0000 (UTC) Authentication-Results: imf01.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=dxGYpN8B; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf01.hostedemail.com: domain of inwardvessel@gmail.com designates 209.85.216.53 as permitted sender) smtp.mailfrom=inwardvessel@gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1739848507; a=rsa-sha256; cv=none; b=ks85h91fIsLRCwKmcurevpuUFXaZVHfd8luA+Ip1ktkwjNRrpghw5MLJ3Jtz6SChoYtsLr 9RT4P+7pzaRObAISTgWHb56gTB6xh/5S6lZhXXAQP91+KWmVYTu8PIN8sZ7RbGsTSOvxIc 84mmqID66ZZy2MyctiUxZM67OFvOdo8= ARC-Authentication-Results: i=1; imf01.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=dxGYpN8B; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf01.hostedemail.com: domain of inwardvessel@gmail.com designates 209.85.216.53 as permitted sender) smtp.mailfrom=inwardvessel@gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1739848507; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=jAioZutszBaS0Z/YoqfTJqqVrbVraKzr8HB8FcWf8VM=; b=JI9J/AEMNB2WN/uTpmOKlAWYSEcKBkNmjMfZbzI56gFHYZPVqzlyimU+52r8e7Ng+vmpS4 h4wa4f/tdEbSuQv+IpPxF+m/3WJSDuSsNY7aHL/+KYyznv7oeoDxWNTvUYJliZYN2dZZqj Z3j1fzTDQcUyTnEE7mcMwqy2x/WSq5U= Received: by mail-pj1-f53.google.com with SMTP id 98e67ed59e1d1-2fc3fa00323so5464389a91.3 for ; Mon, 17 Feb 2025 19:15:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739848507; x=1740453307; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jAioZutszBaS0Z/YoqfTJqqVrbVraKzr8HB8FcWf8VM=; b=dxGYpN8B+7kvTW151cA7yx7TnAA+Dnc4eRYHwWpmF/DZXtJqiP+yHdJ097/fM6IDBy yBNNZhRG/aB4cc5vWII77Kjb1eMLA3rWXP3GlWW0Uv+QYihxpzj2N4jyQlwecdnnrFbE f9ThoJ0Bk5I2wHjPgVdrgUbYxFOZUNn7E7ssr2fbndTrSC1xj1uRLPsvzdbE/46UgS+J SHVqFCO7SpNP+15ghs2OIpwrog05WvijCUOkyN7fUuWjHLtpsJBMS7KCpHE9IUhIxfhW n75XV4uVvQEQmSw+ZR1O9ig/kj/74kDL5ftAt1yStUsrOQXnFiID7CAMjORX356QzKSf hv4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739848507; x=1740453307; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jAioZutszBaS0Z/YoqfTJqqVrbVraKzr8HB8FcWf8VM=; b=Uq6mj3Dfmuw1wPRkw7UnJt5kPFNzVK1m2mUDfU8Qnphwf3b9c6ADzuKP23DrYSSzNV yNXz9Y8ZWx5SVT/s3MpjOTGe+8LjtoXSHDJs7v/oId3QyLHXzrnccCq0K55HEsXqec70 MOsA1xA1Ohg8wan7AZ924f3oMRSZVzndoCUhINVefDsjuLt6foHhiAdUqKUrdupa44sy iJjwdJfr3Yuchc8k8OotqEraTY1cA8bPOkBiSCVEJcJnLWzRJNANTZKEsO0pswhqzi+D mS0hFBWXBuw2mWpXXCGGQNS/qXoA0QO/IaHPlD7QxpvbkgWDw5caWGY7+ilT8bgjYFZ0 BvRw== X-Gm-Message-State: AOJu0YxMCU3eBskjYe/kKe4ZM2peg6VfkH/pu8jfrL9pg2xNsMbuj2Zi mvYzGvQ/zcCNgbgXid62tviPGHpaQZgFBgS0oZ3JA81U5XuI0jgK X-Gm-Gg: ASbGnctjvbYyNvw3/YwN9jcDlHwO5kZ2YGB7wByemIUYqEP5hXO9smV1DJ9NsFsBRHh +q8EjyzWA2H0lh4Za06sphnVg3syHNpb78hN3KL9WC3Qy7C1+BMo1b6SOb0lKQfEByyWwuEKN6E HhQwSnqNXgIaXJpynOk11Z6vcBpMx0S1HbxeB2J8WA9FpufrTDxusm8ksTgzLui87HiKDLI6YTM DrlkIA+g0rsRc0AY5H0ekqgToxg4Kn1/JzA2AgxuLObuFIER0mykahg+bUdTq67ZRiDPB2awBXN qO7z1ODnPlSTAUHkwuFXe53XzLjn+tZGt7WuXRK8fvBCLSuG8pcO X-Google-Smtp-Source: AGHT+IHo+onZRqN7Qw0BKGqYOQIOyp+AShjQ0rjEZCDEjA45rubie5vL5mfqBgXSfDiXivgdQ4eXKg== X-Received: by 2002:aa7:8893:0:b0:730:a40f:e6dc with SMTP id d2e1a72fcca58-732618f3469mr19540551b3a.23.1739848506699; Mon, 17 Feb 2025 19:15:06 -0800 (PST) Received: from saturn.. (c-67-188-127-15.hsd1.ca.comcast.net. [67.188.127.15]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-732425466besm8763451b3a.9.2025.02.17.19.15.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2025 19:15:06 -0800 (PST) From: JP Kobryn To: shakeel.butt@linux.dev, tj@kernel.org, mhocko@kernel.org, hannes@cmpxchg.org, yosryahmed@google.com, akpm@linux-foundation.org Cc: linux-mm@kvack.org, cgroups@vger.kernel.org, kernel-team@meta.com Subject: [PATCH 04/11] cgroup: introduce cgroup_rstat_ops Date: Mon, 17 Feb 2025 19:14:41 -0800 Message-ID: <20250218031448.46951-5-inwardvessel@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250218031448.46951-1-inwardvessel@gmail.com> References: <20250218031448.46951-1-inwardvessel@gmail.com> MIME-Version: 1.0 X-Rspamd-Server: rspam02 X-Rspamd-Queue-Id: CC54A40007 X-Stat-Signature: wbk6g191i5suabwctduiisi1q789rmjy X-Rspam-User: X-HE-Tag: 1739848507-649722 X-HE-Meta: U2FsdGVkX1+1rTIykh4fdIyYc2/5c9WrH/xOCQ8RQA9iumNjmrBsCuVhwyaWDSlrjoKfMQOied6xpui0nTuOz0rooBpZX4MngTWO0eRcxDQuEBKM1FtZIXVMBP8x/VuhTDnSU8m07LcZ9yaGTmeaLnhlx1vrZqrlvsDwz7ZViSMaRokYS3Nv3V06TgNtArW+K64mFh1tQQuJ5Pcu33RydQf7pNXPZNQh0Oy+MnU4pF1+qTv36+3zFldGuRJhysRyyF/IeDz/ewBx6meQE9fY7iKiXEwCW3eZ1ZnsbTZaREoZwnS3e4wUhinqvL55oRMBiU8Oc14p/BZFPiTWeQGrCm5wDrQyrwW5tvC95tRzS+Ec8GwKxKfz72JO0UaWeXGLmHvImCUtCiOk4tgkq7A2i5thcXJ94iGw0JxyyUBkv0fZFd/Is1c26A1OIsQZHn7AzbLpjMxGL+aejrdTOkU4Ka+0c9scL4QQvoE6alABKtSIiQjpRIZXLbRBHIgJuEPxHCXYpvgZZrHNbjOR5xljVxPfcGFdLpCFz9Wikoz//Yt/lJx1UzkljFj/dxencpQTdfCJ1p1IaP/j88CbVrzHQHW6gTAdqJzq6cNCUk7nyXdLohweVcPdVJlHHqn5smQoZGfCQOUaQn6gx5L0rdTpNAPrCfSgVyhIdgf27Ih7fKApcq8A55l4XTIDyKA/dXL+D0nUppvJW9bM7ji9q4YkcjHI3EwVVaBvAn70sB2YU/nLZEY3xoaiXeiDzH3gO+j48yfqZFaEHrdeFMiCWv/0tcPQRtDe1vbS41nMT7x+Aj1rMYyA4/HzH6+YVO4NxZUFwJ9++KYi7sQcH4ztLAZyk1O58UUfd/b8eTjg2AycAACkGqetpmF58aatHcq0FRJPiN1sRL3zci6XRJuiEZHCqu2x5C+zIfmgJZpMGmRQxyBul8yZEqSDNQ8TR6NZAIxYCyJCCV7H3POmZ+8m1Ao hnrDWy5H zkKHP9kmUppXyuGd/o+vBv3tEmY2qHz0MfABM620hR1Wdt/s3YQ6ZAZAUDqKI2KU8OcBbIpKKeU0/xlYvfubl6lS0I6f1Z9/V/HAqP/aSulBTM0Fqy/g4fiTsTWy3J2AFcsIEurnWuzrEFqtMP+B1WgzgprsoCp359RLyQmchMSqqVnkZT7ddOF9YAK3tKLaQe1RpJ9HZnnlN1pN8LBtUTNQPh+dFR3KwW7TwCarj9dxpQUp73ddLjAsdxGOlOnC9KCW9NqyI+pQuyoNfiFFMMEKv8+hWXZhYANC2ndUGhuBUADx0Sh98G/ldFmhVTfv1BekPe8JnlinPGkjUvxudHjdHJCCkLnHfHHECPZFVbeOo9rSC+oS35PtLxTgQpodz48oZfDKw8Xize6ASeduTkVMNbbpfz6iCdenhJ2B3uZ1zRk8= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: The cgroup_rstat_ops interface provides a way for type-specific operations to be hidden from the common rstat operations. Use it to decouple the cgroup_subsys_type from within the internal rstat updated/flush routines. The new ops interface allows for greater extensibility in terms of future changes. i.e. public updated/flush api's can be created that accept a arbitrary types, as long as that type has an associated ops interface. Signed-off-by: JP Kobryn --- kernel/cgroup/rstat.c | 131 +++++++++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 46 deletions(-) diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c index a32bcd7942a5..a8bb304e49c4 100644 --- a/kernel/cgroup/rstat.c +++ b/kernel/cgroup/rstat.c @@ -9,6 +9,12 @@ #include +struct cgroup_rstat_ops { + struct cgroup_rstat *(*parent_fn)(struct cgroup_rstat *); + struct cgroup *(*cgroup_fn)(struct cgroup_rstat *); + void (*flush_fn)(struct cgroup_rstat *, int); +}; + static DEFINE_SPINLOCK(cgroup_rstat_lock); static DEFINE_PER_CPU(raw_spinlock_t, cgroup_rstat_cpu_lock); @@ -19,7 +25,17 @@ static struct cgroup_rstat_cpu *rstat_cpu(struct cgroup_rstat *rstat, int cpu) return per_cpu_ptr(rstat->rstat_cpu, cpu); } -static struct cgroup_rstat *rstat_parent(struct cgroup_rstat *rstat) +static inline bool is_base_css(struct cgroup_subsys_state *css) +{ + /* css for base stats has no subsystem */ + if (!css->ss) + return true; + + return false; +} + +static struct cgroup_rstat *rstat_parent_via_css( + struct cgroup_rstat *rstat) { struct cgroup_subsys_state *css = container_of( rstat, typeof(*css), rstat); @@ -30,6 +46,33 @@ static struct cgroup_rstat *rstat_parent(struct cgroup_rstat *rstat) return &(css->parent->rstat); } +static struct cgroup *rstat_cgroup_via_css(struct cgroup_rstat *rstat) +{ + struct cgroup_subsys_state *css = + container_of(rstat, struct cgroup_subsys_state, rstat); + + return css->cgroup; +} + +static void rstat_flush_via_css(struct cgroup_rstat *rstat, int cpu) +{ + struct cgroup_subsys_state *css = container_of( + rstat, typeof(*css), rstat); + + if (is_base_css(css)) { + cgroup_base_stat_flush(css->cgroup, cpu); + return; + } + + css->ss->css_rstat_flush(css, cpu); +} + +static struct cgroup_rstat_ops rstat_css_ops = { + .parent_fn = rstat_parent_via_css, + .cgroup_fn = rstat_cgroup_via_css, + .flush_fn = rstat_flush_via_css, +}; + /* * Helper functions for rstat per CPU lock (cgroup_rstat_cpu_lock). * @@ -84,11 +127,11 @@ void _cgroup_rstat_cpu_unlock(raw_spinlock_t *cpu_lock, int cpu, raw_spin_unlock_irqrestore(cpu_lock, flags); } -static void __cgroup_rstat_updated(struct cgroup_rstat *rstat, int cpu) +static void __cgroup_rstat_updated(struct cgroup_rstat *rstat, int cpu, + struct cgroup_rstat_ops *ops) { - struct cgroup_subsys_state *css = container_of( - rstat, typeof(*css), rstat); - struct cgroup *cgrp = css->cgroup; + struct cgroup *cgrp; + raw_spinlock_t *cpu_lock = per_cpu_ptr(&cgroup_rstat_cpu_lock, cpu); unsigned long flags; @@ -103,12 +146,13 @@ static void __cgroup_rstat_updated(struct cgroup_rstat *rstat, int cpu) if (data_race(rstat_cpu(rstat, cpu)->updated_next)) return; + cgrp = ops->cgroup_fn(rstat); flags = _cgroup_rstat_cpu_lock(cpu_lock, cpu, cgrp, true); /* put @rstat and all ancestors on the corresponding updated lists */ while (true) { struct cgroup_rstat_cpu *rstatc = rstat_cpu(rstat, cpu); - struct cgroup_rstat *parent = rstat_parent(rstat); + struct cgroup_rstat *parent = ops->parent_fn(rstat); struct cgroup_rstat_cpu *prstatc; /* @@ -145,7 +189,7 @@ static void __cgroup_rstat_updated(struct cgroup_rstat *rstat, int cpu) */ __bpf_kfunc void cgroup_rstat_updated(struct cgroup_subsys_state *css, int cpu) { - __cgroup_rstat_updated(&css->rstat, cpu); + __cgroup_rstat_updated(&css->rstat, cpu, &rstat_css_ops); } /** @@ -161,7 +205,8 @@ __bpf_kfunc void cgroup_rstat_updated(struct cgroup_subsys_state *css, int cpu) * cgroups into a stack. The root is pushed by the caller. */ static struct cgroup_rstat *cgroup_rstat_push_children( - struct cgroup_rstat *head, struct cgroup_rstat *child, int cpu) + struct cgroup_rstat *head, struct cgroup_rstat *child, int cpu, + struct cgroup_rstat_ops *ops) { struct cgroup_rstat *chead = child; /* Head of child cgroup level */ struct cgroup_rstat *ghead = NULL; /* Head of grandchild cgroup level */ @@ -174,7 +219,7 @@ static struct cgroup_rstat *cgroup_rstat_push_children( while (chead) { child = chead; chead = child->rstat_flush_next; - parent = rstat_parent(child); + parent = ops->parent_fn(child); /* updated_next is parent cgroup terminated */ while (child != parent) { @@ -220,16 +265,15 @@ static struct cgroup_rstat *cgroup_rstat_push_children( * here is the cgroup root whose updated_next can be self terminated. */ static struct cgroup_rstat *cgroup_rstat_updated_list( - struct cgroup_rstat *root, int cpu) + struct cgroup_rstat *root, int cpu, struct cgroup_rstat_ops *ops) { - struct cgroup_subsys_state *css = container_of( - root, typeof(*css), rstat); - struct cgroup *cgrp = css->cgroup; raw_spinlock_t *cpu_lock = per_cpu_ptr(&cgroup_rstat_cpu_lock, cpu); struct cgroup_rstat_cpu *rstatc = rstat_cpu(root, cpu); struct cgroup_rstat *head = NULL, *parent, *child; + struct cgroup *cgrp; unsigned long flags; + cgrp = ops->cgroup_fn(root); flags = _cgroup_rstat_cpu_lock(cpu_lock, cpu, cgrp, false); /* Return NULL if this subtree is not on-list */ @@ -240,7 +284,7 @@ static struct cgroup_rstat *cgroup_rstat_updated_list( * Unlink @root from its parent. As the updated_children list is * singly linked, we have to walk it to find the removal point. */ - parent = rstat_parent(root); + parent = ops->parent_fn(root); if (parent) { struct cgroup_rstat_cpu *prstatc; struct cgroup_rstat **nextp; @@ -265,7 +309,7 @@ static struct cgroup_rstat *cgroup_rstat_updated_list( child = rstatc->updated_children; rstatc->updated_children = root; if (child != root) - head = cgroup_rstat_push_children(head, child, cpu); + head = cgroup_rstat_push_children(head, child, cpu, ops); unlock_ret: _cgroup_rstat_cpu_unlock(cpu_lock, cpu, cgrp, flags, false); return head; @@ -323,34 +367,30 @@ static inline void __cgroup_rstat_unlock(struct cgroup *cgrp, int cpu_in_loop) } /* see cgroup_rstat_flush() */ -static void cgroup_rstat_flush_locked(struct cgroup_rstat *rstat) +static void cgroup_rstat_flush_locked(struct cgroup_rstat *rstat, + struct cgroup_rstat_ops *ops) __releases(&cgroup_rstat_lock) __acquires(&cgroup_rstat_lock) { - struct cgroup_subsys_state *css = container_of( - rstat, typeof(*css), rstat); - struct cgroup *cgrp = css->cgroup; int cpu; lockdep_assert_held(&cgroup_rstat_lock); for_each_possible_cpu(cpu) { - struct cgroup_rstat *pos = cgroup_rstat_updated_list(rstat, cpu); + struct cgroup_rstat *pos = cgroup_rstat_updated_list( + rstat, cpu, ops); for (; pos; pos = pos->rstat_flush_next) { - struct cgroup_subsys_state *pos_css = container_of( - pos, typeof(*pos_css), rstat); - struct cgroup *pos_cgroup = pos_css->cgroup; - - if (!pos_css->ss) - cgroup_base_stat_flush(pos_cgroup, cpu); - else - pos_css->ss->css_rstat_flush(pos_css, cpu); + struct cgroup *pos_cgroup = ops->cgroup_fn(pos); + ops->flush_fn(pos, cpu); bpf_rstat_flush(pos_cgroup, cgroup_parent(pos_cgroup), cpu); } /* play nice and yield if necessary */ if (need_resched() || spin_needbreak(&cgroup_rstat_lock)) { + struct cgroup *cgrp; + + cgrp = ops->cgroup_fn(rstat); __cgroup_rstat_unlock(cgrp, cpu); if (!cond_resched()) cpu_relax(); @@ -359,16 +399,15 @@ static void cgroup_rstat_flush_locked(struct cgroup_rstat *rstat) } } -static void __cgroup_rstat_flush(struct cgroup_rstat *rstat) +static void __cgroup_rstat_flush(struct cgroup_rstat *rstat, + struct cgroup_rstat_ops *ops) { - struct cgroup_subsys_state *css = container_of( - rstat, typeof(*css), rstat); - struct cgroup *cgrp = css->cgroup; + struct cgroup *cgrp; might_sleep(); - + cgrp = ops->cgroup_fn(rstat); __cgroup_rstat_lock(cgrp, -1); - cgroup_rstat_flush_locked(rstat); + cgroup_rstat_flush_locked(rstat, ops); __cgroup_rstat_unlock(cgrp, -1); } @@ -387,19 +426,19 @@ static void __cgroup_rstat_flush(struct cgroup_rstat *rstat) */ __bpf_kfunc void cgroup_rstat_flush(struct cgroup_subsys_state *css) { - __cgroup_rstat_flush(&css->rstat); + __cgroup_rstat_flush(&css->rstat, &rstat_css_ops); } -static void __cgroup_rstat_flush_hold(struct cgroup_rstat *rstat) +static void __cgroup_rstat_flush_hold(struct cgroup_rstat *rstat, + struct cgroup_rstat_ops *ops) __acquires(&cgroup_rstat_lock) { - struct cgroup_subsys_state *css = container_of( - rstat, typeof(*css), rstat); - struct cgroup *cgrp = css->cgroup; + struct cgroup *cgrp; might_sleep(); + cgrp = ops->cgroup_fn(rstat); __cgroup_rstat_lock(cgrp, -1); - cgroup_rstat_flush_locked(rstat); + cgroup_rstat_flush_locked(rstat, ops); } /** @@ -413,20 +452,20 @@ static void __cgroup_rstat_flush_hold(struct cgroup_rstat *rstat) */ void cgroup_rstat_flush_hold(struct cgroup_subsys_state *css) { - __cgroup_rstat_flush_hold(&css->rstat); + __cgroup_rstat_flush_hold(&css->rstat, &rstat_css_ops); } /** * cgroup_rstat_flush_release - release cgroup_rstat_flush_hold() * @rstat: rstat node used to find associated cgroup used by tracepoint */ -static void __cgroup_rstat_flush_release(struct cgroup_rstat *rstat) +static void __cgroup_rstat_flush_release(struct cgroup_rstat *rstat, + struct cgroup_rstat_ops *ops) __releases(&cgroup_rstat_lock) { - struct cgroup_subsys_state *css = container_of( - rstat, typeof(*css), rstat); - struct cgroup *cgrp = css->cgroup; + struct cgroup *cgrp; + cgrp = ops->cgroup_fn(rstat); __cgroup_rstat_unlock(cgrp, -1); } @@ -436,7 +475,7 @@ static void __cgroup_rstat_flush_release(struct cgroup_rstat *rstat) */ void cgroup_rstat_flush_release(struct cgroup_subsys_state *css) { - __cgroup_rstat_flush_release(&css->rstat); + __cgroup_rstat_flush_release(&css->rstat, &rstat_css_ops); } static void __cgroup_rstat_init(struct cgroup_rstat *rstat)