From 533788bfca87ccf50916500a5c1144eb3816dd58 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Thu, 27 Oct 2022 11:07:47 -0700 Subject: [PATCH] net: qrtr: Add pm_wakeup_event() support In some cases system enters into suspend state before handling incoming packets and cause delay in communication. Add pm_wakup_event() to abort the suspend when a packet is received. Force a wakeup when queueing packets to a socket. This is needed to give userspace clients a chance to run if the device is going into system suspend. The wakeup event should force the device to abort suspend. The only node that should not behave this way is the SLPI node because sensor stream race conditions cause suspend issues and power drain issues. There was an update to add a device parameter into wakeup_source_register(). Change-Id: Ie69be3a46309f6a05cfbff0642b95194c2d6e955 Signed-off-by: Chris Lew --- net/qrtr/af_qrtr.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c index 3124c5115e49..fd67e66c2492 100644 --- a/net/qrtr/af_qrtr.c +++ b/net/qrtr/af_qrtr.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -153,6 +154,7 @@ static struct work_struct qrtr_backup_work; * @task: task to run the worker thread * @read_data: scheduled work for recv work * @say_hello: scheduled work for initiating hello + * @ws: wakeupsource avoid system suspend */ struct qrtr_node { struct mutex ep_lock; @@ -173,6 +175,8 @@ struct qrtr_node { struct task_struct *task; struct kthread_work read_data; struct kthread_work say_hello; + + struct wakeup_source *ws; }; /** @@ -254,6 +258,7 @@ static void __qrtr_node_release(struct kref *kref) kthread_flush_worker(&node->kworker); kthread_stop(node->task); skb_queue_purge(&node->rx_queue); + wakeup_source_unregister(node->ws); /* Free tx flow counters */ radix_tree_for_each_slot(slot, &node->qrtr_tx_flow, &iter, 0) { @@ -727,6 +732,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) if (cb->type != QRTR_TYPE_DATA || cb->dst_node != qrtr_local_nid) { skb_queue_tail(&node->rx_queue, skb); kthread_queue_work(&node->kworker, &node->read_data); + __pm_wakeup_event(node->ws, 0); } else { ipc = qrtr_port_lookup(cb->dst_port); if (!ipc) { @@ -739,6 +745,10 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) goto err; } + /* Force wakeup for all packets except for sensors */ + if (node->nid != 9) + __pm_wakeup_event(node->ws, 0); + qrtr_port_put(ipc); } @@ -985,6 +995,8 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id, up_write(&qrtr_epts_lock); ep->node = node; + node->ws = wakeup_source_register(NULL, "qrtr_ws"); + kthread_queue_work(&node->kworker, &node->say_hello); return 0; }