diff options
Diffstat (limited to 'kernel/bpf/cgroup_iter.c')
| -rw-r--r-- | kernel/bpf/cgroup_iter.c | 16 | 
1 files changed, 15 insertions, 1 deletions
| diff --git a/kernel/bpf/cgroup_iter.c b/kernel/bpf/cgroup_iter.c index 9fcf09f2ef00..06989d278846 100644 --- a/kernel/bpf/cgroup_iter.c +++ b/kernel/bpf/cgroup_iter.c @@ -157,23 +157,37 @@ static const struct seq_operations cgroup_iter_seq_ops = {  	.show   = cgroup_iter_seq_show,  }; -BTF_ID_LIST_SINGLE(bpf_cgroup_btf_id, struct, cgroup) +BTF_ID_LIST_GLOBAL_SINGLE(bpf_cgroup_btf_id, struct, cgroup)  static int cgroup_iter_seq_init(void *priv, struct bpf_iter_aux_info *aux)  {  	struct cgroup_iter_priv *p = (struct cgroup_iter_priv *)priv;  	struct cgroup *cgrp = aux->cgroup.start; +	/* bpf_iter_attach_cgroup() has already acquired an extra reference +	 * for the start cgroup, but the reference may be released after +	 * cgroup_iter_seq_init(), so acquire another reference for the +	 * start cgroup. +	 */  	p->start_css = &cgrp->self; +	css_get(p->start_css);  	p->terminate = false;  	p->visited_all = false;  	p->order = aux->cgroup.order;  	return 0;  } +static void cgroup_iter_seq_fini(void *priv) +{ +	struct cgroup_iter_priv *p = (struct cgroup_iter_priv *)priv; + +	css_put(p->start_css); +} +  static const struct bpf_iter_seq_info cgroup_iter_seq_info = {  	.seq_ops		= &cgroup_iter_seq_ops,  	.init_seq_private	= cgroup_iter_seq_init, +	.fini_seq_private	= cgroup_iter_seq_fini,  	.seq_priv_size		= sizeof(struct cgroup_iter_priv),  }; |