diff options
Diffstat (limited to 'kernel/bpf/stackmap.c')
| -rw-r--r-- | kernel/bpf/stackmap.c | 13 | 
1 files changed, 10 insertions, 3 deletions
| diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c index e8eefdf8cf3e..6e75bbee39f0 100644 --- a/kernel/bpf/stackmap.c +++ b/kernel/bpf/stackmap.c @@ -63,7 +63,8 @@ static inline int stack_map_data_size(struct bpf_map *map)  static int prealloc_elems_and_freelist(struct bpf_stack_map *smap)  { -	u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size; +	u64 elem_size = sizeof(struct stack_map_bucket) + +			(u64)smap->map.value_size;  	int err;  	smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries, @@ -179,7 +180,7 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,  	 * with build_id.  	 */  	if (!user || !current || !current->mm || irq_work_busy || -	    !mmap_read_trylock_non_owner(current->mm)) { +	    !mmap_read_trylock(current->mm)) {  		/* cannot access current->mm, fall back to ips */  		for (i = 0; i < trace_nr; i++) {  			id_offs[i].status = BPF_STACK_BUILD_ID_IP; @@ -204,9 +205,15 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,  	}  	if (!work) { -		mmap_read_unlock_non_owner(current->mm); +		mmap_read_unlock(current->mm);  	} else {  		work->mm = current->mm; + +		/* The lock will be released once we're out of interrupt +		 * context. Tell lockdep that we've released it now so +		 * it doesn't complain that we forgot to release it. +		 */ +		rwsem_release(¤t->mm->mmap_lock.dep_map, _RET_IP_);  		irq_work_queue(&work->irq_work);  	}  } |