diff options
Diffstat (limited to 'include/linux/bpf-cgroup.h')
| -rw-r--r-- | include/linux/bpf-cgroup.h | 58 | 
1 files changed, 49 insertions, 9 deletions
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h index c42e02b4d84b..8b77d08d4b47 100644 --- a/include/linux/bpf-cgroup.h +++ b/include/linux/bpf-cgroup.h @@ -20,14 +20,25 @@ struct bpf_sock_ops_kern;  struct bpf_cgroup_storage;  struct ctl_table;  struct ctl_table_header; +struct task_struct;  #ifdef CONFIG_CGROUP_BPF  extern struct static_key_false cgroup_bpf_enabled_key[MAX_BPF_ATTACH_TYPE];  #define cgroup_bpf_enabled(type) static_branch_unlikely(&cgroup_bpf_enabled_key[type]) -DECLARE_PER_CPU(struct bpf_cgroup_storage*, -		bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]); +#define BPF_CGROUP_STORAGE_NEST_MAX	8 + +struct bpf_cgroup_storage_info { +	struct task_struct *task; +	struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE]; +}; + +/* For each cpu, permit maximum BPF_CGROUP_STORAGE_NEST_MAX number of tasks + * to use bpf cgroup storage simultaneously. + */ +DECLARE_PER_CPU(struct bpf_cgroup_storage_info, +		bpf_cgroup_storage_info[BPF_CGROUP_STORAGE_NEST_MAX]);  #define for_each_cgroup_storage_type(stype) \  	for (stype = 0; stype < MAX_BPF_CGROUP_STORAGE_TYPE; stype++) @@ -161,13 +172,42 @@ static inline enum bpf_cgroup_storage_type cgroup_storage_type(  	return BPF_CGROUP_STORAGE_SHARED;  } -static inline void bpf_cgroup_storage_set(struct bpf_cgroup_storage -					  *storage[MAX_BPF_CGROUP_STORAGE_TYPE]) +static inline int bpf_cgroup_storage_set(struct bpf_cgroup_storage +					 *storage[MAX_BPF_CGROUP_STORAGE_TYPE])  {  	enum bpf_cgroup_storage_type stype; +	int i, err = 0; + +	preempt_disable(); +	for (i = 0; i < BPF_CGROUP_STORAGE_NEST_MAX; i++) { +		if (unlikely(this_cpu_read(bpf_cgroup_storage_info[i].task) != NULL)) +			continue; + +		this_cpu_write(bpf_cgroup_storage_info[i].task, current); +		for_each_cgroup_storage_type(stype) +			this_cpu_write(bpf_cgroup_storage_info[i].storage[stype], +				       storage[stype]); +		goto out; +	} +	err = -EBUSY; +	WARN_ON_ONCE(1); + +out: +	preempt_enable(); +	return err; +} + +static inline void bpf_cgroup_storage_unset(void) +{ +	int i; -	for_each_cgroup_storage_type(stype) -		this_cpu_write(bpf_cgroup_storage[stype], storage[stype]); +	for (i = 0; i < BPF_CGROUP_STORAGE_NEST_MAX; i++) { +		if (unlikely(this_cpu_read(bpf_cgroup_storage_info[i].task) != current)) +			continue; + +		this_cpu_write(bpf_cgroup_storage_info[i].task, NULL); +		return; +	}  }  struct bpf_cgroup_storage * @@ -418,7 +458,6 @@ int cgroup_bpf_prog_query(const union bpf_attr *attr,  			  union bpf_attr __user *uattr);  #else -struct bpf_prog;  struct cgroup_bpf {};  static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; }  static inline void cgroup_bpf_offline(struct cgroup *cgrp) {} @@ -448,8 +487,9 @@ static inline int cgroup_bpf_prog_query(const union bpf_attr *attr,  	return -EINVAL;  } -static inline void bpf_cgroup_storage_set( -	struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE]) {} +static inline int bpf_cgroup_storage_set( +	struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE]) { return 0; } +static inline void bpf_cgroup_storage_unset(void) {}  static inline int bpf_cgroup_storage_assign(struct bpf_prog_aux *aux,  					    struct bpf_map *map) { return 0; }  static inline struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(  |