--- x/net/core/sock_map.c +++ y/net/core/sock_map.c @@ -932,11 +932,12 @@ static long sock_hash_delete_elem(struct struct bpf_shtab_bucket *bucket; struct bpf_shtab_elem *elem; int ret = -ENOENT; + unsigned long flags; hash = sock_hash_bucket_hash(key, key_size); bucket = sock_hash_select_bucket(htab, hash); - spin_lock_bh(&bucket->lock); + spin_lock_irqsave(&bucket->lock, flags); elem = sock_hash_lookup_elem_raw(&bucket->head, hash, key, key_size); if (elem) { hlist_del_rcu(&elem->node); @@ -944,7 +945,7 @@ static long sock_hash_delete_elem(struct sock_hash_free_elem(htab, elem); ret = 0; } - spin_unlock_bh(&bucket->lock); + spin_unlock_irqrestore(&bucket->lock, flags); return ret; } @@ -1143,6 +1144,8 @@ static void sock_hash_free(struct bpf_ma */ synchronize_rcu(); for (i = 0; i < htab->buckets_num; i++) { + unsigned long flags; + bucket = sock_hash_select_bucket(htab, i); /* We are racing with sock_hash_delete_from_link to @@ -1151,11 +1154,11 @@ static void sock_hash_free(struct bpf_ma * exists, psock exists and holds a ref to socket. That * lets us to grab a socket ref too. */ - spin_lock_bh(&bucket->lock); + spin_lock_irqsave(&bucket->lock, flags); hlist_for_each_entry(elem, &bucket->head, node) sock_hold(elem->sk); hlist_move_list(&bucket->head, &unlink_list); - spin_unlock_bh(&bucket->lock); + spin_unlock_irqrestore(&bucket->lock, flags); /* Process removed entries out of atomic context to * block for socket lock before deleting the psock's