From patchwork Tue Jan 7 05:47:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 11320453 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 41D8713A0 for ; Tue, 7 Jan 2020 05:48:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 208372075A for ; Tue, 7 Jan 2020 05:48:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="yG5p0DxG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727345AbgAGFsA (ORCPT ); Tue, 7 Jan 2020 00:48:00 -0500 Received: from mail-pf1-f195.google.com ([209.85.210.195]:33338 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727327AbgAGFr7 (ORCPT ); Tue, 7 Jan 2020 00:47:59 -0500 Received: by mail-pf1-f195.google.com with SMTP id z16so28049998pfk.0 for ; Mon, 06 Jan 2020 21:47:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=dp7a/ozyZfwB+kP9dnZlOFXZoCwRQSjpD5T5pIZB/8Q=; b=yG5p0DxGkRBjp/72mUW+KHkkmfaqAG3dRkQk/K8otpNmmxqbbHXTuqI3PI88MWL98a aH57NWaxfTAQLfjE05VRrzeS/XqFqlyvsOfBB6Q/zs0WEM2VqFWCQ/m7bx7OOp4TT2Wn 9Ju9v4nCwRJsqeEY4Rz4eg8o6Vznol5Hn+pF/f0r6UNZyolE2ioBWiP90HgXTDuDpG9n raS1ofswapv74TCZDwb3CQ46mUNg71E4OGWxNAqmgZReQc48uSIbGb8xM3fqfd7Hdc3Q 8k66w1JR8ImNTIdnzSmEQf3kILOH0JDy9Mlq3swvZj2VJnDZhZnhXFavf2aQYP86YYCB tPuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dp7a/ozyZfwB+kP9dnZlOFXZoCwRQSjpD5T5pIZB/8Q=; b=GlbMK+y3zo49pWbKd9+ulYNMyt5VzkHkjwZIoq/LifPwKv2OvIKemGmfc/ulsu6Yix PFNQ9JnFOoaKpj/5KiKVpuKzK8cKy59MyxQGw4aWlrY81gc4HwsE8a4pFtOmMD244iPi J3FuI8cEsjxS2qxH/EeorahPokuxoxYWBhZiy7iyeuAWUn+mTFWB8QNUS5UVcE/0WG0m 5sLWfpEkRLYDQzMQtaAr+LMlTS62lmI4/IDO6fW7hBowEKnusNluQ7UGayneF2Y7zQPY hINk8HmTVv0faRRojGNFfbACsev/MqYXiPcUQgtwDhMIxvm0Cl0vfeoB4/3FTX232zrp DeRg== X-Gm-Message-State: APjAAAXqU51MqvwBbZtONUDQ+eOvI5MjDpHO6TyCs8t5OqW49ZPR5uCd Fkgjpx0KXbLICNc0a9rjUC/KkA== X-Google-Smtp-Source: APXvYqxL6g+CoprISrZRW8EQIhr/95irjbEu71b+reVIWVK02C3ShkAlq/3bL3LoeYxiH57cIRzzMw== X-Received: by 2002:a63:e17:: with SMTP id d23mr115992276pgl.173.1578376077643; Mon, 06 Jan 2020 21:47:57 -0800 (PST) Received: from localhost.localdomain (104-188-17-28.lightspeed.sndgca.sbcglobal.net. [104.188.17.28]) by smtp.gmail.com with ESMTPSA id k21sm67129177pfa.63.2020.01.06.21.47.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jan 2020 21:47:57 -0800 (PST) From: Bjorn Andersson To: "David S. Miller" Cc: Arun Kumar Neelakantam , Chris Lew , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [PATCH v3 1/5] net: qrtr: Move resume-tx transmission to recvmsg Date: Mon, 6 Jan 2020 21:47:09 -0800 Message-Id: <20200107054713.3909260-2-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200107054713.3909260-1-bjorn.andersson@linaro.org> References: <20200107054713.3909260-1-bjorn.andersson@linaro.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org The confirm-rx bit is used to implement a per port flow control, in order to make sure that no messages are dropped due to resource exhaustion. Move the resume-tx transmission to recvmsg to only confirm messages as they are consumed by the application. Signed-off-by: Bjorn Andersson --- Changes since v2: - None net/qrtr/qrtr.c | 60 +++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index 88f98f27ad88..6c56a8ce83ef 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -362,22 +362,11 @@ static void qrtr_port_put(struct qrtr_sock *ipc); static void qrtr_node_rx_work(struct work_struct *work) { struct qrtr_node *node = container_of(work, struct qrtr_node, work); - struct qrtr_ctrl_pkt *pkt; - struct sockaddr_qrtr dst; - struct sockaddr_qrtr src; struct sk_buff *skb; while ((skb = skb_dequeue(&node->rx_queue)) != NULL) { struct qrtr_sock *ipc; - struct qrtr_cb *cb; - int confirm; - - cb = (struct qrtr_cb *)skb->cb; - src.sq_node = cb->src_node; - src.sq_port = cb->src_port; - dst.sq_node = cb->dst_node; - dst.sq_port = cb->dst_port; - confirm = !!cb->confirm_rx; + struct qrtr_cb *cb = (struct qrtr_cb *)skb->cb; qrtr_node_assign(node, cb->src_node); @@ -390,20 +379,6 @@ static void qrtr_node_rx_work(struct work_struct *work) qrtr_port_put(ipc); } - - if (confirm) { - skb = qrtr_alloc_ctrl_packet(&pkt); - if (!skb) - break; - - pkt->cmd = cpu_to_le32(QRTR_TYPE_RESUME_TX); - pkt->client.node = cpu_to_le32(dst.sq_node); - pkt->client.port = cpu_to_le32(dst.sq_port); - - if (qrtr_node_enqueue(node, skb, QRTR_TYPE_RESUME_TX, - &dst, &src)) - break; - } } } @@ -816,6 +791,34 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) return rc; } +static int qrtr_send_resume_tx(struct qrtr_cb *cb) +{ + struct sockaddr_qrtr remote = { AF_QIPCRTR, cb->src_node, cb->src_port }; + struct sockaddr_qrtr local = { AF_QIPCRTR, cb->dst_node, cb->dst_port }; + struct qrtr_ctrl_pkt *pkt; + struct qrtr_node *node; + struct sk_buff *skb; + int ret; + + node = qrtr_node_lookup(remote.sq_node); + if (!node) + return -EINVAL; + + skb = qrtr_alloc_ctrl_packet(&pkt); + if (!skb) + return -ENOMEM; + + pkt->cmd = cpu_to_le32(QRTR_TYPE_RESUME_TX); + pkt->client.node = cpu_to_le32(cb->dst_node); + pkt->client.port = cpu_to_le32(cb->dst_port); + + ret = qrtr_node_enqueue(node, skb, QRTR_TYPE_RESUME_TX, &local, &remote); + + qrtr_node_release(node); + + return ret; +} + static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, int flags) { @@ -838,6 +841,7 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, release_sock(sk); return rc; } + cb = (struct qrtr_cb *)skb->cb; copied = skb->len; if (copied > size) { @@ -851,7 +855,6 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, rc = copied; if (addr) { - cb = (struct qrtr_cb *)skb->cb; addr->sq_family = AF_QIPCRTR; addr->sq_node = cb->src_node; addr->sq_port = cb->src_port; @@ -859,6 +862,9 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, } out: + if (cb->confirm_rx) + qrtr_send_resume_tx(cb); + skb_free_datagram(sk, skb); release_sock(sk); From patchwork Tue Jan 7 05:47:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 11320455 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BA06D138D for ; Tue, 7 Jan 2020 05:48:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 846952087F for ; Tue, 7 Jan 2020 05:48:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="snWGlbZz" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727602AbgAGFsR (ORCPT ); Tue, 7 Jan 2020 00:48:17 -0500 Received: from mail-pg1-f196.google.com ([209.85.215.196]:39514 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727329AbgAGFr7 (ORCPT ); Tue, 7 Jan 2020 00:47:59 -0500 Received: by mail-pg1-f196.google.com with SMTP id b137so27957547pga.6 for ; Mon, 06 Jan 2020 21:47:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Q8WRI+qUQZlGszEtK3jeWsUzFsQlStZutV7Edw49HRw=; b=snWGlbZzbm52Mz1lT/882bGPX6l7KVbWuYotQZm7zWhmk/Gw2qxF+2bJW+axtnEMuH t5500qOs7GjrNNDOJW4TVUdR3Q5NvSgAqLDzseB/Y3d2+n/YlBJeNwgyzNmVImaGq1BY FdXSTiUg1MqKthlFjCjw4O1yAFX4zRokNTFgasiWDA+Cm7egIzDsopXWdULk31L/h8AW rvdUZ6qBIp/L01vPs8dZC4kYaX4q0ptCPunWAYew7Hge+EDlHxRZUQzq/c/euzwmQu+M E4ZApkK6Ez8t0OXwRe3tuEEfGlill0laOCEftYsRgZeqm3/CmLYG0TTIgR7831eR34O0 2qAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Q8WRI+qUQZlGszEtK3jeWsUzFsQlStZutV7Edw49HRw=; b=RjCqdNYNWEdeNmOIWvOQuJS3l6LCzf7ZJhBHHoOJQdGHea952uHZhTGFoO1rkKmwW4 i9EIjh/89kW34wa9WMJtOD9XB4gLWdAZJ5EAWQ+lJsqqD2jt0GtQYIZA4hIhdxIend+M b4Vrjn5W2/pXQ+bWRZfJu66hK1/fCMwqR8EepIbFIU2YNra9RK/ifUhQ0Ziz1K6u+7q3 4V7WWS7z7yDf3m/vG/OSGkpiYGLGR6Qqo49pjfmE/+aeZkvfdVAxZrT89f1WBGVlkslD AklpP6ztyUFsM9ewIWBeendfEU5NUYymG0bysHPZszt2WVg816j75J1rqxIOvO5nlN6s m1+Q== X-Gm-Message-State: APjAAAXkhjyJUzMZVEPEOGnKK9ExR9P2nOVgwjY2XV6HECy5WQzjGf4m ZBJAy5qmsKhhDcJAehfFbql1HQ== X-Google-Smtp-Source: APXvYqz6RS6rAhVvClehoCBs5c52r1sjw5fT2BTjjcHyVPvCNiUzmZ2fMS8GuyINaDDz6gJiPEM3tA== X-Received: by 2002:aa7:9092:: with SMTP id i18mr81869493pfa.238.1578376078978; Mon, 06 Jan 2020 21:47:58 -0800 (PST) Received: from localhost.localdomain (104-188-17-28.lightspeed.sndgca.sbcglobal.net. [104.188.17.28]) by smtp.gmail.com with ESMTPSA id k21sm67129177pfa.63.2020.01.06.21.47.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jan 2020 21:47:58 -0800 (PST) From: Bjorn Andersson To: "David S. Miller" Cc: Arun Kumar Neelakantam , Chris Lew , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [PATCH v3 2/5] net: qrtr: Implement outgoing flow control Date: Mon, 6 Jan 2020 21:47:10 -0800 Message-Id: <20200107054713.3909260-3-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200107054713.3909260-1-bjorn.andersson@linaro.org> References: <20200107054713.3909260-1-bjorn.andersson@linaro.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org In order to prevent overconsumption of resources on the remote side QRTR implements a flow control mechanism. The mechanism works by the sender keeping track of the number of outstanding unconfirmed messages that has been transmitted to a particular node/port pair. Upon count reaching a low watermark (L) the confirm_rx bit is set in the outgoing message and when the count reaching a high watermark (H) transmission will be blocked upon the reception of a resume_tx message from the remote, that resets the counter to 0. This guarantees that there will be at most 2H - L messages in flight. Values chosen for L and H are 5 and 10 respectively. Signed-off-by: Bjorn Andersson --- Changes since v2: - Replaced atomic "pending" with in and the use of a spin_lockon &resume_tx.lock - Move wait queue into qrtr_tx_flow struct to only wake up the sleepers that are actually affected by the notification - Take spinlock around the check in qrtr_tx_wait(), so that we don't need to spin around the wait_event to prevent > H clients continuing net/qrtr/qrtr.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 182 insertions(+), 7 deletions(-) diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index 6c56a8ce83ef..a6da5fa2a9b5 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -8,6 +8,7 @@ #include #include /* For TIOCINQ/OUTQ */ #include +#include #include @@ -113,6 +114,8 @@ static DEFINE_MUTEX(qrtr_port_lock); * @ep: endpoint * @ref: reference count for node * @nid: node id + * @qrtr_tx_flow: tree of qrtr_tx_flow, keyed by node << 32 | port + * @qrtr_tx_lock: lock for qrtr_tx_flow inserts * @rx_queue: receive queue * @work: scheduled work struct for recv work * @item: list item for broadcast list @@ -123,11 +126,29 @@ struct qrtr_node { struct kref ref; unsigned int nid; + struct radix_tree_root qrtr_tx_flow; + struct mutex qrtr_tx_lock; /* for qrtr_tx_flow */ + struct sk_buff_head rx_queue; struct work_struct work; struct list_head item; }; +/** + * struct qrtr_tx_flow - tx flow control + * @resume_tx: waiters for a resume tx from the remote + * @pending: number of waiting senders + * @tx_failed: indicates that a message with confirm_rx flag was lost + */ +struct qrtr_tx_flow { + struct wait_queue_head resume_tx; + int pending; + int tx_failed; +}; + +#define QRTR_TX_FLOW_HIGH 10 +#define QRTR_TX_FLOW_LOW 5 + static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb, int type, struct sockaddr_qrtr *from, struct sockaddr_qrtr *to); @@ -142,7 +163,9 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb, */ static void __qrtr_node_release(struct kref *kref) { + struct radix_tree_iter iter; struct qrtr_node *node = container_of(kref, struct qrtr_node, ref); + void __rcu **slot; if (node->nid != QRTR_EP_NID_AUTO) radix_tree_delete(&qrtr_nodes, node->nid); @@ -152,6 +175,12 @@ static void __qrtr_node_release(struct kref *kref) cancel_work_sync(&node->work); skb_queue_purge(&node->rx_queue); + + /* Free tx flow counters */ + radix_tree_for_each_slot(slot, &node->qrtr_tx_flow, &iter, 0) { + radix_tree_iter_delete(&node->qrtr_tx_flow, &iter, slot); + kfree(*slot); + } kfree(node); } @@ -171,6 +200,122 @@ static void qrtr_node_release(struct qrtr_node *node) kref_put_mutex(&node->ref, __qrtr_node_release, &qrtr_node_lock); } +/** + * qrtr_tx_resume() - reset flow control counter + * @node: qrtr_node that the QRTR_TYPE_RESUME_TX packet arrived on + * @skb: resume_tx packet + */ +static void qrtr_tx_resume(struct qrtr_node *node, struct sk_buff *skb) +{ + struct qrtr_ctrl_pkt *pkt = (struct qrtr_ctrl_pkt *)skb->data; + u64 remote_node = le32_to_cpu(pkt->client.node); + u32 remote_port = le32_to_cpu(pkt->client.port); + struct qrtr_tx_flow *flow; + unsigned long key; + + key = remote_node << 32 | remote_port; + + flow = radix_tree_lookup(&node->qrtr_tx_flow, key); + if (flow) { + spin_lock(&flow->resume_tx.lock); + flow->pending = 0; + spin_unlock(&flow->resume_tx.lock); + wake_up_interruptible_all(&flow->resume_tx); + } + + consume_skb(skb); +} + +/** + * qrtr_tx_wait() - flow control for outgoing packets + * @node: qrtr_node that the packet is to be send to + * @dest_node: node id of the destination + * @dest_port: port number of the destination + * @type: type of message + * + * The flow control scheme is based around the low and high "watermarks". When + * the low watermark is passed the confirm_rx flag is set on the outgoing + * message, which will trigger the remote to send a control message of the type + * QRTR_TYPE_RESUME_TX to reset the counter. If the high watermark is hit + * further transmision should be paused. + * + * Return: 1 if confirm_rx should be set, 0 otherwise or errno failure + */ +static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port, + int type) +{ + unsigned long key = (u64)dest_node << 32 | dest_port; + struct qrtr_tx_flow *flow; + int confirm_rx = 0; + int ret; + + /* Never set confirm_rx on non-data packets */ + if (type != QRTR_TYPE_DATA) + return 0; + + mutex_lock(&node->qrtr_tx_lock); + flow = radix_tree_lookup(&node->qrtr_tx_flow, key); + if (!flow) { + flow = kzalloc(sizeof(*flow), GFP_KERNEL); + if (flow) { + init_waitqueue_head(&flow->resume_tx); + radix_tree_insert(&node->qrtr_tx_flow, key, flow); + } + } + mutex_unlock(&node->qrtr_tx_lock); + + /* Set confirm_rx if we where unable to find and allocate a flow */ + if (!flow) + return 1; + + spin_lock_irq(&flow->resume_tx.lock); + ret = wait_event_interruptible_locked_irq(flow->resume_tx, + flow->pending < QRTR_TX_FLOW_HIGH || + flow->tx_failed || + !node->ep); + if (ret < 0) { + confirm_rx = ret; + } else if (!node->ep) { + confirm_rx = -EPIPE; + } else if (flow->tx_failed) { + flow->tx_failed = 0; + confirm_rx = 1; + } else { + flow->pending++; + confirm_rx = flow->pending == QRTR_TX_FLOW_LOW; + } + spin_unlock_irq(&flow->resume_tx.lock); + + return confirm_rx; +} + +/** + * qrtr_tx_flow_failed() - flag that tx of confirm_rx flagged messages failed + * @node: qrtr_node that the packet is to be send to + * @dest_node: node id of the destination + * @dest_port: port number of the destination + * + * Signal that the transmission of a message with confirm_rx flag failed. The + * flow's "pending" counter will keep incrementing towards QRTR_TX_FLOW_HIGH, + * at which point transmission would stall forever waiting for the resume TX + * message associated with the dropped confirm_rx message. + * Work around this by marking the flow as having a failed transmission and + * cause the next transmission attempt to be sent with the confirm_rx. + */ +static void qrtr_tx_flow_failed(struct qrtr_node *node, int dest_node, + int dest_port) +{ + unsigned long key = (u64)dest_node << 32 | dest_port; + struct qrtr_tx_flow *flow; + + flow = radix_tree_lookup(&node->qrtr_tx_flow, key); + if (flow) { + spin_lock_irq(&flow->resume_tx.lock); + flow->tx_failed = 1; + spin_unlock_irq(&flow->resume_tx.lock); + } +} + /* Pass an outgoing packet socket buffer to the endpoint driver. */ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, int type, struct sockaddr_qrtr *from, @@ -179,6 +324,13 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, struct qrtr_hdr_v1 *hdr; size_t len = skb->len; int rc = -ENODEV; + int confirm_rx; + + confirm_rx = qrtr_tx_wait(node, to->sq_node, to->sq_port, type); + if (confirm_rx < 0) { + kfree_skb(skb); + return confirm_rx; + } hdr = skb_push(skb, sizeof(*hdr)); hdr->version = cpu_to_le32(QRTR_PROTO_VER_1); @@ -194,7 +346,7 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, } hdr->size = cpu_to_le32(len); - hdr->confirm_rx = 0; + hdr->confirm_rx = !!confirm_rx; skb_put_padto(skb, ALIGN(len, 4)); @@ -205,6 +357,11 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, kfree_skb(skb); mutex_unlock(&node->ep_lock); + /* Need to ensure that a subsequent message carries the otherwise lost + * confirm_rx flag if we dropped this one */ + if (rc && confirm_rx) + qrtr_tx_flow_failed(node, to->sq_node, to->sq_port); + return rc; } @@ -311,7 +468,8 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) if (len != ALIGN(size, 4) + hdrlen) goto err; - if (cb->dst_port != QRTR_PORT_CTRL && cb->type != QRTR_TYPE_DATA) + if (cb->dst_port != QRTR_PORT_CTRL && cb->type != QRTR_TYPE_DATA && + cb->type != QRTR_TYPE_RESUME_TX) goto err; skb_put_data(skb, data + hdrlen, size); @@ -370,14 +528,18 @@ static void qrtr_node_rx_work(struct work_struct *work) qrtr_node_assign(node, cb->src_node); - ipc = qrtr_port_lookup(cb->dst_port); - if (!ipc) { - kfree_skb(skb); + if (cb->type == QRTR_TYPE_RESUME_TX) { + qrtr_tx_resume(node, skb); } else { - if (sock_queue_rcv_skb(&ipc->sk, skb)) + ipc = qrtr_port_lookup(cb->dst_port); + if (!ipc) { kfree_skb(skb); + } else { + if (sock_queue_rcv_skb(&ipc->sk, skb)) + kfree_skb(skb); - qrtr_port_put(ipc); + qrtr_port_put(ipc); + } } } } @@ -408,6 +570,8 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid) node->nid = QRTR_EP_NID_AUTO; node->ep = ep; + INIT_RADIX_TREE(&node->qrtr_tx_flow, GFP_KERNEL); + qrtr_node_assign(node, nid); mutex_lock(&qrtr_node_lock); @@ -428,8 +592,11 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep) 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 radix_tree_iter iter; struct qrtr_ctrl_pkt *pkt; + struct qrtr_tx_flow *flow; struct sk_buff *skb; + void __rcu **slot; mutex_lock(&node->ep_lock); node->ep = NULL; @@ -442,6 +609,14 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep) qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst); } + /* Wake up any transmitters waiting for resume-tx from the node */ + mutex_lock(&node->qrtr_tx_lock); + radix_tree_for_each_slot(slot, &node->qrtr_tx_flow, &iter, 0) { + flow = *slot; + wake_up_interruptible_all(&flow->resume_tx); + } + mutex_unlock(&node->qrtr_tx_lock); + qrtr_node_release(node); ep->node = NULL; } From patchwork Tue Jan 7 05:47:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 11320451 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 16EE3138C for ; Tue, 7 Jan 2020 05:48:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E984320848 for ; Tue, 7 Jan 2020 05:48:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="tEHba60/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727364AbgAGFsB (ORCPT ); Tue, 7 Jan 2020 00:48:01 -0500 Received: from mail-pf1-f195.google.com ([209.85.210.195]:43145 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727346AbgAGFsA (ORCPT ); Tue, 7 Jan 2020 00:48:00 -0500 Received: by mail-pf1-f195.google.com with SMTP id x6so26939078pfo.10 for ; Mon, 06 Jan 2020 21:48:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QW14bafe1w8Z5IsyZLv1Y8P7MJNChniS4xfMck61RNI=; b=tEHba60/tybGmDlgdPXzF2TruzOu2iEQ9ugQVOp5WB0v395QQnbEdhtpbaACGOUFwb za10LlwHCSYWYD5qlkNBxX5iD6JNOogVUTa41FNh02kEx/DhC6N8+HEZfLwemmDIvRGy g3erNafOcTy2V0L8jn3kGstv2U/yTTdTT1DguKnp7Ysv441QwCi+lRmKUBT4+M5qRTAa msZ27QfzryxDLuMS7Gr45ZM+gmheVdEt7ycl93kMW78Q1iOXayzzfCHOmPBPJ1o08aC2 St/LH/VIZ5NVzFQuzjzCIzYWlL+12pSGeu+OexMVB/5WpFn5WrzjPV9G43Zga7LUgfvY fdhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QW14bafe1w8Z5IsyZLv1Y8P7MJNChniS4xfMck61RNI=; b=cHQ0XpQMbQFlZggfmiPybKvZObdVJqSANAsFIerv7CjyN2P3sbjknSDem8Bmu/AoRs l9c1K4xQX7gw1XtKoNegPWRf7mYjzGcx4miFrmPFxVs2EeQp/t+PZjtF7/0JEZmDnOT6 aYCOHnTYgn3ZJ/AjpypriktcktmE7NMbNRijkR1SvsN8GpkwMNZ+b0vIk/D9crTT9EDr 7Wy3PCTuwF8lzxM0iVBSbzp6sOEM7YagYTpfvFsQlSqG0I+Pes48C/8BqwEKzV4mz5pK WUlE9IBJR0dREsATGTtcKdMvUDMmN3XjZvGKO0Bo0i8yFbKCft1p7uHMDlOLWXZ9L8XC nqBg== X-Gm-Message-State: APjAAAXomRg+TCi7l4GUJbpAMofG+RBVZ7VMuKr0bqXT6nBSWk8izE3X fKv3gpctZvCnQser9o8WK7VDlA== X-Google-Smtp-Source: APXvYqw/+U4ygJC5AbBpmPBwWDHDT7tPaXhtragdnFqBE7IpGe9OU+YV0CPMvBULpHy1yI9vuxRNJg== X-Received: by 2002:aa7:96b0:: with SMTP id g16mr108180089pfk.99.1578376080279; Mon, 06 Jan 2020 21:48:00 -0800 (PST) Received: from localhost.localdomain (104-188-17-28.lightspeed.sndgca.sbcglobal.net. [104.188.17.28]) by smtp.gmail.com with ESMTPSA id k21sm67129177pfa.63.2020.01.06.21.47.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jan 2020 21:47:59 -0800 (PST) From: Bjorn Andersson To: "David S. Miller" Cc: Arun Kumar Neelakantam , Chris Lew , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [PATCH v3 3/5] net: qrtr: Migrate node lookup tree to spinlock Date: Mon, 6 Jan 2020 21:47:11 -0800 Message-Id: <20200107054713.3909260-4-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200107054713.3909260-1-bjorn.andersson@linaro.org> References: <20200107054713.3909260-1-bjorn.andersson@linaro.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Move operations on the qrtr_nodes radix tree under a separate spinlock and make the qrtr_nodes tree GFP_ATOMIC, to allow operation from atomic context in a subsequent patch. Signed-off-by: Bjorn Andersson --- Changes since v2: - None net/qrtr/qrtr.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index a6da5fa2a9b5..c2bbfa7ec6e2 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -8,6 +8,7 @@ #include #include /* For TIOCINQ/OUTQ */ #include +#include #include #include @@ -98,10 +99,11 @@ static inline struct qrtr_sock *qrtr_sk(struct sock *sk) static unsigned int qrtr_local_nid = NUMA_NO_NODE; /* for node ids */ -static RADIX_TREE(qrtr_nodes, GFP_KERNEL); +static RADIX_TREE(qrtr_nodes, GFP_ATOMIC); +static DEFINE_SPINLOCK(qrtr_nodes_lock); /* broadcast list */ static LIST_HEAD(qrtr_all_nodes); -/* lock for qrtr_nodes, qrtr_all_nodes and node reference */ +/* lock for qrtr_all_nodes and node reference */ static DEFINE_MUTEX(qrtr_node_lock); /* local port allocation management */ @@ -165,10 +167,13 @@ static void __qrtr_node_release(struct kref *kref) { struct radix_tree_iter iter; struct qrtr_node *node = container_of(kref, struct qrtr_node, ref); + unsigned long flags; void __rcu **slot; + spin_lock_irqsave(&qrtr_nodes_lock, flags); if (node->nid != QRTR_EP_NID_AUTO) radix_tree_delete(&qrtr_nodes, node->nid); + spin_unlock_irqrestore(&qrtr_nodes_lock, flags); list_del(&node->item); mutex_unlock(&qrtr_node_lock); @@ -372,11 +377,12 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, static struct qrtr_node *qrtr_node_lookup(unsigned int nid) { struct qrtr_node *node; + unsigned long flags; - mutex_lock(&qrtr_node_lock); + spin_lock_irqsave(&qrtr_nodes_lock, flags); node = radix_tree_lookup(&qrtr_nodes, nid); node = qrtr_node_acquire(node); - mutex_unlock(&qrtr_node_lock); + spin_unlock_irqrestore(&qrtr_nodes_lock, flags); return node; } @@ -388,13 +394,15 @@ static struct qrtr_node *qrtr_node_lookup(unsigned int nid) */ static void qrtr_node_assign(struct qrtr_node *node, unsigned int nid) { + unsigned long flags; + if (node->nid != QRTR_EP_NID_AUTO || nid == QRTR_EP_NID_AUTO) return; - mutex_lock(&qrtr_node_lock); + spin_lock_irqsave(&qrtr_nodes_lock, flags); radix_tree_insert(&qrtr_nodes, nid, node); node->nid = nid; - mutex_unlock(&qrtr_node_lock); + spin_unlock_irqrestore(&qrtr_nodes_lock, flags); } /** From patchwork Tue Jan 7 05:47:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 11320447 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 11E24138D for ; Tue, 7 Jan 2020 05:48:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E395A207FD for ; Tue, 7 Jan 2020 05:48:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="u9xMo+eL" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727541AbgAGFsD (ORCPT ); Tue, 7 Jan 2020 00:48:03 -0500 Received: from mail-pf1-f195.google.com ([209.85.210.195]:40331 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727485AbgAGFsC (ORCPT ); Tue, 7 Jan 2020 00:48:02 -0500 Received: by mail-pf1-f195.google.com with SMTP id q8so28038025pfh.7 for ; Mon, 06 Jan 2020 21:48:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=38/4Y0ttJU3gjmWod1STa0fq8ebh+tOt6oi3RiKS+1w=; b=u9xMo+eLqQvQ/IJ7caEM6KhgyMLLfsJJ+eAdj9CADXeF5AXp9MFkVpBRJ2geqXQFYn C724xCooKW7BrsuIEV47tXlYikrpRY/HeIDTcKeY5xa/fGFSK4Y5/us3wFx0aSR3tswS X3/M5JNNT6oClwdCpMKVBJJpqUqffShvPrTdAB+AdBcYIKocuf2TBGy//aDGDXzaZssW nOOQp7FnsA5navJ/thkkoslj1QkbD2qQzNCeKKz1WkMFchYvWAtJKG6a87+f/KDgwo6T lmX437JvEcahq9Ra2HJtzJeKNQ/HzgaU7Ma2oN2jTCpiLguQiz2MmF/Q5mI62TiGDdOF Y3AA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=38/4Y0ttJU3gjmWod1STa0fq8ebh+tOt6oi3RiKS+1w=; b=a1JSjUid2cfhkPkHRj9H3n7aHSTLbsHQXcUkjMiq+4twrjyc29bfniQPtNb0Z9xqQf kqcnebzfoeZhMPDYcUKqj+m5DnfEiOQf2rqgfkfvC/l/859Vh8CjBHKlzuJsuuGv2AbP k3B+IetuS2SaqzUPXwxhmZ+GdAVv01GsAd4GYOp8kjyQG4UAx306GIioVeCebDwRwfcm e+zG2YHxC0+VgfvGOGs1MeyBhkM3JPnLCQys8ItffTdWNKtuL+IHQgXXrKQLJXkc5aab nAKvQeYyRuh5wyCDEVQ05CiWw4F7DcpJJIX/FmQyF96A4TRT+Ms8INvw6BeAL75ICLaL ureQ== X-Gm-Message-State: APjAAAX+PHMCYp5LwdbtBvQ02UDdVO3zaLTNaOD/lq6jgXXN3QQHPn1s VIKHy6rEbltFagbJIO9XxT+b3Q== X-Google-Smtp-Source: APXvYqxLPgfY0nt6d/aCSf9XEz2l1bafazaXRoHPfqGwSpjMNK72AM37LWljxj2SrkdcvhV4PE4ViQ== X-Received: by 2002:aa7:928b:: with SMTP id j11mr12265082pfa.176.1578376081489; Mon, 06 Jan 2020 21:48:01 -0800 (PST) Received: from localhost.localdomain (104-188-17-28.lightspeed.sndgca.sbcglobal.net. [104.188.17.28]) by smtp.gmail.com with ESMTPSA id k21sm67129177pfa.63.2020.01.06.21.48.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jan 2020 21:48:00 -0800 (PST) From: Bjorn Andersson To: "David S. Miller" Cc: Arun Kumar Neelakantam , Chris Lew , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [PATCH v3 4/5] net: qrtr: Make qrtr_port_lookup() use RCU Date: Mon, 6 Jan 2020 21:47:12 -0800 Message-Id: <20200107054713.3909260-5-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200107054713.3909260-1-bjorn.andersson@linaro.org> References: <20200107054713.3909260-1-bjorn.andersson@linaro.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org The important part of qrtr_port_lookup() wrt synchronization is that the function returns a reference counted struct qrtr_sock, or fail. As such we need only to ensure that an decrement of the object's refcount happens inbetween the finding of the object in the idr and qrtr_port_lookup()'s own increment of the object. By using RCU and putting a synchronization point after we remove the mapping from the idr, but before it can be released we achieve this - with the benefit of not having to hold the mutex in qrtr_port_lookup(). Signed-off-by: Bjorn Andersson --- Changes since v2: - None net/qrtr/qrtr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index c2bbfa7ec6e2..aae24c1d8531 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -641,11 +641,11 @@ static struct qrtr_sock *qrtr_port_lookup(int port) if (port == QRTR_PORT_CTRL) port = 0; - mutex_lock(&qrtr_port_lock); + rcu_read_lock(); ipc = idr_find(&qrtr_ports, port); if (ipc) sock_hold(&ipc->sk); - mutex_unlock(&qrtr_port_lock); + rcu_read_unlock(); return ipc; } @@ -687,6 +687,10 @@ static void qrtr_port_remove(struct qrtr_sock *ipc) mutex_lock(&qrtr_port_lock); idr_remove(&qrtr_ports, port); mutex_unlock(&qrtr_port_lock); + + /* Ensure that if qrtr_port_lookup() did enter the RCU read section we + * wait for it to up increment the refcount */ + synchronize_rcu(); } /* Assign port number to socket. From patchwork Tue Jan 7 05:47:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 11320449 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1E7F8138D for ; Tue, 7 Jan 2020 05:48:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E77BD2075A for ; Tue, 7 Jan 2020 05:48:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="OBuUT/c7" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727593AbgAGFsL (ORCPT ); Tue, 7 Jan 2020 00:48:11 -0500 Received: from mail-pl1-f196.google.com ([209.85.214.196]:33967 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727524AbgAGFsD (ORCPT ); Tue, 7 Jan 2020 00:48:03 -0500 Received: by mail-pl1-f196.google.com with SMTP id x17so22756767pln.1 for ; Mon, 06 Jan 2020 21:48:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QBdcBUa9neWrNycYPg6Xn0JWlrsGRPiALO7TyZJ27r4=; b=OBuUT/c7eH2sNBiwbWKpCm0EvCU+le18qBEhJRO7vm1Hy3Kkqd3b5ODS334pOOFELQ 5vZMxskS26ZUL+PGn+FmV/s3Aar0P0QpR1O7NZ+DVcKtCVgvXPOMbaFLlMCEMnNXVoPO 6/GClz7F0z23CCf9dqL2+WisKR+e3zKdX7yGrMDtF6WOcOzi4AgUHCGvg+mgsEKOGjPt mQZuxq/Dp3tGjQesb2FIrx1jsdC4h9WLORMWCkEysLMJ6EGc0RaNIOuzCIz6kIDx8mn1 SkhQjTsqbKWyhauWm7Ib/SeJU7Ggr2ZXMooQRjYdb/3J0JYZEPuPehuLenEN/k4Pn4EU 4+9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QBdcBUa9neWrNycYPg6Xn0JWlrsGRPiALO7TyZJ27r4=; b=Igki+iqwUhYymZWdnZRsGWsEOkXaFCRCguYoIbZwiDzlvHY6VE4DJ1oyInvAEMScFs htLHpnZPfFeVtTimnwT/DdWTWXRKRB9Ow3Zbbx2HV+F438zWaZWl2SwzRMzZdjrdGVAf sjK+zxZmj0SZq/YvbxxbXNjhis0iIl4ZWTyYJarC6IE9UqqBuljTdCF7z3TCCx38WWSC uHcW/y4UqMkkGX0kDE7yuuN1IfdxRH9S/HNecHx734gFy9Zr3I7dQqcwJG5ZV3Svinfx L63LzVVYehDFD9QwHXtcV12Kg4i/CNAA3q0+i0E8pMkJ8TnibLG/kh+C4CWk9IQz2tKJ 0/Lw== X-Gm-Message-State: APjAAAVraTjtgj/XIw3ChHPfYiv068ENJO/HB2miK/6l1VxVKap4RGo7 n31aY1k8cPK+Q6NFMgWULNpw3Q== X-Google-Smtp-Source: APXvYqzapVe65+YM76oisi5LeUPXFisQpAfqpgAqDCGAc2BVKQ+14xuTG6BZuHx3KfMhQBZmS1dSKA== X-Received: by 2002:a17:90a:a596:: with SMTP id b22mr680943pjq.28.1578376082555; Mon, 06 Jan 2020 21:48:02 -0800 (PST) Received: from localhost.localdomain (104-188-17-28.lightspeed.sndgca.sbcglobal.net. [104.188.17.28]) by smtp.gmail.com with ESMTPSA id k21sm67129177pfa.63.2020.01.06.21.48.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jan 2020 21:48:02 -0800 (PST) From: Bjorn Andersson To: "David S. Miller" Cc: Arun Kumar Neelakantam , Chris Lew , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [PATCH v3 5/5] net: qrtr: Remove receive worker Date: Mon, 6 Jan 2020 21:47:13 -0800 Message-Id: <20200107054713.3909260-6-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200107054713.3909260-1-bjorn.andersson@linaro.org> References: <20200107054713.3909260-1-bjorn.andersson@linaro.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Rather than enqueuing messages and scheduling a worker to deliver them to the individual sockets we can now, thanks to the previous work, move this directly into the endpoint callback. This saves us a context switch per incoming message and removes the possibility of an opportunistic suspend to happen between the message is coming from the endpoint until it ends up in the socket's receive buffer. Signed-off-by: Bjorn Andersson --- Changes since v2: - None net/qrtr/qrtr.c | 57 +++++++++++++++---------------------------------- 1 file changed, 17 insertions(+), 40 deletions(-) diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index aae24c1d8531..c94240d7c89f 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -119,7 +119,6 @@ static DEFINE_MUTEX(qrtr_port_lock); * @qrtr_tx_flow: tree of qrtr_tx_flow, keyed by node << 32 | port * @qrtr_tx_lock: lock for qrtr_tx_flow inserts * @rx_queue: receive queue - * @work: scheduled work struct for recv work * @item: list item for broadcast list */ struct qrtr_node { @@ -132,7 +131,6 @@ struct qrtr_node { struct mutex qrtr_tx_lock; /* for qrtr_tx_flow */ struct sk_buff_head rx_queue; - struct work_struct work; struct list_head item; }; @@ -157,6 +155,8 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb, static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb, int type, struct sockaddr_qrtr *from, struct sockaddr_qrtr *to); +static struct qrtr_sock *qrtr_port_lookup(int port); +static void qrtr_port_put(struct qrtr_sock *ipc); /* Release node resources and free the node. * @@ -178,7 +178,6 @@ static void __qrtr_node_release(struct kref *kref) list_del(&node->item); mutex_unlock(&qrtr_node_lock); - cancel_work_sync(&node->work); skb_queue_purge(&node->rx_queue); /* Free tx flow counters */ @@ -418,6 +417,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) struct qrtr_node *node = ep->node; const struct qrtr_hdr_v1 *v1; const struct qrtr_hdr_v2 *v2; + struct qrtr_sock *ipc; struct sk_buff *skb; struct qrtr_cb *cb; unsigned int size; @@ -482,8 +482,20 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) skb_put_data(skb, data + hdrlen, size); - skb_queue_tail(&node->rx_queue, skb); - schedule_work(&node->work); + qrtr_node_assign(node, cb->src_node); + + if (cb->type == QRTR_TYPE_RESUME_TX) { + qrtr_tx_resume(node, skb); + } else { + ipc = qrtr_port_lookup(cb->dst_port); + if (!ipc) + goto err; + + if (sock_queue_rcv_skb(&ipc->sk, skb)) + goto err; + + qrtr_port_put(ipc); + } return 0; @@ -518,40 +530,6 @@ static struct sk_buff *qrtr_alloc_ctrl_packet(struct qrtr_ctrl_pkt **pkt) return skb; } -static struct qrtr_sock *qrtr_port_lookup(int port); -static void qrtr_port_put(struct qrtr_sock *ipc); - -/* Handle and route a received packet. - * - * This will auto-reply with resume-tx packet as necessary. - */ -static void qrtr_node_rx_work(struct work_struct *work) -{ - struct qrtr_node *node = container_of(work, struct qrtr_node, work); - struct sk_buff *skb; - - while ((skb = skb_dequeue(&node->rx_queue)) != NULL) { - struct qrtr_sock *ipc; - struct qrtr_cb *cb = (struct qrtr_cb *)skb->cb; - - qrtr_node_assign(node, cb->src_node); - - if (cb->type == QRTR_TYPE_RESUME_TX) { - qrtr_tx_resume(node, skb); - } else { - ipc = qrtr_port_lookup(cb->dst_port); - if (!ipc) { - kfree_skb(skb); - } else { - if (sock_queue_rcv_skb(&ipc->sk, skb)) - kfree_skb(skb); - - qrtr_port_put(ipc); - } - } - } -} - /** * qrtr_endpoint_register() - register a new endpoint * @ep: endpoint to register @@ -571,7 +549,6 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid) if (!node) return -ENOMEM; - INIT_WORK(&node->work, qrtr_node_rx_work); kref_init(&node->ref); mutex_init(&node->ep_lock); skb_queue_head_init(&node->rx_queue);