From patchwork Thu Jan 10 22:24:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 10757011 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 7E00E1399 for ; Thu, 10 Jan 2019 22:25:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6B74B29B6B for ; Thu, 10 Jan 2019 22:25:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5FC8329B94; Thu, 10 Jan 2019 22:25:13 +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 E496D29B6B for ; Thu, 10 Jan 2019 22:25:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728991AbfAJWZM (ORCPT ); Thu, 10 Jan 2019 17:25:12 -0500 Received: from mail-pf1-f194.google.com ([209.85.210.194]:43357 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728800AbfAJWZM (ORCPT ); Thu, 10 Jan 2019 17:25:12 -0500 Received: by mail-pf1-f194.google.com with SMTP id w73so5940547pfk.10 for ; Thu, 10 Jan 2019 14:25:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ctm6dsa1PPQY/Zp33MkcTFiyzDPnCNzcx4cWaEFRmsc=; b=pjZBDZIPeOhygE29qpER8UqwQqg517DEenfckKhuuLbyL1SN4kpoIdtkf9F8qw3PRu /CGbhBvpNY58pGkLdP+m0kHBaMg6Z22jbONrBzAFpo2r4lXNekeA78H4kB7wWl6SiWSO ZltFFRcA4hcqMy7Oy8NWWMp4fKuZ2gVU235Go2CtOWuKu4mgJm2o5Cm8GG/DjrZbWOLK cZHrxEZKjE9qTEECbHHJxY/G/RUgg8BEGBSaY9GtcjLw0++fM2wKEsUbVOScoytmk3HT bb6diH8idW/zNmTwcXerYyIUDRkALH8VuvmysMkQyZLJ5Ye0Q0tYGEUAWK2m/5YxhFY/ uXfw== 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; bh=ctm6dsa1PPQY/Zp33MkcTFiyzDPnCNzcx4cWaEFRmsc=; b=ggza5hCFz2f+jolfOClV4B4x7pBb4aBtbION7/VuHBlU+tgZI+eJ+6Ni+E+MZ0oXZ/ noGvfMhbzunCLltIBz4nHWmAStc6NNlr6DedobjvdgKmI/nrOf23umugDImaNyfT419E tmrKysJOkXAZAvWJlkIQ9gYOhdrh+NyniOLZe+cwyVvkZ7XXtgzzQ3KDxYM3RVEa2ffR 9DHDQZBw+BvSufvny3ipCOadoItlkpq0QZ8OUX6nAY3/6+OLdoI5iSttBPj15rm4KTHO OjRvzM4CdqC3uFeFROaRpNH56ghUYrjhJ+yLxEa5YB7BsRCJf173mf1DdB9+ssBzo1XA zerg== X-Gm-Message-State: AJcUukdqySR3IPkwcSk7DxeLZIe0nhQxS0P90r9lMOGbX8yaC/EbFhQr OMu/NCleQRlG6z976JOWzYB7T4U= X-Google-Smtp-Source: ALg8bN7tSdh/9Xu+A+5XevUXAjWHQ+cwf6pLKRgO1AmEa68CFvHmrhyiZssp+398AIaMq1mf9v9Y9w== X-Received: by 2002:a63:a41:: with SMTP id z1mr11001425pgk.117.1547159110872; Thu, 10 Jan 2019 14:25:10 -0800 (PST) Received: from ubuntu-vm.corp.microsoft.com ([2001:4898:80e8:3:a18b:4e9f:6b7c:507d]) by smtp.gmail.com with ESMTPSA id z127sm118006755pfb.80.2019.01.10.14.25.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 10 Jan 2019 14:25:09 -0800 (PST) From: Pavel Shilovsky X-Google-Original-From: Pavel Shilovsky To: linux-cifs@vger.kernel.org Cc: Steve French , Ronnie Sahlberg Subject: [PATCH 3/7] CIFS: Fix credit computation for compounded requests Date: Thu, 10 Jan 2019 14:24:54 -0800 Message-Id: <1547159098-19011-4-git-send-email-pshilov@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1547159098-19011-1-git-send-email-pshilov@microsoft.com> References: <1547159098-19011-1-git-send-email-pshilov@microsoft.com> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In SMB3 protocol every part of the compound chain consumes credits individually, so we need to call wait_for_free_credits() for each of the PDUs in the chain. If an operation is interrupted, we must ensure we return all credits taken from the server structure back. Cc: Signed-off-by: Pavel Shilovsky --- fs/cifs/transport.c | 59 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 8e75d68..e047f06 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -795,7 +795,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, int i, j, rc = 0; int timeout, optype; struct mid_q_entry *midQ[MAX_COMPOUND]; - unsigned int credits = 0; + bool cancelled_mid[MAX_COMPOUND] = {false}; + unsigned int credits[MAX_COMPOUND] = {0}; char *buf; timeout = flags & CIFS_TIMEOUT_MASK; @@ -813,13 +814,31 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, return -ENOENT; /* - * Ensure that we do not send more than 50 overlapping requests - * to the same server. We may make this configurable later or - * use ses->maxReq. + * Ensure we obtain 1 credit per request in the compound chain. + * It can be optimized further by waiting for all the credits + * at once but this can wait long enough if we don't have enough + * credits due to some heavy operations in progress or the server + * not granting us much, so a fallback to the current approach is + * needed anyway. */ - rc = wait_for_free_request(ses->server, timeout, optype); - if (rc) - return rc; + for (i = 0; i < num_rqst; i++) { + rc = wait_for_free_request(ses->server, timeout, optype); + if (rc) { + /* + * We haven't sent an SMB packet to the server yet but + * we already obtained credits for i requests in the + * compound chain - need to return those credits back + * for future use. Note that we need to call add_credits + * multiple times to match the way we obtained credits + * in the first place and to account for in flight + * requests correctly. + */ + for (j = 0; j < i; j++) + add_credits(ses->server, 1, optype); + return rc; + } + credits[i] = 1; + } /* * Make sure that we sign in the same order that we send on this socket @@ -835,8 +854,10 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, for (j = 0; j < i; j++) cifs_delete_mid(midQ[j]); mutex_unlock(&ses->server->srv_mutex); + /* Update # of requests on wire to server */ - add_credits(ses->server, 1, optype); + for (j = 0; j < num_rqst; j++) + add_credits(ses->server, credits[j], optype); return PTR_ERR(midQ[i]); } @@ -883,17 +904,16 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { midQ[i]->mid_flags |= MID_WAIT_CANCELLED; midQ[i]->callback = DeleteMidQEntry; - spin_unlock(&GlobalMid_Lock); - add_credits(ses->server, 1, optype); - return rc; + cancelled_mid[i] = true; } spin_unlock(&GlobalMid_Lock); } } for (i = 0; i < num_rqst; i++) - if (midQ[i]->resp_buf) - credits += ses->server->ops->get_credits(midQ[i]); + if (!cancelled_mid[i] && midQ[i]->resp_buf + && (midQ[i]->mid_state == MID_RESPONSE_RECEIVED)) + credits[i] = ses->server->ops->get_credits(midQ[i]); for (i = 0; i < num_rqst; i++) { if (rc < 0) @@ -901,8 +921,9 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, rc = cifs_sync_mid_result(midQ[i], ses->server); if (rc != 0) { - add_credits(ses->server, credits, optype); - return rc; + /* mark this mid as cancelled to not free it below */ + cancelled_mid[i] = true; + goto out; } if (!midQ[i]->resp_buf || @@ -949,9 +970,11 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, * This is prevented above by using a noop callback that will not * wake this thread except for the very last PDU. */ - for (i = 0; i < num_rqst; i++) - cifs_delete_mid(midQ[i]); - add_credits(ses->server, credits, optype); + for (i = 0; i < num_rqst; i++) { + if (!cancelled_mid[i]) + cifs_delete_mid(midQ[i]); + add_credits(ses->server, credits[i], optype); + } return rc; }