diff options
Diffstat (limited to 'kernel/bpf/queue_stack_maps.c')
| -rw-r--r-- | kernel/bpf/queue_stack_maps.c | 21 | 
1 files changed, 18 insertions, 3 deletions
diff --git a/kernel/bpf/queue_stack_maps.c b/kernel/bpf/queue_stack_maps.c index 8d2ddcb7566b..d869f51ea93a 100644 --- a/kernel/bpf/queue_stack_maps.c +++ b/kernel/bpf/queue_stack_maps.c @@ -98,7 +98,12 @@ static long __queue_map_get(struct bpf_map *map, void *value, bool delete)  	int err = 0;  	void *ptr; -	raw_spin_lock_irqsave(&qs->lock, flags); +	if (in_nmi()) { +		if (!raw_spin_trylock_irqsave(&qs->lock, flags)) +			return -EBUSY; +	} else { +		raw_spin_lock_irqsave(&qs->lock, flags); +	}  	if (queue_stack_map_is_empty(qs)) {  		memset(value, 0, qs->map.value_size); @@ -128,7 +133,12 @@ static long __stack_map_get(struct bpf_map *map, void *value, bool delete)  	void *ptr;  	u32 index; -	raw_spin_lock_irqsave(&qs->lock, flags); +	if (in_nmi()) { +		if (!raw_spin_trylock_irqsave(&qs->lock, flags)) +			return -EBUSY; +	} else { +		raw_spin_lock_irqsave(&qs->lock, flags); +	}  	if (queue_stack_map_is_empty(qs)) {  		memset(value, 0, qs->map.value_size); @@ -193,7 +203,12 @@ static long queue_stack_map_push_elem(struct bpf_map *map, void *value,  	if (flags & BPF_NOEXIST || flags > BPF_EXIST)  		return -EINVAL; -	raw_spin_lock_irqsave(&qs->lock, irq_flags); +	if (in_nmi()) { +		if (!raw_spin_trylock_irqsave(&qs->lock, irq_flags)) +			return -EBUSY; +	} else { +		raw_spin_lock_irqsave(&qs->lock, irq_flags); +	}  	if (queue_stack_map_is_full(qs)) {  		if (!replace) {  | 
