diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/devmap.c | 3 | ||||
| -rw-r--r-- | kernel/bpf/syscall.c | 11 | ||||
| -rw-r--r-- | kernel/bpf/verifier.c | 4 | ||||
| -rw-r--r-- | kernel/events/core.c | 13 | ||||
| -rw-r--r-- | kernel/trace/bpf_trace.c | 2 | 
5 files changed, 23 insertions, 10 deletions
| diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c index 4e2cdbb5629f..7f3b34452243 100644 --- a/kernel/bpf/devmap.c +++ b/kernel/bpf/devmap.c @@ -760,9 +760,6 @@ int dev_map_redirect_multi(struct net_device *dev, struct sk_buff *skb,  		for (i = 0; i < dtab->n_buckets; i++) {  			head = dev_map_index_hash(dtab, i);  			hlist_for_each_entry_safe(dst, next, head, index_hlist) { -				if (!dst) -					continue; -  				if (is_ifindex_excluded(excluded_devices, num_excluded,  							dst->dev->ifindex))  					continue; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 2222c3ff88e7..f45ed6adc092 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -2998,6 +2998,7 @@ static int bpf_obj_get(const union bpf_attr *attr)  void bpf_link_init(struct bpf_link *link, enum bpf_link_type type,  		   const struct bpf_link_ops *ops, struct bpf_prog *prog)  { +	WARN_ON(ops->dealloc && ops->dealloc_deferred);  	atomic64_set(&link->refcnt, 1);  	link->type = type;  	link->id = 0; @@ -3056,16 +3057,17 @@ static void bpf_link_defer_dealloc_mult_rcu_gp(struct rcu_head *rcu)  /* bpf_link_free is guaranteed to be called from process context */  static void bpf_link_free(struct bpf_link *link)  { +	const struct bpf_link_ops *ops = link->ops;  	bool sleepable = false;  	bpf_link_free_id(link->id);  	if (link->prog) {  		sleepable = link->prog->sleepable;  		/* detach BPF program, clean up used resources */ -		link->ops->release(link); +		ops->release(link);  		bpf_prog_put(link->prog);  	} -	if (link->ops->dealloc_deferred) { +	if (ops->dealloc_deferred) {  		/* schedule BPF link deallocation; if underlying BPF program  		 * is sleepable, we need to first wait for RCU tasks trace  		 * sync, then go through "classic" RCU grace period @@ -3074,9 +3076,8 @@ static void bpf_link_free(struct bpf_link *link)  			call_rcu_tasks_trace(&link->rcu, bpf_link_defer_dealloc_mult_rcu_gp);  		else  			call_rcu(&link->rcu, bpf_link_defer_dealloc_rcu_gp); -	} -	if (link->ops->dealloc) -		link->ops->dealloc(link); +	} else if (ops->dealloc) +		ops->dealloc(link);  }  static void bpf_link_put_deferred(struct work_struct *work) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 48f3a9acdef3..36ef8e96787e 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -11128,7 +11128,11 @@ BTF_ID(func, bpf_iter_css_task_new)  #else  BTF_ID_UNUSED  #endif +#ifdef CONFIG_BPF_EVENTS  BTF_ID(func, bpf_session_cookie) +#else +BTF_ID_UNUSED +#endif  static bool is_kfunc_ret_null(struct bpf_kfunc_call_arg_meta *meta)  { diff --git a/kernel/events/core.c b/kernel/events/core.c index f0128c5ff278..8f908f077935 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5384,6 +5384,7 @@ int perf_event_release_kernel(struct perf_event *event)  again:  	mutex_lock(&event->child_mutex);  	list_for_each_entry(child, &event->child_list, child_list) { +		void *var = NULL;  		/*  		 * Cannot change, child events are not migrated, see the @@ -5424,11 +5425,23 @@ again:  			 * this can't be the last reference.  			 */  			put_event(event); +		} else { +			var = &ctx->refcount;  		}  		mutex_unlock(&event->child_mutex);  		mutex_unlock(&ctx->mutex);  		put_ctx(ctx); + +		if (var) { +			/* +			 * If perf_event_free_task() has deleted all events from the +			 * ctx while the child_mutex got released above, make sure to +			 * notify about the preceding put_ctx(). +			 */ +			smp_mb(); /* pairs with wait_var_event() */ +			wake_up_var(var); +		}  		goto again;  	}  	mutex_unlock(&event->child_mutex); diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 6249dac61701..d1daeab1bbc1 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -3517,7 +3517,6 @@ static u64 bpf_uprobe_multi_entry_ip(struct bpf_run_ctx *ctx)  }  #endif /* CONFIG_UPROBES */ -#ifdef CONFIG_FPROBE  __bpf_kfunc_start_defs();  __bpf_kfunc bool bpf_session_is_return(void) @@ -3566,4 +3565,3 @@ static int __init bpf_kprobe_multi_kfuncs_init(void)  }  late_initcall(bpf_kprobe_multi_kfuncs_init); -#endif | 
