From patchwork Wed Aug 1 15:19:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Weiner X-Patchwork-Id: 10552473 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2679915E9 for ; Wed, 1 Aug 2018 15:17:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 16C1A2ACA2 for ; Wed, 1 Aug 2018 15:17:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 094D02ACBC; Wed, 1 Aug 2018 15:17:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3E9C2ACA2 for ; Wed, 1 Aug 2018 15:17:47 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 2086F6B0286; Wed, 1 Aug 2018 11:17:46 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 1B8E26B0287; Wed, 1 Aug 2018 11:17:46 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 05C4D6B0289; Wed, 1 Aug 2018 11:17:45 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-qk0-f199.google.com (mail-qk0-f199.google.com [209.85.220.199]) by kanga.kvack.org (Postfix) with ESMTP id C4AB96B0287 for ; Wed, 1 Aug 2018 11:17:45 -0400 (EDT) Received: by mail-qk0-f199.google.com with SMTP id y130-v6so17255743qka.1 for ; Wed, 01 Aug 2018 08:17:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:dkim-signature:from:to:cc:subject:date :message-id:in-reply-to:references; bh=td8sVEq7B3zRpddgZoElV+O4+/3RnsPaR9Zy76qVrWc=; b=NY4hIoIUKG8+da9MVvxjE19YfyPLeaVy5wqZ+nFfQq8hXv3LCg4M6LVy0gRpy27RJu E68ClCFeB4ghMcAKxzcdArgHM/eONc5puzc0jFKP82K2B7Id1fkCwhuWojgdL/UhrP1t e2E+kVzs+AICa+p2lO87aH4vc0dwMgVnF8YfZ3iE0gTiNHAETbcc2K7xr1v/x0ld50X4 ImaFZ+rlXYUC+m4Bu8mA9gHk4SMebA6cWHmwaMdqhtPf1GxSgC40pTcUgdqTiFw1BLHj qFXu5iC60zMOg1Xj1TIqod13jr4xToEPuZCjgY0IU9TpoEf1B47398q3c/3C0S2BEp43 CcFQ== X-Gm-Message-State: AOUpUlGP+omQTZYT7Gn4k3c7VIUIhFXJJBXka8Ny7QKQ6BobAD6ZU9s6 e1kyCGJzC+pGVoaOeWsIvGrBcMvCXdbTJJt8Zom/rTKcYA10CPsm3dwyJGA1VSwPm438yj7cTYj mf6+2/dwSHHI/OLSxGebWeD8diiNr45Jfy5qRkj5qd1Yc6yGbyIptE+4840o41bjctI/j902FKv OxVITS4zR754TuxAbe0g8QasPKWWGpPrXvNNURLIFtU2D5mbGnEZ8EF1cFfARDmBYGa6IQcxT6N 1+jfN1woPZvY1QRjSf6uDGSXcSqMjz69PpFLGuSjBr/ry/kY4Ahs2HRc1q2D/XyglHLjzkXNRR3 QLcxMARSkEEwhKX9RDAmq0G75RRRtAxYutTY6JybXeqS/iVb8kwWi9JxMfjFww2w3ihiHK4nBTR U X-Received: by 2002:a37:2711:: with SMTP id n17-v6mr23623189qkn.109.1533136665481; Wed, 01 Aug 2018 08:17:45 -0700 (PDT) X-Received: by 2002:a37:2711:: with SMTP id n17-v6mr23623119qkn.109.1533136664458; Wed, 01 Aug 2018 08:17:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533136664; cv=none; d=google.com; s=arc-20160816; b=DJia2LiSLHBJtHiF4V244MZEV9uEeqcEWiANgMXdcGCcCBv33QKKgq38+8lMnglQnC ynlN0gbvLPVrxjy6mL61ziNJVIkml4z0ccz5mKdUj53g/R9iiJf/sku5gQ9gvQSkJIh3 0cWgjVb9EU+1GJAunHBjGriBE+jJZLz3madQCx4MNy+MTRy0jZHlL8AnD1J5jom0TPef BVCf84wo9nIqTkckMwyUNGcvKJvUeiTIK/v2CdXRkUjP9jpZzFPRmY/kTo+wqqtxMh2k N8tBCv1J16Cp4mFtVRax4mdtrMNbJcyksB00vrQGlLC/npQaohEYmy/y3NKbDFJjOZ2U VBwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=td8sVEq7B3zRpddgZoElV+O4+/3RnsPaR9Zy76qVrWc=; b=VFu42kqqPb0dDYSGibWRRkyz8pKGe+pDSr/BZN5A3NphOOtwgVQzOHTGA1eaV8m9oX JGtVL7mTNpfJXgH0M4Bd26Kr/4iH/SEuPGlUfYuOM6LxcuFh3UrLM3SgkUZ+41V+lRZ3 3/iVoN/iQPsei61NavH7uwSO7LBzhgAVx6dRYZDwVfphyFg+mGw00KBUmU1SV1luHHie swYCbK+xkLrecPhmb3SwjI0KCJAkQVO+igowLrdMtSTZcTgmF/atAlv9bUeTegA/a2vK qNLec94i+GlUvVaTvXAfbgTFO9On5j6r1dXd1h/YMcq9PfeTK2t64scD6MfbwxObNOE9 1BQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cmpxchg-org.20150623.gappssmtp.com header.s=20150623 header.b=KL9Kw381; spf=pass (google.com: domain of hannes@cmpxchg.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=hannes@cmpxchg.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cmpxchg.org Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id z11-v6sor9254252qti.109.2018.08.01.08.17.44 for (Google Transport Security); Wed, 01 Aug 2018 08:17:44 -0700 (PDT) Received-SPF: pass (google.com: domain of hannes@cmpxchg.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@cmpxchg-org.20150623.gappssmtp.com header.s=20150623 header.b=KL9Kw381; spf=pass (google.com: domain of hannes@cmpxchg.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=hannes@cmpxchg.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cmpxchg.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cmpxchg-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=td8sVEq7B3zRpddgZoElV+O4+/3RnsPaR9Zy76qVrWc=; b=KL9Kw381RFpnCLgDoWqIx1BR1NJDAptWxyqx03S6uawYslq4CKGBtWzF0Ih4PK519W msUTCi4DSh35e+wZGcM/GIu0haSYPvTc9ZmFjklrpaTBXShCHT/oqaA3UI57uigLOLrY RwgrZ5WlvxWUcp4bfk2R/pOtj8ScNj9XqOi0vjAccEUSe/f7bkceysqpIgkOdogH3Tgg ZbNfGItmz8Wy/FS0WTRjhh8mxr0jqiu5Bn4tzFzqncBdPhIXFUFhEPMG7CpBwMLLhI8V Ph0pitoppIirCVzVOwNTzB9R8MGHTDqkDMzp5Owm+58ggB0PkeAy1IsHMneC1FpIQN5+ /qrA== X-Google-Smtp-Source: AAOMgpfyin81rAClyoUowtUsN3pTO+9hDyRNQFZ89szGm2n+DcXpuwg6L0RkPia6xfvysbyo2Fj0Xg== X-Received: by 2002:ac8:489:: with SMTP id s9-v6mr25479578qtg.173.1533136663941; Wed, 01 Aug 2018 08:17:43 -0700 (PDT) Received: from localhost (216.49.36.201.res-cmts.bus.ptd.net. [216.49.36.201]) by smtp.gmail.com with ESMTPSA id 49-v6sm12027407qtz.43.2018.08.01.08.17.42 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 01 Aug 2018 08:17:42 -0700 (PDT) From: Johannes Weiner To: Ingo Molnar , Peter Zijlstra , Andrew Morton , Linus Torvalds Cc: Tejun Heo , Suren Baghdasaryan , Daniel Drake , Vinayak Menon , Christopher Lameter , Mike Galbraith , Shakeel Butt , Peter Enderborg , linux-mm@kvack.org, cgroups@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@fb.com Subject: [PATCH 9/9] psi: cgroup support Date: Wed, 1 Aug 2018 11:19:58 -0400 Message-Id: <20180801151958.32590-10-hannes@cmpxchg.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180801151958.32590-1-hannes@cmpxchg.org> References: <20180801151958.32590-1-hannes@cmpxchg.org> 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: X-Virus-Scanned: ClamAV using ClamSMTP On a system that executes multiple cgrouped jobs and independent workloads, we don't just care about the health of the overall system, but also that of individual jobs, so that we can ensure individual job health, fairness between jobs, or prioritize some jobs over others. This patch implements pressure stall tracking for cgroups. In kernels with CONFIG_PSI=y, cgroup2 groups will have cpu.pressure, memory.pressure, and io.pressure files that track aggregate pressure stall times for only the tasks inside the cgroup. v3: - fix copy-paste indentation screwups Acked-by: Tejun Heo Signed-off-by: Johannes Weiner --- Documentation/accounting/psi.txt | 9 ++++ Documentation/cgroup-v2.txt | 18 +++++++ include/linux/cgroup-defs.h | 4 ++ include/linux/cgroup.h | 15 ++++++ include/linux/psi.h | 25 ++++++++++ init/Kconfig | 4 ++ kernel/cgroup/cgroup.c | 45 +++++++++++++++++- kernel/sched/psi.c | 81 +++++++++++++++++++++++++++++++- 8 files changed, 197 insertions(+), 4 deletions(-) diff --git a/Documentation/accounting/psi.txt b/Documentation/accounting/psi.txt index 51e7ef14142e..e051810d5127 100644 --- a/Documentation/accounting/psi.txt +++ b/Documentation/accounting/psi.txt @@ -62,3 +62,12 @@ well as medium and long term trends. The total absolute stall time is tracked and exported as well, to allow detection of latency spikes which wouldn't necessarily make a dent in the time averages, or to average trends over custom time frames. + +Cgroup2 interface +================= + +In a system with a CONFIG_CGROUP=y kernel and the cgroup2 filesystem +mounted, pressure stall information is also tracked for tasks grouped +into cgroups. Each subdirectory in the cgroupfs mountpoint contains +cpu.pressure, memory.pressure, and io.pressure files; the format is +the same as the /proc/pressure/ files. diff --git a/Documentation/cgroup-v2.txt b/Documentation/cgroup-v2.txt index 74cdeaed9f7a..a22879dba019 100644 --- a/Documentation/cgroup-v2.txt +++ b/Documentation/cgroup-v2.txt @@ -963,6 +963,12 @@ All time durations are in microseconds. $PERIOD duration. "max" for $MAX indicates no limit. If only one number is written, $MAX is updated. + cpu.pressure + A read-only nested-key file which exists on non-root cgroups. + + Shows pressure stall information for CPU. See + Documentation/accounting/psi.txt for details. + Memory ------ @@ -1199,6 +1205,12 @@ PAGE_SIZE multiple when read back. Swap usage hard limit. If a cgroup's swap usage reaches this limit, anonymous memory of the cgroup will not be swapped out. + memory.pressure + A read-only nested-key file which exists on non-root cgroups. + + Shows pressure stall information for memory. See + Documentation/accounting/psi.txt for details. + Usage Guidelines ~~~~~~~~~~~~~~~~ @@ -1334,6 +1346,12 @@ IO Interface Files 8:16 rbps=2097152 wbps=max riops=max wiops=max + io.pressure + A read-only nested-key file which exists on non-root cgroups. + + Shows pressure stall information for IO. See + Documentation/accounting/psi.txt for details. + Writeback ~~~~~~~~~ diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index dc5b70449dc6..280f18da956a 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef CONFIG_CGROUPS @@ -424,6 +425,9 @@ struct cgroup { /* used to schedule release agent */ struct work_struct release_agent_work; + /* used to track pressure stalls */ + struct psi_group psi; + /* used to store eBPF programs */ struct cgroup_bpf bpf; diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 473e0c0abb86..fd94c294c207 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -627,6 +627,11 @@ static inline void pr_cont_cgroup_path(struct cgroup *cgrp) pr_cont_kernfs_path(cgrp->kn); } +static inline struct psi_group *cgroup_psi(struct cgroup *cgrp) +{ + return &cgrp->psi; +} + static inline void cgroup_init_kthreadd(void) { /* @@ -680,6 +685,16 @@ static inline union kernfs_node_id *cgroup_get_kernfs_id(struct cgroup *cgrp) return NULL; } +static inline struct cgroup *cgroup_parent(struct cgroup *cgrp) +{ + return NULL; +} + +static inline struct psi_group *cgroup_psi(struct cgroup *cgrp) +{ + return NULL; +} + static inline bool task_under_cgroup_hierarchy(struct task_struct *task, struct cgroup *ancestor) { diff --git a/include/linux/psi.h b/include/linux/psi.h index 371af1479699..05c3dae3e9c5 100644 --- a/include/linux/psi.h +++ b/include/linux/psi.h @@ -4,6 +4,9 @@ #include #include +struct seq_file; +struct css_set; + #ifdef CONFIG_PSI extern bool psi_disabled; @@ -15,6 +18,14 @@ void psi_task_change(struct task_struct *task, u64 now, int clear, int set); void psi_memstall_enter(unsigned long *flags); void psi_memstall_leave(unsigned long *flags); +int psi_show(struct seq_file *s, struct psi_group *group, enum psi_res res); + +#ifdef CONFIG_CGROUPS +int psi_cgroup_alloc(struct cgroup *cgrp); +void psi_cgroup_free(struct cgroup *cgrp); +void cgroup_move_task(struct task_struct *p, struct css_set *to); +#endif + #else /* CONFIG_PSI */ static inline void psi_init(void) {} @@ -22,6 +33,20 @@ static inline void psi_init(void) {} static inline void psi_memstall_enter(unsigned long *flags) {} static inline void psi_memstall_leave(unsigned long *flags) {} +#ifdef CONFIG_CGROUPS +static inline int psi_cgroup_alloc(struct cgroup *cgrp) +{ + return 0; +} +static inline void psi_cgroup_free(struct cgroup *cgrp) +{ +} +static inline void cgroup_move_task(struct task_struct *p, struct css_set *to) +{ + rcu_assign_pointer(p->cgroups, to); +} +#endif + #endif /* CONFIG_PSI */ #endif /* _LINUX_PSI_H */ diff --git a/init/Kconfig b/init/Kconfig index ad61ddb5d68e..5c029f8d69f1 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -468,6 +468,10 @@ config PSI the share of walltime in which some or all tasks in the system are delayed due to contention of the respective resource. + In kernels with cgroup support (cgroup2 only), cgroups will + have cpu.pressure, memory.pressure, and io.pressure files, + which aggregate pressure stalls for the grouped tasks only. + For more details see Documentation/accounting/psi.txt. Say N if unsure. diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index a662bfcbea0e..bbb00b3ab752 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #define CREATE_TRACE_POINTS @@ -826,7 +827,7 @@ static void css_set_move_task(struct task_struct *task, */ WARN_ON_ONCE(task->flags & PF_EXITING); - rcu_assign_pointer(task->cgroups, to_cset); + cgroup_move_task(task, to_cset); list_add_tail(&task->cg_list, use_mg_tasks ? &to_cset->mg_tasks : &to_cset->tasks); } @@ -3388,6 +3389,21 @@ static int cpu_stat_show(struct seq_file *seq, void *v) return ret; } +#ifdef CONFIG_PSI +static int cgroup_io_pressure_show(struct seq_file *seq, void *v) +{ + return psi_show(seq, &seq_css(seq)->cgroup->psi, PSI_IO); +} +static int cgroup_memory_pressure_show(struct seq_file *seq, void *v) +{ + return psi_show(seq, &seq_css(seq)->cgroup->psi, PSI_MEM); +} +static int cgroup_cpu_pressure_show(struct seq_file *seq, void *v) +{ + return psi_show(seq, &seq_css(seq)->cgroup->psi, PSI_CPU); +} +#endif + static int cgroup_file_open(struct kernfs_open_file *of) { struct cftype *cft = of->kn->priv; @@ -4499,6 +4515,23 @@ static struct cftype cgroup_base_files[] = { .flags = CFTYPE_NOT_ON_ROOT, .seq_show = cpu_stat_show, }, +#ifdef CONFIG_PSI + { + .name = "io.pressure", + .flags = CFTYPE_NOT_ON_ROOT, + .seq_show = cgroup_io_pressure_show, + }, + { + .name = "memory.pressure", + .flags = CFTYPE_NOT_ON_ROOT, + .seq_show = cgroup_memory_pressure_show, + }, + { + .name = "cpu.pressure", + .flags = CFTYPE_NOT_ON_ROOT, + .seq_show = cgroup_cpu_pressure_show, + }, +#endif { } /* terminate */ }; @@ -4559,6 +4592,7 @@ static void css_free_rwork_fn(struct work_struct *work) */ cgroup_put(cgroup_parent(cgrp)); kernfs_put(cgrp->kn); + psi_cgroup_free(cgrp); if (cgroup_on_dfl(cgrp)) cgroup_stat_exit(cgrp); kfree(cgrp); @@ -4805,10 +4839,15 @@ static struct cgroup *cgroup_create(struct cgroup *parent) cgrp->self.parent = &parent->self; cgrp->root = root; cgrp->level = level; - ret = cgroup_bpf_inherit(cgrp); + + ret = psi_cgroup_alloc(cgrp); if (ret) goto out_idr_free; + ret = cgroup_bpf_inherit(cgrp); + if (ret) + goto out_psi_free; + for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) { cgrp->ancestor_ids[tcgrp->level] = tcgrp->id; @@ -4846,6 +4885,8 @@ static struct cgroup *cgroup_create(struct cgroup *parent) return cgrp; +out_psi_free: + psi_cgroup_free(cgrp); out_idr_free: cgroup_idr_remove(&root->cgroup_idr, cgrp->id); out_stat_exit: diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index 57ec86592b5a..a20f885da66f 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c @@ -464,6 +464,9 @@ static void psi_group_change(struct psi_group *group, int cpu, u64 now, void psi_task_change(struct task_struct *task, u64 now, int clear, int set) { +#ifdef CONFIG_CGROUPS + struct cgroup *cgroup, *parent; +#endif int cpu = task_cpu(task); if (psi_disabled) @@ -485,6 +488,18 @@ void psi_task_change(struct task_struct *task, u64 now, int clear, int set) task->psi_flags |= set; psi_group_change(&psi_system, cpu, now, clear, set); + +#ifdef CONFIG_CGROUPS + cgroup = task->cgroups->dfl_cgrp; + while (cgroup && (parent = cgroup_parent(cgroup))) { + struct psi_group *group; + + group = cgroup_psi(cgroup); + psi_group_change(group, cpu, now, clear, set); + + cgroup = parent; + } +#endif } /** @@ -551,8 +566,70 @@ void psi_memstall_leave(unsigned long *flags) rq_unlock_irq(rq, &rf); } -static int psi_show(struct seq_file *m, struct psi_group *group, - enum psi_res res) +#ifdef CONFIG_CGROUPS +int psi_cgroup_alloc(struct cgroup *cgroup) +{ + cgroup->psi.pcpu = alloc_percpu(struct psi_group_cpu); + if (!cgroup->psi.pcpu) + return -ENOMEM; + psi_group_init(&cgroup->psi); + return 0; +} + +void psi_cgroup_free(struct cgroup *cgroup) +{ + cancel_delayed_work_sync(&cgroup->psi.clock_work); + free_percpu(cgroup->psi.pcpu); +} + +/** + * cgroup_move_task - move task to a different cgroup + * @task: the task + * @to: the target css_set + * + * Move task to a new cgroup and safely migrate its associated stall + * state between the different groups. + * + * This function acquires the task's rq lock to lock out concurrent + * changes to the task's scheduling state and - in case the task is + * running - concurrent changes to its stall state. + */ +void cgroup_move_task(struct task_struct *task, struct css_set *to) +{ + unsigned int task_flags = 0; + struct rq_flags rf; + struct rq *rq; + u64 now; + + rq = task_rq_lock(task, &rf); + + if (task_on_rq_queued(task)) + task_flags = TSK_RUNNING; + else if (task->in_iowait) + task_flags = TSK_IOWAIT; + if (task->flags & PF_MEMSTALL) + task_flags |= TSK_MEMSTALL; + + if (task_flags) { + update_rq_clock(rq); + now = rq_clock(rq); + psi_task_change(task, now, task_flags, 0); + } + + /* + * Lame to do this here, but the scheduler cannot be locked + * from the outside, so we move cgroups from inside sched/. + */ + rcu_assign_pointer(task->cgroups, to); + + if (task_flags) + psi_task_change(task, now, 0, task_flags); + + task_rq_unlock(rq, task, &rf); +} +#endif /* CONFIG_CGROUPS */ + +int psi_show(struct seq_file *m, struct psi_group *group, enum psi_res res) { int full;