summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/packet.h2
-rw-r--r--net/packet/af_packet.c16
-rw-r--r--net/packet/diag.c6
3 files changed, 15 insertions, 9 deletions
diff --git a/include/net/netns/packet.h b/include/net/netns/packet.h
index cb4e894c0f8..4780b080a43 100644
--- a/include/net/netns/packet.h
+++ b/include/net/netns/packet.h
@@ -8,7 +8,7 @@
#include <linux/spinlock.h>
struct netns_packet {
- spinlock_t sklist_lock;
+ struct mutex sklist_lock;
struct hlist_head sklist;
};
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index bfaa0a83f0e..f220c5bdb71 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2317,10 +2317,13 @@ static int packet_release(struct socket *sock)
net = sock_net(sk);
po = pkt_sk(sk);
- spin_lock_bh(&net->packet.sklist_lock);
+ mutex_lock(&net->packet.sklist_lock);
sk_del_node_init_rcu(sk);
+ mutex_unlock(&net->packet.sklist_lock);
+
+ preempt_disable();
sock_prot_inuse_add(net, sk->sk_prot, -1);
- spin_unlock_bh(&net->packet.sklist_lock);
+ preempt_enable();
spin_lock(&po->bind_lock);
unregister_prot_hook(sk, false);
@@ -2519,10 +2522,13 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
register_prot_hook(sk);
}
- spin_lock_bh(&net->packet.sklist_lock);
+ mutex_lock(&net->packet.sklist_lock);
sk_add_node_rcu(sk, &net->packet.sklist);
+ mutex_unlock(&net->packet.sklist_lock);
+
+ preempt_disable();
sock_prot_inuse_add(net, &packet_proto, 1);
- spin_unlock_bh(&net->packet.sklist_lock);
+ preempt_enable();
return 0;
out:
@@ -3775,7 +3781,7 @@ static const struct file_operations packet_seq_fops = {
static int __net_init packet_net_init(struct net *net)
{
- spin_lock_init(&net->packet.sklist_lock);
+ mutex_init(&net->packet.sklist_lock);
INIT_HLIST_HEAD(&net->packet.sklist);
if (!proc_net_fops_create(net, "packet", 0, &packet_seq_fops))
diff --git a/net/packet/diag.c b/net/packet/diag.c
index bc33fbe8a5e..39bce0d50df 100644
--- a/net/packet/diag.c
+++ b/net/packet/diag.c
@@ -177,8 +177,8 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
net = sock_net(skb->sk);
req = nlmsg_data(cb->nlh);
- rcu_read_lock();
- sk_for_each_rcu(sk, node, &net->packet.sklist) {
+ mutex_lock(&net->packet.sklist_lock);
+ sk_for_each(sk, node, &net->packet.sklist) {
if (!net_eq(sock_net(sk), net))
continue;
if (num < s_num)
@@ -192,7 +192,7 @@ next:
num++;
}
done:
- rcu_read_unlock();
+ mutex_unlock(&net->packet.sklist_lock);
cb->args[0] = num;
return skb->len;