From a729cfdb0bb42425447ea798f2af3a6b3b112148 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 11 Oct 2022 13:02:59 -0700 Subject: [PATCH 1/4] net: qrtr: ns: create kthread worker to process ns work If worker is not processing packets on control port fast enough, socket buffer may get full and result in drop of control packets. Creating dedicated worker thread to process control packets. CRs-Fixed: 2763561 Change-Id: I4585015cef2a507a9ba13014cd93f40e60f8a25a Signed-off-by: Deepak Kumar Singh Signed-off-by: Chris Lew --- net/qrtr/ns.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index b092de1678dc..1c4f93811350 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -23,8 +23,9 @@ static struct { struct socket *sock; struct sockaddr_qrtr bcast_sq; struct list_head lookups; - struct workqueue_struct *workqueue; - struct work_struct work; + struct kthread_worker kworker; + struct kthread_work work; + struct task_struct *task; int local_node; } qrtr_ns; @@ -574,7 +575,7 @@ static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, } } -static void qrtr_ns_worker(struct work_struct *work) +static void qrtr_ns_worker(struct kthread_work *work) { const struct qrtr_ctrl_pkt *pkt; size_t recv_buf_size = 4096; @@ -668,7 +669,7 @@ static void qrtr_ns_worker(struct work_struct *work) static void qrtr_ns_data_ready(struct sock *sk) { - queue_work(qrtr_ns.workqueue, &qrtr_ns.work); + kthread_queue_work(&qrtr_ns.kworker, &qrtr_ns.work); } int qrtr_ns_init(void) @@ -677,7 +678,8 @@ int qrtr_ns_init(void) int ret; INIT_LIST_HEAD(&qrtr_ns.lookups); - INIT_WORK(&qrtr_ns.work, qrtr_ns_worker); + kthread_init_worker(&qrtr_ns.kworker); + kthread_init_work(&qrtr_ns.work, qrtr_ns_worker); ret = sock_create_kern(&init_net, AF_QIPCRTR, SOCK_DGRAM, PF_QIPCRTR, &qrtr_ns.sock); @@ -690,9 +692,11 @@ int qrtr_ns_init(void) goto err_sock; } - qrtr_ns.workqueue = alloc_workqueue("qrtr_ns_handler", WQ_UNBOUND, 1); - if (!qrtr_ns.workqueue) { - ret = -ENOMEM; + qrtr_ns.task = kthread_run(kthread_worker_fn, &qrtr_ns.kworker, + "qrtr_ns"); + if (IS_ERR(qrtr_ns.task)) { + pr_err("failed to spawn worker thread %ld\n", + PTR_ERR(qrtr_ns.task)); goto err_sock; } @@ -718,7 +722,7 @@ int qrtr_ns_init(void) return 0; err_wq: - destroy_workqueue(qrtr_ns.workqueue); + kthread_stop(qrtr_ns.task); err_sock: sock_release(qrtr_ns.sock); return ret; @@ -727,8 +731,8 @@ EXPORT_SYMBOL_GPL(qrtr_ns_init); void qrtr_ns_remove(void) { - cancel_work_sync(&qrtr_ns.work); - destroy_workqueue(qrtr_ns.workqueue); + kthread_flush_worker(&qrtr_ns.kworker); + kthread_stop(qrtr_ns.task); sock_release(qrtr_ns.sock); } EXPORT_SYMBOL_GPL(qrtr_ns_remove); From 16c6929261ebe1423633ea277b86b893ce0ffe30 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 11 Oct 2022 13:03:22 -0700 Subject: [PATCH 2/4] net: qrtr: ns: Increase socket recvbuf Increase the socket recvbuf for the ns so control packets are not dropped in heavy traffic situations. This change will not actually set the recvbuf to INT_MAX but to the system defined rmem_max for sockets. Change-Id: I860cc1052080cc6e683b44bef1dd9f8fc1899f31 Signed-off-by: Jay Jayanna Signed-off-by: Chris Lew --- net/qrtr/ns.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index 1c4f93811350..7417b3c43568 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -675,6 +675,7 @@ static void qrtr_ns_data_ready(struct sock *sk) int qrtr_ns_init(void) { struct sockaddr_qrtr sq; + int rx_buf_sz = INT_MAX; int ret; INIT_LIST_HEAD(&qrtr_ns.lookups); @@ -711,6 +712,9 @@ int qrtr_ns_init(void) goto err_wq; } + sock_setsockopt(qrtr_ns.sock, SOL_SOCKET, SO_RCVBUF, + KERNEL_SOCKPTR((void *)&rx_buf_sz), sizeof(rx_buf_sz)); + qrtr_ns.bcast_sq.sq_family = AF_QIPCRTR; qrtr_ns.bcast_sq.sq_node = QRTR_NODE_BCAST; qrtr_ns.bcast_sq.sq_port = QRTR_PORT_CTRL; From d94badbdaab717bd251ed3997e517b9a59cae8a5 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 11 Oct 2022 13:03:27 -0700 Subject: [PATCH 3/4] net: qrtr: ns: Ignore ENODEV failures in ns Ignore the ENODEV failures returned by kernel_sendmsg(). These errors mean either the local port has closed or the remote has gone down. Neither of these scenarios are fatal and will eventually be handled through packets that are later queued on the control port. Also improve the logging messages to print the error code returned by kernel_sendmsg(). Change-Id: Ibcebd1f44a3fbc87febaa84b11e05675663da5a0 Signed-off-by: Chris Lew --- net/qrtr/ns.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index 7417b3c43568..61b18cbf6b69 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -156,8 +156,8 @@ static int service_announce_del(struct sockaddr_qrtr *dest, msg.msg_namelen = sizeof(*dest); ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); - if (ret < 0) - pr_err("failed to announce del service\n"); + if (ret < 0 && ret != -ENODEV) + pr_err("failed to announce del service %d\n", ret); return ret; } @@ -187,8 +187,8 @@ static void lookup_notify(struct sockaddr_qrtr *to, struct qrtr_server *srv, msg.msg_namelen = sizeof(*to); ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); - if (ret < 0) - pr_err("failed to send lookup notification\n"); + if (ret < 0 && ret != -ENODEV) + pr_err("failed to send lookup notification %d\n", ret); } static int announce_servers(struct sockaddr_qrtr *sq) @@ -206,7 +206,10 @@ static int announce_servers(struct sockaddr_qrtr *sq) xa_for_each(&node->servers, index, srv) { ret = service_announce_new(sq, srv); if (ret < 0) { - pr_err("failed to announce new service\n"); + if (ret == -ENODEV) + continue; + + pr_err("failed to announce new service %d\n", ret); return ret; } } @@ -311,7 +314,7 @@ static int say_hello(struct sockaddr_qrtr *dest) ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); if (ret < 0) - pr_err("failed to send hello msg\n"); + pr_err("failed to send hello msg %d\n", ret); return ret; } @@ -369,8 +372,8 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from) msg.msg_namelen = sizeof(sq); ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); - if (ret < 0) { - pr_err("failed to send bye cmd\n"); + if (ret < 0 && ret != -ENODEV) { + pr_err("failed to send bye cmd %d\n", ret); return ret; } } @@ -437,8 +440,8 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, msg.msg_namelen = sizeof(sq); ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); - if (ret < 0) { - pr_err("failed to send del client cmd\n"); + if (ret < 0 && ret != -ENODEV) { + pr_err("failed to send del client cmd %d\n", ret); return ret; } } @@ -468,7 +471,7 @@ static int ctrl_cmd_new_server(struct sockaddr_qrtr *from, if (srv->node == qrtr_ns.local_node) { ret = service_announce_new(&qrtr_ns.bcast_sq, srv); if (ret < 0) { - pr_err("failed to announce new service\n"); + pr_err("failed to announce new service %d\n", ret); return ret; } } From f540ee360d36889a94ed1104014824afc54e22b5 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Tue, 11 Oct 2022 13:03:32 -0700 Subject: [PATCH 4/4] net: qrtr: ns: Add pr_fmt to ns Add pr_fmt to the ns file for easier error log matching. Change-Id: I711735ee60c1fd9fde25850b8e625bb44c04f4c4 Signed-off-by: Chris Lew --- net/qrtr/ns.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index 61b18cbf6b69..6459024cfa44 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -6,6 +6,8 @@ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ +#define pr_fmt(fmt) "qrtr: %s(): " fmt, __func__ + #include #include #include