diff options
Diffstat (limited to 'kernel/events/core.c')
| -rw-r--r-- | kernel/events/core.c | 19 | 
1 files changed, 15 insertions, 4 deletions
| diff --git a/kernel/events/core.c b/kernel/events/core.c index 3e691b75b2db..10cdb9c26b5d 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -662,7 +662,7 @@ static inline void update_cgrp_time_from_event(struct perf_event *event)  	/*  	 * Do not update time when cgroup is not active  	 */ -	if (cgrp == event->cgrp) +       if (cgroup_is_descendant(cgrp->css.cgroup, event->cgrp->css.cgroup))  		__update_cgrp_time(event->cgrp);  } @@ -901,9 +901,11 @@ list_update_cgroup_event(struct perf_event *event,  	cpuctx_entry = &cpuctx->cgrp_cpuctx_entry;  	/* cpuctx->cgrp is NULL unless a cgroup event is active in this CPU .*/  	if (add) { +		struct perf_cgroup *cgrp = perf_cgroup_from_task(current, ctx); +  		list_add(cpuctx_entry, this_cpu_ptr(&cgrp_cpuctx_list)); -		if (perf_cgroup_from_task(current, ctx) == event->cgrp) -			cpuctx->cgrp = event->cgrp; +		if (cgroup_is_descendant(cgrp->css.cgroup, event->cgrp->css.cgroup)) +			cpuctx->cgrp = cgrp;  	} else {  		list_del(cpuctx_entry);  		cpuctx->cgrp = NULL; @@ -8171,6 +8173,7 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd)  		}  	}  	event->tp_event->prog = prog; +	event->tp_event->bpf_prog_owner = event;  	return 0;  } @@ -8185,7 +8188,7 @@ static void perf_event_free_bpf_prog(struct perf_event *event)  		return;  	prog = event->tp_event->prog; -	if (prog) { +	if (prog && event->tp_event->bpf_prog_owner == event) {  		event->tp_event->prog = NULL;  		bpf_prog_put(prog);  	} @@ -8954,6 +8957,14 @@ static struct perf_cpu_context __percpu *find_pmu_context(int ctxn)  static void free_pmu_context(struct pmu *pmu)  { +	/* +	 * Static contexts such as perf_sw_context have a global lifetime +	 * and may be shared between different PMUs. Avoid freeing them +	 * when a single PMU is going away. +	 */ +	if (pmu->task_ctx_nr > perf_invalid_context) +		return; +  	mutex_lock(&pmus_lock);  	free_percpu(pmu->pmu_cpu_context);  	mutex_unlock(&pmus_lock); |