Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e13155f7 authored by Arun Prakash's avatar Arun Prakash Committed by Sivaji Boddupilli
Browse files

net: qrtr: Cleanup flow control during DEL proc



Flow control cleanup of remote socket is not happening in
case of DEL proc which will cause flow control hit for that
remote socket once the proc is active again.

Cleanup flow control on the reception of DEL proc command.

Change-Id: I9cbaa121d7ca39a887b423ee274652dccaba8a38
Signed-off-by: default avatarArun Prakash <app@codeaurora.org>
parent 7006b6e2
Loading
Loading
Loading
Loading
+30 −3
Original line number Diff line number Diff line
@@ -211,7 +211,7 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
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_handle_del_proc(struct qrtr_node *node, struct sk_buff *skb);
static void qrtr_cleanup_flow_control(struct qrtr_node *node,
				      struct sk_buff *skb);

@@ -300,6 +300,10 @@ static void qrtr_log_rx_msg(struct qrtr_node *node, struct sk_buff *skb)
			QRTR_INFO(node->ilc,
				  "RX CTRL: cmd:0x%x node[0x%x]\n",
				  cb->type, cb->src_node);
		else if (cb->type == QRTR_TYPE_DEL_PROC)
			QRTR_INFO(node->ilc,
				  "RX CTRL: cmd:0x%x node[0x%x]\n",
				  cb->type, le32_to_cpu(pkt.proc.node));
	}
}

@@ -1043,7 +1047,7 @@ static void qrtr_node_rx_work(struct kthread_work *work)
			   cb->type == QRTR_TYPE_DATA) {
			qrtr_fwd_pkt(skb, cb);
		} else if (cb->type == QRTR_TYPE_DEL_PROC) {
			qrtr_handle_del_proc(skb);
			qrtr_handle_del_proc(node, skb);
		} else {
			ipc = qrtr_port_lookup(cb->dst_port);
			if (!ipc) {
@@ -1101,14 +1105,37 @@ static void qrtr_cleanup_flow_control(struct qrtr_node *node,
	mutex_unlock(&node->qrtr_tx_lock);
}

static void qrtr_handle_del_proc(struct sk_buff *skb)
static void qrtr_handle_del_proc(struct qrtr_node *node, struct sk_buff *skb)
{
	struct sockaddr_qrtr src = {AF_QIPCRTR, 0, QRTR_PORT_CTRL};
	struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL};
	struct qrtr_ctrl_pkt pkt = {0,};
	struct qrtr_tx_flow_waiter *waiter;
	struct qrtr_tx_flow_waiter *temp;
	struct radix_tree_iter iter;
	struct qrtr_tx_flow *flow;
	void __rcu **slot;
	unsigned long node_id;

	skb_copy_bits(skb, 0, &pkt, sizeof(pkt));
	src.sq_node = le32_to_cpu(pkt.proc.node);
	/* Free tx flow counters */
	mutex_lock(&node->qrtr_tx_lock);
	radix_tree_for_each_slot(slot, &node->qrtr_tx_flow, &iter, 0) {
		flow = rcu_dereference(*slot);
		/* extract node id from the index key */
		node_id = (iter.index & 0xFFFFFFFF00000000) >> 32;
		if (node_id != src.sq_node)
			continue;
		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, iter.index);
	}
	mutex_unlock(&node->qrtr_tx_lock);

	memset(&pkt, 0, sizeof(pkt));
	pkt.cmd = cpu_to_le32(QRTR_TYPE_BYE);