bpf, sockmap: fix deadlocks in the sockhash and sockmap
[linux-2.6-microblaze.git] / net / core / sock_map.c
index 7c189c2..66305b7 100644 (file)
@@ -414,8 +414,9 @@ static int __sock_map_delete(struct bpf_stab *stab, struct sock *sk_test,
 {
        struct sock *sk;
        int err = 0;
+       unsigned long flags;
 
-       raw_spin_lock_bh(&stab->lock);
+       raw_spin_lock_irqsave(&stab->lock, flags);
        sk = *psk;
        if (!sk_test || sk_test == sk)
                sk = xchg(psk, NULL);
@@ -425,7 +426,7 @@ static int __sock_map_delete(struct bpf_stab *stab, struct sock *sk_test,
        else
                err = -EINVAL;
 
-       raw_spin_unlock_bh(&stab->lock);
+       raw_spin_unlock_irqrestore(&stab->lock, flags);
        return err;
 }
 
@@ -932,11 +933,12 @@ static long sock_hash_delete_elem(struct bpf_map *map, void *key)
        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);
 
-       raw_spin_lock_bh(&bucket->lock);
+       raw_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 +946,7 @@ static long sock_hash_delete_elem(struct bpf_map *map, void *key)
                sock_hash_free_elem(htab, elem);
                ret = 0;
        }
-       raw_spin_unlock_bh(&bucket->lock);
+       raw_spin_unlock_irqrestore(&bucket->lock, flags);
        return ret;
 }