Loading net/qrtr/qrtr.c +23 −16 Original line number Original line Diff line number Diff line Loading @@ -477,6 +477,8 @@ static int qrtr_tx_wait(struct qrtr_node *node, struct sockaddr_qrtr *to, /* Assume sk is set correctly for all data type packets */ /* Assume sk is set correctly for all data type packets */ timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); ret = timeo; for (;;) { mutex_lock(&node->qrtr_tx_lock); mutex_lock(&node->qrtr_tx_lock); flow = radix_tree_lookup(&node->qrtr_tx_flow, key); flow = radix_tree_lookup(&node->qrtr_tx_flow, key); if (!flow) { if (!flow) { Loading @@ -488,11 +490,7 @@ static int qrtr_tx_wait(struct qrtr_node *node, struct sockaddr_qrtr *to, INIT_LIST_HEAD(&flow->waiters); INIT_LIST_HEAD(&flow->waiters); radix_tree_insert(&node->qrtr_tx_flow, key, flow); radix_tree_insert(&node->qrtr_tx_flow, key, flow); } } mutex_unlock(&node->qrtr_tx_lock); ret = timeo; for (;;) { mutex_lock(&node->qrtr_tx_lock); if (atomic_read(&flow->pending) < QRTR_TX_FLOW_HIGH) { if (atomic_read(&flow->pending) < QRTR_TX_FLOW_HIGH) { atomic_inc(&flow->pending); atomic_inc(&flow->pending); confirm_rx = atomic_read(&flow->pending) == confirm_rx = atomic_read(&flow->pending) == Loading Loading @@ -1069,8 +1067,10 @@ static void qrtr_cleanup_flow_control(struct qrtr_node *node, { { struct qrtr_ctrl_pkt *pkt; struct qrtr_ctrl_pkt *pkt; unsigned long key; unsigned long key; void __rcu **slot; struct sockaddr_qrtr src; struct sockaddr_qrtr src; struct qrtr_tx_flow *flow; struct qrtr_tx_flow *flow; struct radix_tree_iter iter; struct qrtr_tx_flow_waiter *waiter; struct qrtr_tx_flow_waiter *waiter; struct qrtr_tx_flow_waiter *temp; struct qrtr_tx_flow_waiter *temp; u32 cmd; u32 cmd; Loading Loading @@ -1100,8 +1100,15 @@ static void qrtr_cleanup_flow_control(struct qrtr_node *node, sock_put(waiter->sk); sock_put(waiter->sk); kfree(waiter); kfree(waiter); } } 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); kfree(flow); radix_tree_delete(&node->qrtr_tx_flow, key); break; } } mutex_unlock(&node->qrtr_tx_lock); mutex_unlock(&node->qrtr_tx_lock); } } Loading Loading @@ -1132,8 +1139,8 @@ static void qrtr_handle_del_proc(struct qrtr_node *node, struct sk_buff *skb) sock_put(waiter->sk); sock_put(waiter->sk); kfree(waiter); kfree(waiter); } } radix_tree_iter_delete(&node->qrtr_tx_flow, &iter, slot); kfree(flow); kfree(flow); radix_tree_delete(&node->qrtr_tx_flow, iter.index); } } mutex_unlock(&node->qrtr_tx_lock); mutex_unlock(&node->qrtr_tx_lock); Loading Loading
net/qrtr/qrtr.c +23 −16 Original line number Original line Diff line number Diff line Loading @@ -477,6 +477,8 @@ static int qrtr_tx_wait(struct qrtr_node *node, struct sockaddr_qrtr *to, /* Assume sk is set correctly for all data type packets */ /* Assume sk is set correctly for all data type packets */ timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); ret = timeo; for (;;) { mutex_lock(&node->qrtr_tx_lock); mutex_lock(&node->qrtr_tx_lock); flow = radix_tree_lookup(&node->qrtr_tx_flow, key); flow = radix_tree_lookup(&node->qrtr_tx_flow, key); if (!flow) { if (!flow) { Loading @@ -488,11 +490,7 @@ static int qrtr_tx_wait(struct qrtr_node *node, struct sockaddr_qrtr *to, INIT_LIST_HEAD(&flow->waiters); INIT_LIST_HEAD(&flow->waiters); radix_tree_insert(&node->qrtr_tx_flow, key, flow); radix_tree_insert(&node->qrtr_tx_flow, key, flow); } } mutex_unlock(&node->qrtr_tx_lock); ret = timeo; for (;;) { mutex_lock(&node->qrtr_tx_lock); if (atomic_read(&flow->pending) < QRTR_TX_FLOW_HIGH) { if (atomic_read(&flow->pending) < QRTR_TX_FLOW_HIGH) { atomic_inc(&flow->pending); atomic_inc(&flow->pending); confirm_rx = atomic_read(&flow->pending) == confirm_rx = atomic_read(&flow->pending) == Loading Loading @@ -1069,8 +1067,10 @@ static void qrtr_cleanup_flow_control(struct qrtr_node *node, { { struct qrtr_ctrl_pkt *pkt; struct qrtr_ctrl_pkt *pkt; unsigned long key; unsigned long key; void __rcu **slot; struct sockaddr_qrtr src; struct sockaddr_qrtr src; struct qrtr_tx_flow *flow; struct qrtr_tx_flow *flow; struct radix_tree_iter iter; struct qrtr_tx_flow_waiter *waiter; struct qrtr_tx_flow_waiter *waiter; struct qrtr_tx_flow_waiter *temp; struct qrtr_tx_flow_waiter *temp; u32 cmd; u32 cmd; Loading Loading @@ -1100,8 +1100,15 @@ static void qrtr_cleanup_flow_control(struct qrtr_node *node, sock_put(waiter->sk); sock_put(waiter->sk); kfree(waiter); kfree(waiter); } } 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); kfree(flow); radix_tree_delete(&node->qrtr_tx_flow, key); break; } } mutex_unlock(&node->qrtr_tx_lock); mutex_unlock(&node->qrtr_tx_lock); } } Loading Loading @@ -1132,8 +1139,8 @@ static void qrtr_handle_del_proc(struct qrtr_node *node, struct sk_buff *skb) sock_put(waiter->sk); sock_put(waiter->sk); kfree(waiter); kfree(waiter); } } radix_tree_iter_delete(&node->qrtr_tx_flow, &iter, slot); kfree(flow); kfree(flow); radix_tree_delete(&node->qrtr_tx_flow, iter.index); } } mutex_unlock(&node->qrtr_tx_lock); mutex_unlock(&node->qrtr_tx_lock); Loading