From patchwork Mon Sep 3 15:29:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 10586103 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3B9F013BB for ; Mon, 3 Sep 2018 15:30:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2AF9E294FC for ; Mon, 3 Sep 2018 15:30:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1F88229631; Mon, 3 Sep 2018 15:30:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A55CD294FC for ; Mon, 3 Sep 2018 15:30:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727474AbeICTvE (ORCPT ); Mon, 3 Sep 2018 15:51:04 -0400 Received: from mail-it0-f67.google.com ([209.85.214.67]:53814 "EHLO mail-it0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727434AbeICTvE (ORCPT ); Mon, 3 Sep 2018 15:51:04 -0400 Received: by mail-it0-f67.google.com with SMTP id p79-v6so1561723itp.3 for ; Mon, 03 Sep 2018 08:30:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=slOgaRHQNrzhn6x/uSnEhfb6Qim4fWc2u60YW/9DqOA=; b=BSvYNSx3ON+0xdFjUMumZ0p3H4iUlyaMu8WejHFy6bU0LbtUtY7hVUUrE6fU/X1aVK 5nZLbOK5IB9H2WHcrB1ZUG7soN+bg8eSCqX9XiqkFWDGy+7pV4dHcc07zqrxV9RqCha8 qxHYIpHECz3HwF3SIDRz271QvBVgvAhjQdSgcq7XMCUFoXc2sP/cvF1EZshn5I0MZaDL J3ZzxAu+6+pA6fc0cO9PEk5/wtRAczowPriBBVAW9HjGefEweuYeTG6KMgbgwyF8p2Az WTljPMlnpOYa/5x6BLVqOvPiXw0MsMVAZyfmMyy6IolFfPHgollIn63kqFlrbc1ExPo6 O7fQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=slOgaRHQNrzhn6x/uSnEhfb6Qim4fWc2u60YW/9DqOA=; b=mtkNr9xOs9mSI0K/X41nQmg+CvUJbqvd2Y4Q8KN+/GIrrorONRxxpQBF+hj9jA6JkK WIjtmKQPjd+qZ+QTXW+sEz7h8FzZLjA6xLBkYvIEfX33tBtbsU7lojed7x1X1CYN1EUX BvBaC02/+kCxt/lq+S+aK+WONCzOLhKPAoRG3F49C2CtQCcyJPqPyNpChofqT49gF8bt f4fpGaIYxktK2LeTgp2fg/quSR44kPlDTotn5bBh6hwcfvnyhExnOzoM4FSN21Y5WMWv x01xnrZHLTUlkEkabprKIcRFh2TPv0a+luDUP1I4gmYGvyK9Po1ZKWUAD4wkQbMlBabW xPtw== X-Gm-Message-State: APzg51C0Mwzcs/jyY2iMgRW1PQWPbavhDBsV0jrVZdtMdzVL2v0RfxiK HiqoEsHkbvXA5NewdWz+xuaeVjQ= X-Google-Smtp-Source: ANB0VdZxQYQPY/mCc4SrTUbZK6meoJjd+AJQm/8VvxeM4jXTqWJtZWxaHIuaZ+xx3rj6uPEQlTR5jQ== X-Received: by 2002:a24:4254:: with SMTP id i81-v6mr5090881itb.95.1535988623050; Mon, 03 Sep 2018 08:30:23 -0700 (PDT) Received: from leira.trondhjem.org.localdomain (c-68-40-195-73.hsd1.mi.comcast.net. [68.40.195.73]) by smtp.gmail.com with ESMTPSA id c25-v6sm7040027iob.30.2018.09.03.08.30.22 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 03 Sep 2018 08:30:22 -0700 (PDT) From: Trond Myklebust X-Google-Original-From: Trond Myklebust To: linux-nfs@vger.kernel.org Subject: [PATCH 25/27] SUNRPC: Allow calls to xprt_transmit() to drain the entire transmit queue Date: Mon, 3 Sep 2018 11:29:34 -0400 Message-Id: <20180903152936.24325-26-trond.myklebust@hammerspace.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180903152936.24325-25-trond.myklebust@hammerspace.com> References: <20180903152936.24325-1-trond.myklebust@hammerspace.com> <20180903152936.24325-2-trond.myklebust@hammerspace.com> <20180903152936.24325-3-trond.myklebust@hammerspace.com> <20180903152936.24325-4-trond.myklebust@hammerspace.com> <20180903152936.24325-5-trond.myklebust@hammerspace.com> <20180903152936.24325-6-trond.myklebust@hammerspace.com> <20180903152936.24325-7-trond.myklebust@hammerspace.com> <20180903152936.24325-8-trond.myklebust@hammerspace.com> <20180903152936.24325-9-trond.myklebust@hammerspace.com> <20180903152936.24325-10-trond.myklebust@hammerspace.com> <20180903152936.24325-11-trond.myklebust@hammerspace.com> <20180903152936.24325-12-trond.myklebust@hammerspace.com> <20180903152936.24325-13-trond.myklebust@hammerspace.com> <20180903152936.24325-14-trond.myklebust@hammerspace.com> <20180903152936.24325-15-trond.myklebust@hammerspace.com> <20180903152936.24325-16-trond.myklebust@hammerspace.com> <20180903152936.24325-17-trond.myklebust@hammerspace.com> <20180903152936.24325-18-trond.myklebust@hammerspace.com> <20180903152936.24325-19-trond.myklebust@hammerspace.com> <20180903152936.24325-20-trond.myklebust@hammerspace.com> <20180903152936.24325-21-trond.myklebust@hammerspace.com> <20180903152936.24325-22-trond.myklebust@hammerspace.com> <20180903152936.24325-23-trond.myklebust@hammerspace.com> <20180903152936.24325-24-trond.myklebust@hammerspace.com> <20180903152936.24325-25-trond.myklebust@hammerspace.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Rather than forcing each and every RPC task to grab the socket write lock in order to send itself, we allow whichever task is holding the write lock to attempt to drain the entire transmit queue. Signed-off-by: Trond Myklebust --- net/sunrpc/xprt.c | 82 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 13 deletions(-) diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index b85e2c4fa115..1ce32e555c9b 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1116,15 +1116,20 @@ void xprt_end_transmit(struct rpc_task *task) } /** - * xprt_transmit - send an RPC request on a transport - * @task: controlling RPC task + * xprt_request_transmit - send an RPC request on a transport + * @req: pointer to request to transmit + * @snd_task: RPC task that owns the transport lock * - * We have to copy the iovec because sendmsg fiddles with its contents. + * This performs the transmission of a single request. + * Note that if the request is not the same as snd_task, then it + * does need to be pinned. + * Returns '0' on success. */ -void xprt_transmit(struct rpc_task *task) +static int +xprt_request_transmit(struct rpc_rqst *req, struct rpc_task *snd_task) { - struct rpc_rqst *req = task->tk_rqstp; - struct rpc_xprt *xprt = req->rq_xprt; + struct rpc_xprt *xprt = req->rq_xprt; + struct rpc_task *task = req->rq_task; unsigned int connect_cookie; int is_retrans = RPC_WAS_SENT(task); int status; @@ -1132,22 +1137,25 @@ void xprt_transmit(struct rpc_task *task) dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); if (!req->rq_bytes_sent) { - if (xprt_request_data_received(task)) + if (xprt_request_data_received(task)) { + status = 0; goto out_dequeue; + } /* Verify that our message lies in the RPCSEC_GSS window */ if (rpcauth_xmit_need_reencode(task)) { - task->tk_status = -EBADMSG; + status = -EBADMSG; goto out_dequeue; } } connect_cookie = xprt->connect_cookie; - status = xprt->ops->send_request(req, task); + status = xprt->ops->send_request(req, snd_task); trace_xprt_transmit(xprt, req->rq_xid, status); - if (status != 0) { - task->tk_status = status; - return; - } + if (status != 0) + return status; + + if (is_retrans) + task->tk_client->cl_stats->rpcretrans++; if (is_retrans) task->tk_client->cl_stats->rpcretrans++; @@ -1168,6 +1176,54 @@ void xprt_transmit(struct rpc_task *task) req->rq_connect_cookie = connect_cookie; out_dequeue: xprt_request_dequeue_transmit(task); + rpc_wake_up_queued_task_set_status(&xprt->sending, task, status); + return status; +} + +/** + * xprt_transmit - send an RPC request on a transport + * @task: controlling RPC task + * + * Attempts to drain the transmit queue. On exit, either the transport + * signalled an error that needs to be handled before transmission can + * resume, or @task finished transmitting, and detected that it already + * received a reply. + */ +void +xprt_transmit(struct rpc_task *task) +{ + struct rpc_rqst *next, *req = task->tk_rqstp; + struct rpc_xprt *xprt = req->rq_xprt; + LIST_HEAD(head); + int status; + + task->tk_status = -EAGAIN; + spin_lock(&xprt->queue_lock); + /* Avoid livelock by moving the xmit_queue contents to a private list */ + list_splice_init(&xprt->xmit_queue, &head); + while (!list_empty(&head)) { + next = list_first_entry(&head, struct rpc_rqst, rq_xmit); + xprt_pin_rqst(next); + spin_unlock(&xprt->queue_lock); + status = xprt_request_transmit(next, task); + if (status == -EBADMSG && next != req) + status = 0; + cond_resched(); + spin_lock(&xprt->queue_lock); + xprt_unpin_rqst(next); + if (status == 0) { + if (!xprt_request_data_received(task) || + test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) + continue; + } else if (!test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) + rpc_wake_up_queued_task(&xprt->pending, task); + else + task->tk_status = status; + /* On early exit, splice back the list contents */ + list_splice(&head, &xprt->xmit_queue); + break; + } + spin_unlock(&xprt->queue_lock); } static void xprt_add_backlog(struct rpc_xprt *xprt, struct rpc_task *task)