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