mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 03:27:03 +02:00
Merge "net: qrtr: Do not take sock lock on blocking recv"
This commit is contained in:
commit
ec8933f385
|
|
@ -111,9 +111,9 @@ static unsigned int qrtr_local_nid = 1;
|
|||
static RADIX_TREE(qrtr_nodes, GFP_ATOMIC);
|
||||
static DEFINE_SPINLOCK(qrtr_nodes_lock);
|
||||
/* broadcast list */
|
||||
static LIST_HEAD(qrtr_all_nodes);
|
||||
/* lock for qrtr_all_nodes and node reference */
|
||||
static DECLARE_RWSEM(qrtr_node_lock);
|
||||
static LIST_HEAD(qrtr_all_epts);
|
||||
/* lock for qrtr_all_epts */
|
||||
static DECLARE_RWSEM(qrtr_epts_lock);
|
||||
|
||||
/* local port allocation management */
|
||||
static DEFINE_XARRAY_ALLOC(qrtr_ports);
|
||||
|
|
@ -219,7 +219,7 @@ static void __qrtr_node_release(struct kref *kref)
|
|||
spin_unlock_irqrestore(&qrtr_nodes_lock, flags);
|
||||
|
||||
list_del(&node->item);
|
||||
up_write(&qrtr_node_lock);
|
||||
up_write(&qrtr_epts_lock);
|
||||
|
||||
skb_queue_purge(&node->rx_queue);
|
||||
|
||||
|
|
@ -245,7 +245,7 @@ static void qrtr_node_release(struct qrtr_node *node)
|
|||
{
|
||||
if (!node)
|
||||
return;
|
||||
kref_put_rwsem_lock(&node->ref, __qrtr_node_release, &qrtr_node_lock);
|
||||
kref_put_rwsem_lock(&node->ref, __qrtr_node_release, &qrtr_epts_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -572,8 +572,10 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
|
|||
qrtr_tx_resume(node, skb);
|
||||
} else {
|
||||
ipc = qrtr_port_lookup(cb->dst_port);
|
||||
if (!ipc)
|
||||
goto err;
|
||||
if (!ipc) {
|
||||
kfree_skb(skb);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (sock_queue_rcv_skb(&ipc->sk, skb)) {
|
||||
qrtr_port_put(ipc);
|
||||
|
|
@ -649,9 +651,9 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid)
|
|||
|
||||
qrtr_node_assign(node, nid);
|
||||
|
||||
down_write(&qrtr_node_lock);
|
||||
list_add(&node->item, &qrtr_all_nodes);
|
||||
up_write(&qrtr_node_lock);
|
||||
down_write(&qrtr_epts_lock);
|
||||
list_add(&node->item, &qrtr_all_epts);
|
||||
up_write(&qrtr_epts_lock);
|
||||
ep->node = node;
|
||||
|
||||
return 0;
|
||||
|
|
@ -969,17 +971,18 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,
|
|||
{
|
||||
struct sk_buff *skbn;
|
||||
|
||||
down_read(&qrtr_node_lock);
|
||||
list_for_each_entry(node, &qrtr_all_nodes, item) {
|
||||
down_read(&qrtr_epts_lock);
|
||||
list_for_each_entry(node, &qrtr_all_epts, item) {
|
||||
if (node->nid == QRTR_EP_NID_AUTO)
|
||||
continue;
|
||||
|
||||
skbn = skb_clone(skb, GFP_KERNEL);
|
||||
if (!skbn)
|
||||
break;
|
||||
skb_set_owner_w(skbn, skb->sk);
|
||||
qrtr_node_enqueue(node, skbn, type, from, to);
|
||||
}
|
||||
up_read(&qrtr_node_lock);
|
||||
up_read(&qrtr_epts_lock);
|
||||
|
||||
qrtr_local_enqueue(NULL, skb, type, from, to);
|
||||
|
||||
|
|
@ -1112,8 +1115,10 @@ static int qrtr_send_resume_tx(struct qrtr_cb *cb)
|
|||
return -EINVAL;
|
||||
|
||||
skb = qrtr_alloc_ctrl_packet(&pkt, GFP_KERNEL);
|
||||
if (!skb)
|
||||
if (!skb) {
|
||||
qrtr_node_release(node);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pkt->cmd = cpu_to_le32(QRTR_TYPE_RESUME_TX);
|
||||
pkt->client.node = cpu_to_le32(cb->dst_node);
|
||||
|
|
@ -1135,18 +1140,15 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg,
|
|||
struct qrtr_cb *cb;
|
||||
int copied, rc;
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
if (sock_flag(sk, SOCK_ZAPPED)) {
|
||||
release_sock(sk);
|
||||
if (sock_flag(sk, SOCK_ZAPPED))
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
skb = skb_recv_datagram(sk, flags, &rc);
|
||||
if (!skb) {
|
||||
release_sock(sk);
|
||||
if (!skb)
|
||||
return rc;
|
||||
}
|
||||
|
||||
lock_sock(sk);
|
||||
cb = (struct qrtr_cb *)skb->cb;
|
||||
|
||||
copied = skb->len;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user