[PATCH net] Revert "net: qrtr: Send HELLO message on endpoint register"

Thorsten Leemhuis <[email protected]>
Newsgroups org.kernel.vger.netdev,dev.linux.lists.regressions,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
This reverts commit 544d85de4dc22c01badfd8cefa59829ce35c4858.

It causes suspend and resume problems for numerous people, including
maintainers and developers of ath wifi drivers. A fix was proposed[1],
but did not get any traction, so go for a revert instead.

Cc: Chris Lew <[email protected]>
Cc: Deepak Kumar Singh <[email protected]>
Cc: Pranav Mahesh Phansalkar <[email protected]>
Reported-by: Daniel J Blueman <[email protected]>
Link: https://lore.kernel.org/all/[email protected]/ [1]
Reported-by: Takashi Iwai <[email protected]>
Link: https://lore.kernel.org/all/[email protected]/
Reported-by: Vlastimil Babka <[email protected]>
Link: https://lore.kernel.org/all/[email protected]/
Reported-by: Jeff Johnson <[email protected]>
Link: https://lore.kernel.org/all/[email protected]/
Signed-off-by: Thorsten Leemhuis <[email protected]>
---

I'm not affected by this, but due to all those reporters mentioned above
it seems it would be good to get this fixed for 7.3-rc4, as Linus' rule
of thumb wrt to fixing regressions is "generally be 'within a week',
preferably before the next rc". Which is why I currently plan to ask
Linus to pull this directly. If this is a bad idea, just tell me.

The patch from Daniel linked above[1] could have fixed the problem, but
none of the developers of the culprit or the maintainers for this area
commented on it within a week, despite some "please fix this soon" and
"Tested-by" replies from various maintainers of other subsystems. So
let's go for a revert instead, the original change can later easily be
reapplied in improved form. The change reverted looks like something
that maybe shouldn't have been merged after -rc1 anyway, but this is not
my area of expertise, so I might be totally wrong there, as mentioned
earlier.

Ciao, Thorsten
---
 net/qrtr/af_qrtr.c | 66 ++--------------------------------------------
 net/qrtr/ns.c      | 35 +++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 65 deletions(-)

diff --git net/qrtr/af_qrtr.c net/qrtr/af_qrtr.c
index 78347c937af76b..a30fa56e6aa31c 100644
--- net/qrtr/af_qrtr.c
+++ net/qrtr/af_qrtr.c
@@ -9,7 +9,6 @@
 #include <linux/termios.h>	/* For TIOCINQ/OUTQ */
 #include <linux/spinlock.h>
 #include <linux/wait.h>
-#include <linux/workqueue.h>
 
 #include <net/sock.h>
 
@@ -121,10 +120,8 @@ static DEFINE_XARRAY_ALLOC(qrtr_ports);
  * @nid: node id
  * @qrtr_tx_flow: xarray of qrtr_tx_flow, keyed by node << 32 | port
  * @qrtr_tx_lock: lock for qrtr_tx_flow inserts
- * @hello_sent: hello packet send successful
  * @rx_queue: receive queue
  * @item: list item for broadcast list
- * @say_hello: delayed work for sending hello packet
  */
 struct qrtr_node {
 	struct mutex ep_lock;
@@ -135,11 +132,8 @@ struct qrtr_node {
 	struct xarray qrtr_tx_flow;
 	struct mutex qrtr_tx_lock; /* for qrtr_tx_flow */
 
-	bool hello_sent;
-
 	struct sk_buff_head rx_queue;
 	struct list_head item;
-	struct delayed_work say_hello;
 };
 
 /**
@@ -193,8 +187,6 @@ static void __qrtr_node_release(struct kref *kref)
 	list_del(&node->item);
 	mutex_unlock(&qrtr_node_lock);
 
-	cancel_delayed_work_sync(&node->say_hello);
-
 	skb_queue_purge(&node->rx_queue);
 
 	/* Free tx flow counters */
@@ -349,14 +341,6 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
 	size_t len = skb->len;
 	int rc, confirm_rx;
 
-	mutex_lock(&node->ep_lock);
-	if (!node->hello_sent && type != QRTR_TYPE_HELLO) {
-		mutex_unlock(&node->ep_lock);
-		kfree_skb(skb);
-		return -EAGAIN;
-	}
-	mutex_unlock(&node->ep_lock);
-
 	confirm_rx = qrtr_tx_wait(node, to->sq_node, to->sq_port, type);
 	if (confirm_rx < 0) {
 		kfree_skb(skb);
@@ -369,7 +353,7 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
 	hdr->src_node_id = cpu_to_le32(from->sq_node);
 	hdr->src_port_id = cpu_to_le32(from->sq_port);
 	if (to->sq_port == QRTR_PORT_CTRL) {
-		hdr->dst_node_id = cpu_to_le32(READ_ONCE(node->nid));
+		hdr->dst_node_id = cpu_to_le32(node->nid);
 		hdr->dst_port_id = cpu_to_le32(QRTR_PORT_CTRL);
 	} else {
 		hdr->dst_node_id = cpu_to_le32(to->sq_node);
@@ -388,8 +372,6 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
 			rc = node->ep->xmit(node->ep, skb);
 		else
 			kfree_skb(skb);
-		if (!rc && type == QRTR_TYPE_HELLO)
-			node->hello_sent = true;
 		mutex_unlock(&node->ep_lock);
 	}
 	/* Need to ensure that a subsequent message carries the otherwise lost
@@ -397,9 +379,6 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
 	if (rc && confirm_rx)
 		qrtr_tx_flow_failed(node, to->sq_node, to->sq_port);
 
-	if (rc == -EAGAIN && type == QRTR_TYPE_HELLO)
-		schedule_delayed_work(&node->say_hello, msecs_to_jiffies(100));
-
 	return rc;
 }
 
@@ -437,7 +416,7 @@ static void qrtr_node_assign(struct qrtr_node *node, unsigned int nid)
 	spin_lock_irqsave(&qrtr_nodes_lock, flags);
 	radix_tree_insert(&qrtr_nodes, nid, node);
 	if (node->nid == QRTR_EP_NID_AUTO)
-		WRITE_ONCE(node->nid, nid);
+		node->nid = nid;
 	spin_unlock_irqrestore(&qrtr_nodes_lock, flags);
 }
 
@@ -591,38 +570,6 @@ static struct sk_buff *qrtr_alloc_ctrl_packet(struct qrtr_ctrl_pkt **pkt,
 	return skb;
 }
 
-static void qrtr_hello_work(struct work_struct *work)
-{
-	struct sockaddr_qrtr from = {AF_QIPCRTR, 0, QRTR_PORT_CTRL};
-	struct sockaddr_qrtr to = {AF_QIPCRTR, 0, QRTR_PORT_CTRL};
-	struct qrtr_ctrl_pkt *pkt;
-	struct qrtr_node *node;
-	struct qrtr_sock *ctrl;
-	struct sk_buff *skb;
-
-	node = container_of(to_delayed_work(work), struct qrtr_node, say_hello);
-
-	/* NS must be bound before we can send; retry with backoff if not ready */
-	ctrl = qrtr_port_lookup(QRTR_PORT_CTRL);
-	if (!ctrl) {
-		schedule_delayed_work(&node->say_hello, msecs_to_jiffies(100));
-		return;
-	}
-
-	skb = qrtr_alloc_ctrl_packet(&pkt, GFP_KERNEL);
-	if (!skb) {
-		qrtr_port_put(ctrl);
-		schedule_delayed_work(&node->say_hello, msecs_to_jiffies(100));
-		return;
-	}
-
-	pkt->cmd = cpu_to_le32(QRTR_TYPE_HELLO);
-	from.sq_node = qrtr_local_nid;
-	to.sq_node = node->nid;
-	qrtr_node_enqueue(node, skb, QRTR_TYPE_HELLO, &from, &to);
-	qrtr_port_put(ctrl);
-}
-
 /**
  * qrtr_endpoint_register() - register a new endpoint
  * @ep: endpoint to register
@@ -648,9 +595,6 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid)
 	node->nid = QRTR_EP_NID_AUTO;
 	node->ep = ep;
 
-	node->hello_sent = false;
-	INIT_DELAYED_WORK(&node->say_hello, qrtr_hello_work);
-
 	xa_init(&node->qrtr_tx_flow);
 	mutex_init(&node->qrtr_tx_lock);
 
@@ -661,9 +605,6 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid)
 	mutex_unlock(&qrtr_node_lock);
 	ep->node = node;
 
-	/* Initiate HELLO handshake from the core layer */
-	schedule_delayed_work(&node->say_hello, 0);
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(qrtr_endpoint_register);
@@ -938,9 +879,6 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,
 
 	mutex_lock(&qrtr_node_lock);
 	list_for_each_entry(node, &qrtr_all_nodes, item) {
-		/* Skip nodes with no assigned node ID yet. */
-		if (READ_ONCE(node->nid) == QRTR_EP_NID_AUTO)
-			continue;
 		skbn = pskb_copy(skb, GFP_KERNEL);
 		if (!skbn)
 			break;
diff --git net/qrtr/ns.c net/qrtr/ns.c
index bcb090ee79d494..c5e7e01db24984 100644
--- net/qrtr/ns.c
+++ net/qrtr/ns.c
@@ -212,7 +212,6 @@ static void lookup_notify(struct sockaddr_qrtr *to, struct qrtr_server *srv,
 		pr_err("failed to send lookup notification\n");
 }
 
-/* Announce the list of servers registered on the local node */
 static int announce_servers(struct sockaddr_qrtr *sq)
 {
 	struct qrtr_server *srv;
@@ -327,8 +326,38 @@ static int server_del(struct qrtr_node *node, unsigned int port, bool bcast)
 	return 0;
 }
 
+static int say_hello(struct sockaddr_qrtr *dest)
+{
+	struct qrtr_ctrl_pkt pkt;
+	struct msghdr msg = { };
+	struct kvec iv;
+	int ret;
+
+	iv.iov_base = &pkt;
+	iv.iov_len = sizeof(pkt);
+
+	memset(&pkt, 0, sizeof(pkt));
+	pkt.cmd = cpu_to_le32(QRTR_TYPE_HELLO);
+
+	msg.msg_name = (struct sockaddr *)dest;
+	msg.msg_namelen = sizeof(*dest);
+
+	ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
+	if (ret < 0)
+		pr_err("failed to send hello msg\n");
+
+	return ret;
+}
+
+/* Announce the list of servers registered on the local node */
 static int ctrl_cmd_hello(struct sockaddr_qrtr *sq)
 {
+	int ret;
+
+	ret = say_hello(sq);
+	if (ret < 0)
+		return ret;
+
 	return announce_servers(sq);
 }
 
@@ -745,6 +774,10 @@ int qrtr_ns_init(void)
 	qrtr_ns.bcast_sq.sq_node = QRTR_NODE_BCAST;
 	qrtr_ns.bcast_sq.sq_port = QRTR_PORT_CTRL;
 
+	ret = say_hello(&qrtr_ns.bcast_sq);
+	if (ret < 0)
+		goto err_wq;
+
 	/* As the qrtr ns socket owner and creator is the same module, we have
 	 * to decrease the qrtr module reference count to guarantee that it
 	 * remains zero after the ns socket is created, otherwise, executing

base-commit: 5dd1818b15d98d4a20806cd00b1b40320b06004f
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.