net: qrtr: Send BYE message for all nodes on ept

An ept can represent multiple nodes in a system. If an ept unregisters,
qrtr should send a BYE control message for all the nodes that it
represents. Iterate through the node tree to find all the nodes that
belong to the ept.

Change-Id: I641bba615e689f59acecc9ac87fec61c3eecc0d1
Signed-off-by: Chris Lew <clew@codeaurora.org>
This commit is contained in:
Chris Lew 2018-07-17 14:08:33 -07:00
commit bb300aedea

View file

@ -638,28 +638,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);