Merge "net: qrtr: Do not take sock lock on blocking recv"

This commit is contained in:
qctecmdr 2022-10-07 16:59:24 -07:00 committed by Gerrit - the friendly Code Review server
commit ec8933f385

View File

@ -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;