Merge "net: qrtr: Use radix_tree_iter_delete to delete tx flow"
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index f0d1bd7..b0b5908 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -477,22 +477,20 @@
 	/* Assume sk is set correctly for all data type packets */
 	timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
 
-	mutex_lock(&node->qrtr_tx_lock);
-	flow = radix_tree_lookup(&node->qrtr_tx_flow, key);
-	if (!flow) {
-		flow = kzalloc(sizeof(*flow), GFP_KERNEL);
-		if (!flow) {
-			mutex_unlock(&node->qrtr_tx_lock);
-			return 1;
-		}
-		INIT_LIST_HEAD(&flow->waiters);
-		radix_tree_insert(&node->qrtr_tx_flow, key, flow);
-	}
-	mutex_unlock(&node->qrtr_tx_lock);
-
 	ret = timeo;
 	for (;;) {
 		mutex_lock(&node->qrtr_tx_lock);
+		flow = radix_tree_lookup(&node->qrtr_tx_flow, key);
+		if (!flow) {
+			flow = kzalloc(sizeof(*flow), GFP_KERNEL);
+			if (!flow) {
+				mutex_unlock(&node->qrtr_tx_lock);
+				return 1;
+			}
+			INIT_LIST_HEAD(&flow->waiters);
+			radix_tree_insert(&node->qrtr_tx_flow, key, flow);
+		}
+
 		if (atomic_read(&flow->pending) < QRTR_TX_FLOW_HIGH) {
 			atomic_inc(&flow->pending);
 			confirm_rx = atomic_read(&flow->pending) ==
@@ -1069,8 +1067,10 @@
 {
 	struct qrtr_ctrl_pkt *pkt;
 	unsigned long key;
+	void __rcu **slot;
 	struct sockaddr_qrtr src;
 	struct qrtr_tx_flow *flow;
+	struct radix_tree_iter iter;
 	struct qrtr_tx_flow_waiter *waiter;
 	struct qrtr_tx_flow_waiter *temp;
 	u32 cmd;
@@ -1100,8 +1100,15 @@
 		sock_put(waiter->sk);
 		kfree(waiter);
 	}
-	kfree(flow);
-	radix_tree_delete(&node->qrtr_tx_flow, key);
+
+	radix_tree_for_each_slot(slot, &node->qrtr_tx_flow, &iter, 0) {
+		if (flow == (struct qrtr_tx_flow *)rcu_dereference(*slot)) {
+			radix_tree_iter_delete(&node->qrtr_tx_flow,
+					       &iter, slot);
+			kfree(flow);
+			break;
+		}
+	}
 	mutex_unlock(&node->qrtr_tx_lock);
 }
 
@@ -1132,8 +1139,8 @@
 			sock_put(waiter->sk);
 			kfree(waiter);
 		}
+		radix_tree_iter_delete(&node->qrtr_tx_flow, &iter, slot);
 		kfree(flow);
-		radix_tree_delete(&node->qrtr_tx_flow, iter.index);
 	}
 	mutex_unlock(&node->qrtr_tx_lock);