net: qrtr: Cleanup flow control during remote socket release

In case of Q6 SSR for MSM+MDM target flow control cleanup is
not happening for the remote socket on MSM which might cause
flow control hit for that remote socket.

Cleanup flow control for each deleted remote server or client.

Change-Id: Ieaff0d6bb2605e9db54f93dd199dd481420067af
Signed-off-by: Arun Prakash <app@codeaurora.org>
This commit is contained in:
Arun Prakash 2020-09-28 17:50:33 +05:30 committed by Sivaji Boddupilli
parent 48e493cb88
commit 7006b6e27f

View file

@ -212,6 +212,8 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,
int type, struct sockaddr_qrtr *from,
struct sockaddr_qrtr *to, unsigned int flags);
static void qrtr_handle_del_proc(struct sk_buff *skb);
static void qrtr_cleanup_flow_control(struct qrtr_node *node,
struct sk_buff *skb);
static void qrtr_log_tx_msg(struct qrtr_node *node, struct qrtr_hdr_v1 *hdr,
struct sk_buff *skb)
@ -1047,6 +1049,10 @@ static void qrtr_node_rx_work(struct kthread_work *work)
if (!ipc) {
kfree_skb(skb);
} else {
if (cb->type == QRTR_TYPE_DEL_SERVER ||
cb->type == QRTR_TYPE_DEL_CLIENT) {
qrtr_cleanup_flow_control(node, skb);
}
qrtr_sock_queue_skb(node, skb, ipc);
qrtr_port_put(ipc);
}
@ -1054,6 +1060,47 @@ static void qrtr_node_rx_work(struct kthread_work *work)
}
}
static void qrtr_cleanup_flow_control(struct qrtr_node *node,
struct sk_buff *skb)
{
struct qrtr_ctrl_pkt *pkt;
unsigned long key;
struct sockaddr_qrtr src;
struct qrtr_tx_flow *flow;
struct qrtr_tx_flow_waiter *waiter;
struct qrtr_tx_flow_waiter *temp;
u32 cmd;
pkt = (void *)skb->data;
cmd = le32_to_cpu(pkt->cmd);
if (cmd == QRTR_TYPE_DEL_SERVER) {
src.sq_node = le32_to_cpu(pkt->server.node);
src.sq_port = le32_to_cpu(pkt->server.port);
} else {
src.sq_node = le32_to_cpu(pkt->client.node);
src.sq_port = le32_to_cpu(pkt->client.port);
}
key = (u64)src.sq_node << 32 | src.sq_port;
mutex_lock(&node->qrtr_tx_lock);
flow = radix_tree_lookup(&node->qrtr_tx_flow, key);
if (!flow) {
mutex_unlock(&node->qrtr_tx_lock);
return;
}
list_for_each_entry_safe(waiter, temp, &flow->waiters, node) {
list_del(&waiter->node);
sock_put(waiter->sk);
kfree(waiter);
}
kfree(flow);
radix_tree_delete(&node->qrtr_tx_flow, key);
mutex_unlock(&node->qrtr_tx_lock);
}
static void qrtr_handle_del_proc(struct sk_buff *skb)
{
struct sockaddr_qrtr src = {AF_QIPCRTR, 0, QRTR_PORT_CTRL};