mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-08-27 15:36:48 +00:00
cgroup: change rstat function signatures from cgroup-based to css-based
This non-functional change serves as preparation for moving to subsystem-based rstat trees. To simplify future commits, change the signatures of existing cgroup-based rstat functions to become css-based and rename them to reflect that. Though the signatures have changed, the implementations have not. Within these functions use the css->cgroup pointer to obtain the associated cgroup and allow code to function the same just as it did before this patch. At applicable call sites, pass the subsystem-specific css pointer as an argument or pass a pointer to cgroup::self if not in subsystem context. Note that cgroup_rstat_updated_list() and cgroup_rstat_push_children() are not altered yet since there would be a larger amount of css to cgroup conversions which may overcomplicate the code at this intermediate phase. Signed-off-by: JP Kobryn <inwardvessel@gmail.com> Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
845a724580
commit
a97915559f
@ -1144,7 +1144,7 @@ static void blkcg_rstat_flush(struct cgroup_subsys_state *css, int cpu)
|
||||
/*
|
||||
* We source root cgroup stats from the system-wide stats to avoid
|
||||
* tracking the same information twice and incurring overhead when no
|
||||
* cgroups are defined. For that reason, cgroup_rstat_flush in
|
||||
* cgroups are defined. For that reason, css_rstat_flush in
|
||||
* blkcg_print_stat does not actually fill out the iostat in the root
|
||||
* cgroup's blkcg_gq.
|
||||
*
|
||||
@ -1253,7 +1253,7 @@ static int blkcg_print_stat(struct seq_file *sf, void *v)
|
||||
if (!seq_css(sf)->parent)
|
||||
blkcg_fill_root_iostats();
|
||||
else
|
||||
cgroup_rstat_flush(blkcg->css.cgroup);
|
||||
css_rstat_flush(&blkcg->css);
|
||||
|
||||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(blkg, &blkcg->blkg_list, blkcg_node) {
|
||||
@ -2243,7 +2243,7 @@ void blk_cgroup_bio_start(struct bio *bio)
|
||||
}
|
||||
|
||||
u64_stats_update_end_irqrestore(&bis->sync, flags);
|
||||
cgroup_rstat_updated(blkcg->css.cgroup, cpu);
|
||||
css_rstat_updated(&blkcg->css, cpu);
|
||||
put_cpu();
|
||||
}
|
||||
|
||||
|
@ -536,7 +536,7 @@ struct cgroup {
|
||||
/*
|
||||
* A singly-linked list of cgroup structures to be rstat flushed.
|
||||
* This is a scratch field to be used exclusively by
|
||||
* cgroup_rstat_flush_locked() and protected by cgroup_rstat_lock.
|
||||
* css_rstat_flush_locked() and protected by cgroup_rstat_lock.
|
||||
*/
|
||||
struct cgroup *rstat_flush_next;
|
||||
|
||||
|
@ -693,8 +693,8 @@ static inline void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen)
|
||||
/*
|
||||
* cgroup scalable recursive statistics.
|
||||
*/
|
||||
void cgroup_rstat_updated(struct cgroup *cgrp, int cpu);
|
||||
void cgroup_rstat_flush(struct cgroup *cgrp);
|
||||
void css_rstat_updated(struct cgroup_subsys_state *css, int cpu);
|
||||
void css_rstat_flush(struct cgroup_subsys_state *css);
|
||||
|
||||
/*
|
||||
* Basic resource stats.
|
||||
|
@ -270,8 +270,8 @@ int cgroup_task_count(const struct cgroup *cgrp);
|
||||
/*
|
||||
* rstat.c
|
||||
*/
|
||||
int cgroup_rstat_init(struct cgroup *cgrp);
|
||||
void cgroup_rstat_exit(struct cgroup *cgrp);
|
||||
int css_rstat_init(struct cgroup_subsys_state *css);
|
||||
void css_rstat_exit(struct cgroup_subsys_state *css);
|
||||
void cgroup_rstat_boot(void);
|
||||
void cgroup_base_stat_cputime_show(struct seq_file *seq);
|
||||
|
||||
|
@ -1362,7 +1362,7 @@ static void cgroup_destroy_root(struct cgroup_root *root)
|
||||
|
||||
cgroup_unlock();
|
||||
|
||||
cgroup_rstat_exit(cgrp);
|
||||
css_rstat_exit(&cgrp->self);
|
||||
kernfs_destroy_root(root->kf_root);
|
||||
cgroup_free_root(root);
|
||||
}
|
||||
@ -2136,7 +2136,7 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
|
||||
if (ret)
|
||||
goto destroy_root;
|
||||
|
||||
ret = cgroup_rstat_init(root_cgrp);
|
||||
ret = css_rstat_init(&root_cgrp->self);
|
||||
if (ret)
|
||||
goto destroy_root;
|
||||
|
||||
@ -2178,7 +2178,7 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
|
||||
goto out;
|
||||
|
||||
exit_stats:
|
||||
cgroup_rstat_exit(root_cgrp);
|
||||
css_rstat_exit(&root_cgrp->self);
|
||||
destroy_root:
|
||||
kernfs_destroy_root(root->kf_root);
|
||||
root->kf_root = NULL;
|
||||
@ -5435,7 +5435,7 @@ static void css_free_rwork_fn(struct work_struct *work)
|
||||
cgroup_put(cgroup_parent(cgrp));
|
||||
kernfs_put(cgrp->kn);
|
||||
psi_cgroup_free(cgrp);
|
||||
cgroup_rstat_exit(cgrp);
|
||||
css_rstat_exit(css);
|
||||
kfree(cgrp);
|
||||
} else {
|
||||
/*
|
||||
@ -5465,7 +5465,7 @@ static void css_release_work_fn(struct work_struct *work)
|
||||
|
||||
/* css release path */
|
||||
if (!list_empty(&css->rstat_css_node)) {
|
||||
cgroup_rstat_flush(cgrp);
|
||||
css_rstat_flush(css);
|
||||
list_del_rcu(&css->rstat_css_node);
|
||||
}
|
||||
|
||||
@ -5493,7 +5493,7 @@ static void css_release_work_fn(struct work_struct *work)
|
||||
/* cgroup release path */
|
||||
TRACE_CGROUP_PATH(release, cgrp);
|
||||
|
||||
cgroup_rstat_flush(cgrp);
|
||||
css_rstat_flush(css);
|
||||
|
||||
spin_lock_irq(&css_set_lock);
|
||||
for (tcgrp = cgroup_parent(cgrp); tcgrp;
|
||||
@ -5686,17 +5686,13 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
|
||||
if (ret)
|
||||
goto out_free_cgrp;
|
||||
|
||||
ret = cgroup_rstat_init(cgrp);
|
||||
if (ret)
|
||||
goto out_cancel_ref;
|
||||
|
||||
/* create the directory */
|
||||
kn = kernfs_create_dir_ns(parent->kn, name, mode,
|
||||
current_fsuid(), current_fsgid(),
|
||||
cgrp, NULL);
|
||||
if (IS_ERR(kn)) {
|
||||
ret = PTR_ERR(kn);
|
||||
goto out_stat_exit;
|
||||
goto out_cancel_ref;
|
||||
}
|
||||
cgrp->kn = kn;
|
||||
|
||||
@ -5706,6 +5702,14 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
|
||||
cgrp->root = root;
|
||||
cgrp->level = level;
|
||||
|
||||
/*
|
||||
* Now that init_cgroup_housekeeping() has been called and cgrp->self
|
||||
* is setup, it is safe to perform rstat initialization on it.
|
||||
*/
|
||||
ret = css_rstat_init(&cgrp->self);
|
||||
if (ret)
|
||||
goto out_stat_exit;
|
||||
|
||||
ret = psi_cgroup_alloc(cgrp);
|
||||
if (ret)
|
||||
goto out_kernfs_remove;
|
||||
@ -5776,10 +5780,10 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
|
||||
|
||||
out_psi_free:
|
||||
psi_cgroup_free(cgrp);
|
||||
out_stat_exit:
|
||||
css_rstat_exit(&cgrp->self);
|
||||
out_kernfs_remove:
|
||||
kernfs_remove(cgrp->kn);
|
||||
out_stat_exit:
|
||||
cgroup_rstat_exit(cgrp);
|
||||
out_cancel_ref:
|
||||
percpu_ref_exit(&cgrp->self.refcnt);
|
||||
out_free_cgrp:
|
||||
|
@ -34,9 +34,10 @@ static struct cgroup_rstat_base_cpu *cgroup_rstat_base_cpu(
|
||||
* operations without handling high-frequency fast-path "update" events.
|
||||
*/
|
||||
static __always_inline
|
||||
unsigned long _cgroup_rstat_cpu_lock(raw_spinlock_t *cpu_lock, int cpu,
|
||||
struct cgroup *cgrp, const bool fast_path)
|
||||
unsigned long _css_rstat_cpu_lock(raw_spinlock_t *cpu_lock, int cpu,
|
||||
struct cgroup_subsys_state *css, const bool fast_path)
|
||||
{
|
||||
struct cgroup *cgrp = css->cgroup;
|
||||
unsigned long flags;
|
||||
bool contended;
|
||||
|
||||
@ -67,10 +68,12 @@ unsigned long _cgroup_rstat_cpu_lock(raw_spinlock_t *cpu_lock, int cpu,
|
||||
}
|
||||
|
||||
static __always_inline
|
||||
void _cgroup_rstat_cpu_unlock(raw_spinlock_t *cpu_lock, int cpu,
|
||||
struct cgroup *cgrp, unsigned long flags,
|
||||
void _css_rstat_cpu_unlock(raw_spinlock_t *cpu_lock, int cpu,
|
||||
struct cgroup_subsys_state *css, unsigned long flags,
|
||||
const bool fast_path)
|
||||
{
|
||||
struct cgroup *cgrp = css->cgroup;
|
||||
|
||||
if (fast_path)
|
||||
trace_cgroup_rstat_cpu_unlock_fastpath(cgrp, cpu, false);
|
||||
else
|
||||
@ -80,16 +83,17 @@ void _cgroup_rstat_cpu_unlock(raw_spinlock_t *cpu_lock, int cpu,
|
||||
}
|
||||
|
||||
/**
|
||||
* cgroup_rstat_updated - keep track of updated rstat_cpu
|
||||
* @cgrp: target cgroup
|
||||
* css_rstat_updated - keep track of updated rstat_cpu
|
||||
* @css: target cgroup subsystem state
|
||||
* @cpu: cpu on which rstat_cpu was updated
|
||||
*
|
||||
* @cgrp's rstat_cpu on @cpu was updated. Put it on the parent's matching
|
||||
* rstat_cpu->updated_children list. See the comment on top of
|
||||
* @css->cgroup's rstat_cpu on @cpu was updated. Put it on the parent's
|
||||
* matching rstat_cpu->updated_children list. See the comment on top of
|
||||
* cgroup_rstat_cpu definition for details.
|
||||
*/
|
||||
__bpf_kfunc void cgroup_rstat_updated(struct cgroup *cgrp, int cpu)
|
||||
__bpf_kfunc void css_rstat_updated(struct cgroup_subsys_state *css, int cpu)
|
||||
{
|
||||
struct cgroup *cgrp = css->cgroup;
|
||||
raw_spinlock_t *cpu_lock = per_cpu_ptr(&cgroup_rstat_cpu_lock, cpu);
|
||||
unsigned long flags;
|
||||
|
||||
@ -104,7 +108,7 @@ __bpf_kfunc void cgroup_rstat_updated(struct cgroup *cgrp, int cpu)
|
||||
if (data_race(cgroup_rstat_cpu(cgrp, cpu)->updated_next))
|
||||
return;
|
||||
|
||||
flags = _cgroup_rstat_cpu_lock(cpu_lock, cpu, cgrp, true);
|
||||
flags = _css_rstat_cpu_lock(cpu_lock, cpu, css, true);
|
||||
|
||||
/* put @cgrp and all ancestors on the corresponding updated lists */
|
||||
while (true) {
|
||||
@ -132,7 +136,7 @@ __bpf_kfunc void cgroup_rstat_updated(struct cgroup *cgrp, int cpu)
|
||||
cgrp = parent;
|
||||
}
|
||||
|
||||
_cgroup_rstat_cpu_unlock(cpu_lock, cpu, cgrp, flags, true);
|
||||
_css_rstat_cpu_unlock(cpu_lock, cpu, css, flags, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,7 +217,7 @@ static struct cgroup *cgroup_rstat_updated_list(struct cgroup *root, int cpu)
|
||||
struct cgroup *head = NULL, *parent, *child;
|
||||
unsigned long flags;
|
||||
|
||||
flags = _cgroup_rstat_cpu_lock(cpu_lock, cpu, root, false);
|
||||
flags = _css_rstat_cpu_lock(cpu_lock, cpu, &root->self, false);
|
||||
|
||||
/* Return NULL if this subtree is not on-list */
|
||||
if (!rstatc->updated_next)
|
||||
@ -250,14 +254,14 @@ static struct cgroup *cgroup_rstat_updated_list(struct cgroup *root, int cpu)
|
||||
if (child != root)
|
||||
head = cgroup_rstat_push_children(head, child, cpu);
|
||||
unlock_ret:
|
||||
_cgroup_rstat_cpu_unlock(cpu_lock, cpu, root, flags, false);
|
||||
_css_rstat_cpu_unlock(cpu_lock, cpu, &root->self, flags, false);
|
||||
return head;
|
||||
}
|
||||
|
||||
/*
|
||||
* A hook for bpf stat collectors to attach to and flush their stats.
|
||||
* Together with providing bpf kfuncs for cgroup_rstat_updated() and
|
||||
* cgroup_rstat_flush(), this enables a complete workflow where bpf progs that
|
||||
* Together with providing bpf kfuncs for css_rstat_updated() and
|
||||
* css_rstat_flush(), this enables a complete workflow where bpf progs that
|
||||
* collect cgroup stats can integrate with rstat for efficient flushing.
|
||||
*
|
||||
* A static noinline declaration here could cause the compiler to optimize away
|
||||
@ -285,9 +289,11 @@ __bpf_hook_end();
|
||||
* value -1 is used when obtaining the main lock else this is the CPU
|
||||
* number processed last.
|
||||
*/
|
||||
static inline void __cgroup_rstat_lock(struct cgroup *cgrp, int cpu_in_loop)
|
||||
static inline void __css_rstat_lock(struct cgroup_subsys_state *css,
|
||||
int cpu_in_loop)
|
||||
__acquires(&cgroup_rstat_lock)
|
||||
{
|
||||
struct cgroup *cgrp = css->cgroup;
|
||||
bool contended;
|
||||
|
||||
contended = !spin_trylock_irq(&cgroup_rstat_lock);
|
||||
@ -298,28 +304,32 @@ static inline void __cgroup_rstat_lock(struct cgroup *cgrp, int cpu_in_loop)
|
||||
trace_cgroup_rstat_locked(cgrp, cpu_in_loop, contended);
|
||||
}
|
||||
|
||||
static inline void __cgroup_rstat_unlock(struct cgroup *cgrp, int cpu_in_loop)
|
||||
static inline void __css_rstat_unlock(struct cgroup_subsys_state *css,
|
||||
int cpu_in_loop)
|
||||
__releases(&cgroup_rstat_lock)
|
||||
{
|
||||
struct cgroup *cgrp = css->cgroup;
|
||||
|
||||
trace_cgroup_rstat_unlock(cgrp, cpu_in_loop, false);
|
||||
spin_unlock_irq(&cgroup_rstat_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* cgroup_rstat_flush - flush stats in @cgrp's subtree
|
||||
* @cgrp: target cgroup
|
||||
* css_rstat_flush - flush stats in @css->cgroup's subtree
|
||||
* @css: target cgroup subsystem state
|
||||
*
|
||||
* Collect all per-cpu stats in @cgrp's subtree into the global counters
|
||||
* Collect all per-cpu stats in @css->cgroup's subtree into the global counters
|
||||
* and propagate them upwards. After this function returns, all cgroups in
|
||||
* the subtree have up-to-date ->stat.
|
||||
*
|
||||
* This also gets all cgroups in the subtree including @cgrp off the
|
||||
* This also gets all cgroups in the subtree including @css->cgroup off the
|
||||
* ->updated_children lists.
|
||||
*
|
||||
* This function may block.
|
||||
*/
|
||||
__bpf_kfunc void cgroup_rstat_flush(struct cgroup *cgrp)
|
||||
__bpf_kfunc void css_rstat_flush(struct cgroup_subsys_state *css)
|
||||
{
|
||||
struct cgroup *cgrp = css->cgroup;
|
||||
int cpu;
|
||||
|
||||
might_sleep();
|
||||
@ -327,7 +337,7 @@ __bpf_kfunc void cgroup_rstat_flush(struct cgroup *cgrp)
|
||||
struct cgroup *pos;
|
||||
|
||||
/* Reacquire for each CPU to avoid disabling IRQs too long */
|
||||
__cgroup_rstat_lock(cgrp, cpu);
|
||||
__css_rstat_lock(css, cpu);
|
||||
pos = cgroup_rstat_updated_list(cgrp, cpu);
|
||||
for (; pos; pos = pos->rstat_flush_next) {
|
||||
struct cgroup_subsys_state *css;
|
||||
@ -341,14 +351,15 @@ __bpf_kfunc void cgroup_rstat_flush(struct cgroup *cgrp)
|
||||
css->ss->css_rstat_flush(css, cpu);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
__cgroup_rstat_unlock(cgrp, cpu);
|
||||
__css_rstat_unlock(css, cpu);
|
||||
if (!cond_resched())
|
||||
cpu_relax();
|
||||
}
|
||||
}
|
||||
|
||||
int cgroup_rstat_init(struct cgroup *cgrp)
|
||||
int css_rstat_init(struct cgroup_subsys_state *css)
|
||||
{
|
||||
struct cgroup *cgrp = css->cgroup;
|
||||
int cpu;
|
||||
|
||||
/* the root cgrp has rstat_cpu preallocated */
|
||||
@ -379,11 +390,12 @@ int cgroup_rstat_init(struct cgroup *cgrp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cgroup_rstat_exit(struct cgroup *cgrp)
|
||||
void css_rstat_exit(struct cgroup_subsys_state *css)
|
||||
{
|
||||
struct cgroup *cgrp = css->cgroup;
|
||||
int cpu;
|
||||
|
||||
cgroup_rstat_flush(cgrp);
|
||||
css_rstat_flush(&cgrp->self);
|
||||
|
||||
/* sanity check */
|
||||
for_each_possible_cpu(cpu) {
|
||||
@ -490,7 +502,7 @@ static void cgroup_base_stat_cputime_account_end(struct cgroup *cgrp,
|
||||
unsigned long flags)
|
||||
{
|
||||
u64_stats_update_end_irqrestore(&rstatbc->bsync, flags);
|
||||
cgroup_rstat_updated(cgrp, smp_processor_id());
|
||||
css_rstat_updated(&cgrp->self, smp_processor_id());
|
||||
put_cpu_ptr(rstatbc);
|
||||
}
|
||||
|
||||
@ -592,12 +604,12 @@ void cgroup_base_stat_cputime_show(struct seq_file *seq)
|
||||
struct cgroup_base_stat bstat;
|
||||
|
||||
if (cgroup_parent(cgrp)) {
|
||||
cgroup_rstat_flush(cgrp);
|
||||
__cgroup_rstat_lock(cgrp, -1);
|
||||
css_rstat_flush(&cgrp->self);
|
||||
__css_rstat_lock(&cgrp->self, -1);
|
||||
bstat = cgrp->bstat;
|
||||
cputime_adjust(&cgrp->bstat.cputime, &cgrp->prev_cputime,
|
||||
&bstat.cputime.utime, &bstat.cputime.stime);
|
||||
__cgroup_rstat_unlock(cgrp, -1);
|
||||
__css_rstat_unlock(&cgrp->self, -1);
|
||||
} else {
|
||||
root_cgroup_cputime(&bstat);
|
||||
}
|
||||
@ -619,10 +631,10 @@ void cgroup_base_stat_cputime_show(struct seq_file *seq)
|
||||
cgroup_force_idle_show(seq, &bstat);
|
||||
}
|
||||
|
||||
/* Add bpf kfuncs for cgroup_rstat_updated() and cgroup_rstat_flush() */
|
||||
/* Add bpf kfuncs for css_rstat_updated() and css_rstat_flush() */
|
||||
BTF_KFUNCS_START(bpf_rstat_kfunc_ids)
|
||||
BTF_ID_FLAGS(func, cgroup_rstat_updated)
|
||||
BTF_ID_FLAGS(func, cgroup_rstat_flush, KF_SLEEPABLE)
|
||||
BTF_ID_FLAGS(func, css_rstat_updated)
|
||||
BTF_ID_FLAGS(func, css_rstat_flush, KF_SLEEPABLE)
|
||||
BTF_KFUNCS_END(bpf_rstat_kfunc_ids)
|
||||
|
||||
static const struct btf_kfunc_id_set bpf_rstat_kfunc_set = {
|
||||
|
@ -579,7 +579,7 @@ static inline void memcg_rstat_updated(struct mem_cgroup *memcg, int val)
|
||||
if (!val)
|
||||
return;
|
||||
|
||||
cgroup_rstat_updated(memcg->css.cgroup, cpu);
|
||||
css_rstat_updated(&memcg->css, cpu);
|
||||
statc = this_cpu_ptr(memcg->vmstats_percpu);
|
||||
for (; statc; statc = statc->parent) {
|
||||
stats_updates = READ_ONCE(statc->stats_updates) + abs(val);
|
||||
@ -611,7 +611,7 @@ static void __mem_cgroup_flush_stats(struct mem_cgroup *memcg, bool force)
|
||||
if (mem_cgroup_is_root(memcg))
|
||||
WRITE_ONCE(flush_last_time, jiffies_64);
|
||||
|
||||
cgroup_rstat_flush(memcg->css.cgroup);
|
||||
css_rstat_flush(&memcg->css);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -37,8 +37,9 @@ struct {
|
||||
__type(value, struct attach_counter);
|
||||
} attach_counters SEC(".maps");
|
||||
|
||||
extern void cgroup_rstat_updated(struct cgroup *cgrp, int cpu) __ksym;
|
||||
extern void cgroup_rstat_flush(struct cgroup *cgrp) __ksym;
|
||||
extern void css_rstat_updated(
|
||||
struct cgroup_subsys_state *css, int cpu) __ksym;
|
||||
extern void css_rstat_flush(struct cgroup_subsys_state *css) __ksym;
|
||||
|
||||
static uint64_t cgroup_id(struct cgroup *cgrp)
|
||||
{
|
||||
@ -75,7 +76,7 @@ int BPF_PROG(counter, struct cgroup *dst_cgrp, struct task_struct *leader,
|
||||
else if (create_percpu_attach_counter(cg_id, 1))
|
||||
return 0;
|
||||
|
||||
cgroup_rstat_updated(dst_cgrp, bpf_get_smp_processor_id());
|
||||
css_rstat_updated(&dst_cgrp->self, bpf_get_smp_processor_id());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -141,7 +142,7 @@ int BPF_PROG(dumper, struct bpf_iter_meta *meta, struct cgroup *cgrp)
|
||||
return 1;
|
||||
|
||||
/* Flush the stats to make sure we get the most updated numbers */
|
||||
cgroup_rstat_flush(cgrp);
|
||||
css_rstat_flush(&cgrp->self);
|
||||
|
||||
total_counter = bpf_map_lookup_elem(&attach_counters, &cg_id);
|
||||
if (!total_counter) {
|
||||
|
Loading…
Reference in New Issue
Block a user