Loading net/qrtr/qrtr.c +29 −8 Original line number Diff line number Diff line Loading @@ -639,28 +639,49 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid) } EXPORT_SYMBOL_GPL(qrtr_endpoint_register); static void qrtr_notify_bye(u32 nid) { struct sockaddr_qrtr src = {AF_QIPCRTR, nid, QRTR_PORT_CTRL}; struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL}; struct qrtr_ctrl_pkt *pkt; struct sk_buff *skb; skb = qrtr_alloc_ctrl_packet(&pkt); if (!skb) return; pkt->cmd = cpu_to_le32(QRTR_TYPE_BYE); qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst); } /** * qrtr_endpoint_unregister - unregister endpoint * @ep: endpoint to unregister */ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep) { struct radix_tree_iter iter; struct qrtr_node *node = ep->node; struct sockaddr_qrtr src = {AF_QIPCRTR, node->nid, QRTR_PORT_CTRL}; struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL}; struct qrtr_ctrl_pkt *pkt; struct sk_buff *skb; unsigned long flags; void __rcu **slot; mutex_lock(&node->ep_lock); node->ep = NULL; mutex_unlock(&node->ep_lock); /* Notify the local controller about the event */ skb = qrtr_alloc_ctrl_packet(&pkt); if (skb) { pkt->cmd = cpu_to_le32(QRTR_TYPE_BYE); qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst); down_read(&qrtr_epts_lock); spin_lock_irqsave(&qrtr_nodes_lock, flags); radix_tree_for_each_slot(slot, &qrtr_nodes, &iter, 0) { if (node != *slot) continue; spin_unlock_irqrestore(&qrtr_nodes_lock, flags); qrtr_notify_bye(iter.index); spin_lock_irqsave(&qrtr_nodes_lock, flags); } spin_unlock_irqrestore(&qrtr_nodes_lock, flags); up_read(&qrtr_epts_lock); /* Wake up any transmitters waiting for resume-tx from the node */ wake_up_interruptible_all(&node->resume_tx); Loading Loading
net/qrtr/qrtr.c +29 −8 Original line number Diff line number Diff line Loading @@ -639,28 +639,49 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid) } EXPORT_SYMBOL_GPL(qrtr_endpoint_register); static void qrtr_notify_bye(u32 nid) { struct sockaddr_qrtr src = {AF_QIPCRTR, nid, QRTR_PORT_CTRL}; struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL}; struct qrtr_ctrl_pkt *pkt; struct sk_buff *skb; skb = qrtr_alloc_ctrl_packet(&pkt); if (!skb) return; pkt->cmd = cpu_to_le32(QRTR_TYPE_BYE); qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst); } /** * qrtr_endpoint_unregister - unregister endpoint * @ep: endpoint to unregister */ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep) { struct radix_tree_iter iter; struct qrtr_node *node = ep->node; struct sockaddr_qrtr src = {AF_QIPCRTR, node->nid, QRTR_PORT_CTRL}; struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL}; struct qrtr_ctrl_pkt *pkt; struct sk_buff *skb; unsigned long flags; void __rcu **slot; mutex_lock(&node->ep_lock); node->ep = NULL; mutex_unlock(&node->ep_lock); /* Notify the local controller about the event */ skb = qrtr_alloc_ctrl_packet(&pkt); if (skb) { pkt->cmd = cpu_to_le32(QRTR_TYPE_BYE); qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst); down_read(&qrtr_epts_lock); spin_lock_irqsave(&qrtr_nodes_lock, flags); radix_tree_for_each_slot(slot, &qrtr_nodes, &iter, 0) { if (node != *slot) continue; spin_unlock_irqrestore(&qrtr_nodes_lock, flags); qrtr_notify_bye(iter.index); spin_lock_irqsave(&qrtr_nodes_lock, flags); } spin_unlock_irqrestore(&qrtr_nodes_lock, flags); up_read(&qrtr_epts_lock); /* Wake up any transmitters waiting for resume-tx from the node */ wake_up_interruptible_all(&node->resume_tx); Loading