From patchwork Wed Jan 23 21:10:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 10777905 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 B1FEE1515 for ; Wed, 23 Jan 2019 21:11:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A1BC42D7AB for ; Wed, 23 Jan 2019 21:11:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 964D82D8B0; Wed, 23 Jan 2019 21:11:12 +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 8E7CE2D7B1 for ; Wed, 23 Jan 2019 21:11:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726994AbfAWVLL (ORCPT ); Wed, 23 Jan 2019 16:11:11 -0500 Received: from mail-pf1-f196.google.com ([209.85.210.196]:35034 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726991AbfAWVLL (ORCPT ); Wed, 23 Jan 2019 16:11:11 -0500 Received: by mail-pf1-f196.google.com with SMTP id z9so1811093pfi.2 for ; Wed, 23 Jan 2019 13:11:10 -0800 (PST) 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; bh=8nQ19dxyE8Lfj5qY8xj3cn9tpBoyPsRQCTeIurIhNrU=; b=n3eKDO2HHOjsDztD0vo6C4i44uXEqPAuBhhx6/2FcZUuDMW1FR5U2B+bV2d2dG7O9y BEAC7MhS37S0222tIEllkcO6ms7uOc2tFoJ85hYdVfKcNL+8gApLAfgoA6gFZjUiqGVO qnqxqSTlIZqmo4HQSr4l2CETVw7btUDinYPMwfU0bwmIMobwDsmgSa8kPxPLHvNGEFgA PwCKdswieVOJCE67kTCO/I/L5xj9FdYPhX99fpoEEvebcxG046S1v3E0PYCWVduTYGKM CVjdSgCpW8UQk0jlQaLGLeklOyt4VJKMQoJnzSo+NTZfXct7CUfqCiTFGY+BdT2HkNHQ xvgQ== 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; bh=8nQ19dxyE8Lfj5qY8xj3cn9tpBoyPsRQCTeIurIhNrU=; b=ZgCCmupV2nMciou1e8zXM9axKPK2dljSHWhoBwWB63LR1vvVwIIfpvjgU6cxbwDtKY R7knC1sDqH1iyysRJAQr6/quY7/69oj8in3IXkeotHwJ4VX1e1anALsmGnnWa9etCS65 HuKti/Dm/B6kNF4hh4paB3RWNne9ynhhWyVZjyHYVbCaLZUvjdbQom13P465m2uNer2B LQufhqMu7uJoVm9xcnWyA22x8Al4syl1ZblkqwqbkjR8RFI4issVInO5eMeu9CWc+x12 ZJLbiJThckp+VNz5A7Lbviwzk/M9NOjxN3KIXSWSgurT/9g5fdtYv2sXUU3iAO2U4gNZ ZfjA== X-Gm-Message-State: AJcUukdAL8kspbdvyh5wU27OLnaeHNRYCMKiDmN1972ZLB3Jb7sGURlp cAvb8gx4ccAsriIlq+Zt21r8Gug= X-Google-Smtp-Source: ALg8bN6aAEG3oX/p8ZKOFHnu2+StqhVk66MYDnEgVtlIwvTu3Yq3Yv6RdFbGvlkj4uFy7/l3ULCRjA== X-Received: by 2002:a63:4948:: with SMTP id y8mr3484155pgk.32.1548277869119; Wed, 23 Jan 2019 13:11:09 -0800 (PST) Received: from ubuntu-vm.corp.microsoft.com ([2001:4898:80e8:f:a17f:4e9f:6b7c:507d]) by smtp.gmail.com with ESMTPSA id n73sm28063714pfj.148.2019.01.23.13.11.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 23 Jan 2019 13:11:08 -0800 (PST) From: Pavel Shilovsky X-Google-Original-From: Pavel Shilovsky To: linux-cifs@vger.kernel.org, Steve French , Ronnie Sahlberg Subject: [PATCH 13/15] CIFS: Respect reconnect in non-MTU credits calculations Date: Wed, 23 Jan 2019 13:10:43 -0800 Message-Id: <1548277845-6746-14-git-send-email-pshilov@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1548277845-6746-1-git-send-email-pshilov@microsoft.com> References: <1548277845-6746-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 Every time after a session reconnect we don't need to account for credits obtained in previous sessions. Make use of the recently added cifs_credits structure to properly calculate credits for non-MTU requests the same way we did for MTU ones. Signed-off-by: Pavel Shilovsky --- fs/cifs/cifsglob.h | 6 ++---- fs/cifs/cifssmb.c | 9 ++++++--- fs/cifs/smb2pdu.c | 33 +++++++++++++++++++------------- fs/cifs/transport.c | 54 +++++++++++++++++++++++++++++++++++------------------ 4 files changed, 64 insertions(+), 38 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 60a657e..24ecde1 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -738,12 +738,10 @@ has_credits(struct TCP_Server_Info *server, int *credits) } static inline void -add_credits(struct TCP_Server_Info *server, const unsigned int add, +add_credits(struct TCP_Server_Info *server, const struct cifs_credits *credits, const int optype) { - struct cifs_credits credits = { .value = add, .instance = 0 }; - - server->ops->add_credits(server, &credits, optype); + server->ops->add_credits(server, credits, optype); } static inline void diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c8792d2..5b54882 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -813,9 +813,10 @@ static void cifs_echo_callback(struct mid_q_entry *mid) { struct TCP_Server_Info *server = mid->callback_data; + struct cifs_credits credits = { .value = 1, .instance = 0 }; DeleteMidQEntry(mid); - add_credits(server, 1, CIFS_ECHO_OP); + add_credits(server, &credits, CIFS_ECHO_OP); } int @@ -1705,6 +1706,7 @@ cifs_readv_callback(struct mid_q_entry *mid) .rq_npages = rdata->nr_pages, .rq_pagesz = rdata->pagesz, .rq_tailsz = rdata->tailsz }; + struct cifs_credits credits = { .value = 1, .instance = 0 }; cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n", __func__, mid->mid, mid->mid_state, rdata->result, @@ -1742,7 +1744,7 @@ cifs_readv_callback(struct mid_q_entry *mid) queue_work(cifsiod_wq, &rdata->work); DeleteMidQEntry(mid); - add_credits(server, 1, 0); + add_credits(server, &credits, 0); } /* cifs_async_readv - send an async write, and set up mid to handle result */ @@ -2218,6 +2220,7 @@ cifs_writev_callback(struct mid_q_entry *mid) struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); unsigned int written; WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; + struct cifs_credits credits = { .value = 1, .instance = 0 }; switch (mid->mid_state) { case MID_RESPONSE_RECEIVED: @@ -2253,7 +2256,7 @@ cifs_writev_callback(struct mid_q_entry *mid) queue_work(cifsiod_wq, &wdata->work); DeleteMidQEntry(mid); - add_credits(tcon->ses->server, 1, 0); + add_credits(tcon->ses->server, &credits, 0); } /* cifs_async_writev - send an async write, and set up mid to handle result */ diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 401f3a4..2a2ebaa 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2893,14 +2893,16 @@ smb2_echo_callback(struct mid_q_entry *mid) { struct TCP_Server_Info *server = mid->callback_data; struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)mid->resp_buf; - unsigned int credits_received = 0; + struct cifs_credits credits = { .value = 0, .instance = 0 }; if (mid->mid_state == MID_RESPONSE_RECEIVED - || mid->mid_state == MID_RESPONSE_MALFORMED) - credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest); + || mid->mid_state == MID_RESPONSE_MALFORMED) { + credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest); + credits.instance = server->reconnect_instance; + } DeleteMidQEntry(mid); - add_credits(server, credits_received, CIFS_ECHO_OP); + add_credits(server, &credits, CIFS_ECHO_OP); } void smb2_reconnect_server(struct work_struct *work) @@ -3153,7 +3155,7 @@ smb2_readv_callback(struct mid_q_entry *mid) struct TCP_Server_Info *server = tcon->ses->server; struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)rdata->iov[0].iov_base; - unsigned int credits_received = 0; + struct cifs_credits credits = { .value = 0, .instance = 0 }; struct smb_rqst rqst = { .rq_iov = rdata->iov, .rq_nvec = 2, .rq_pages = rdata->pages, @@ -3168,7 +3170,8 @@ smb2_readv_callback(struct mid_q_entry *mid) switch (mid->mid_state) { case MID_RESPONSE_RECEIVED: - credits_received = le16_to_cpu(shdr->CreditRequest); + credits.value = le16_to_cpu(shdr->CreditRequest); + credits.instance = server->reconnect_instance; /* result already set, check signature */ if (server->sign && !mid->decrypted) { int rc; @@ -3193,7 +3196,8 @@ smb2_readv_callback(struct mid_q_entry *mid) cifs_stats_bytes_read(tcon, rdata->got_bytes); break; case MID_RESPONSE_MALFORMED: - credits_received = le16_to_cpu(shdr->CreditRequest); + credits.value = le16_to_cpu(shdr->CreditRequest); + credits.instance = server->reconnect_instance; /* fall through */ default: rdata->result = -EIO; @@ -3214,7 +3218,7 @@ smb2_readv_callback(struct mid_q_entry *mid) queue_work(cifsiod_wq, &rdata->work); DeleteMidQEntry(mid); - add_credits(server, credits_received, 0); + add_credits(server, &credits, 0); } /* smb2_async_readv - send an async read, and set up mid to handle result */ @@ -3386,14 +3390,16 @@ smb2_writev_callback(struct mid_q_entry *mid) { struct cifs_writedata *wdata = mid->callback_data; struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); + struct TCP_Server_Info *server = tcon->ses->server; unsigned int written; struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf; - unsigned int credits_received = 0; + struct cifs_credits credits = { .value = 0, .instance = 0 }; switch (mid->mid_state) { case MID_RESPONSE_RECEIVED: - credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest); - wdata->result = smb2_check_receive(mid, tcon->ses->server, 0); + credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest); + credits.instance = server->reconnect_instance; + wdata->result = smb2_check_receive(mid, server, 0); if (wdata->result != 0) break; @@ -3417,7 +3423,8 @@ smb2_writev_callback(struct mid_q_entry *mid) wdata->result = -EAGAIN; break; case MID_RESPONSE_MALFORMED: - credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest); + credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest); + credits.instance = server->reconnect_instance; /* fall through */ default: wdata->result = -EIO; @@ -3441,7 +3448,7 @@ smb2_writev_callback(struct mid_q_entry *mid) queue_work(cifsiod_wq, &wdata->work); DeleteMidQEntry(mid); - add_credits(tcon->ses->server, credits_received, 0); + add_credits(server, &credits, 0); } /* smb2_async_writev - send an async write, and set up mid to handle result */ diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index f364a08..8b512a9 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -478,15 +478,18 @@ smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, static int wait_for_free_credits(struct TCP_Server_Info *server, const int timeout, - int *credits) + int *credits, unsigned int *instance) { int rc; + *instance = 0; + spin_lock(&server->req_lock); if (timeout == CIFS_ASYNC_OP) { /* oplock breaks must not be held up */ server->in_flight++; *credits -= 1; + *instance = server->reconnect_instance; spin_unlock(&server->req_lock); return 0; } @@ -516,6 +519,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int timeout, if (timeout != CIFS_BLOCKING_OP) { *credits -= 1; server->in_flight++; + *instance = server->reconnect_instance; } spin_unlock(&server->req_lock); break; @@ -526,7 +530,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int timeout, static int wait_for_free_request(struct TCP_Server_Info *server, const int timeout, - const int optype) + const int optype, unsigned int *instance) { int *val; @@ -534,7 +538,7 @@ wait_for_free_request(struct TCP_Server_Info *server, const int timeout, /* Since an echo is already inflight, no need to wait to send another */ if (*val <= 0 && optype == CIFS_ECHO_OP) return -EAGAIN; - return wait_for_free_credits(server, timeout, val); + return wait_for_free_credits(server, timeout, val, instance); } int @@ -635,15 +639,17 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, int rc, timeout, optype; struct mid_q_entry *mid; struct cifs_credits credits = { .value = 0, .instance = 0 }; + unsigned int instance; timeout = flags & CIFS_TIMEOUT_MASK; optype = flags & CIFS_OP_MASK; if ((flags & CIFS_HAS_CREDITS) == 0) { - rc = wait_for_free_request(server, timeout, optype); + rc = wait_for_free_request(server, timeout, optype, &instance); if (rc) return rc; credits.value = 1; + credits.instance = instance; } mutex_lock(&server->srv_mutex); @@ -814,8 +820,12 @@ static void cifs_compound_callback(struct mid_q_entry *mid) { struct TCP_Server_Info *server = mid->server; + struct cifs_credits credits; + + credits.value = server->ops->get_credits(mid); + credits.instance = server->reconnect_instance; - add_credits(server, server->ops->get_credits(mid), mid->optype); + add_credits(server, &credits, mid->optype); } static void @@ -841,7 +851,10 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, int timeout, optype; struct mid_q_entry *midQ[MAX_COMPOUND]; bool cancelled_mid[MAX_COMPOUND] = {false}; - unsigned int credits[MAX_COMPOUND] = {0}; + struct cifs_credits credits[MAX_COMPOUND] = { + { .value = 0, .instance = 0 } + }; + unsigned int instance; char *buf; timeout = flags & CIFS_TIMEOUT_MASK; @@ -867,7 +880,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, * needed anyway. */ for (i = 0; i < num_rqst; i++) { - rc = wait_for_free_request(ses->server, timeout, optype); + rc = wait_for_free_request(ses->server, timeout, optype, + &instance); if (rc) { /* * We haven't sent an SMB packet to the server yet but @@ -879,10 +893,11 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, * requests correctly. */ for (j = 0; j < i; j++) - add_credits(ses->server, 1, optype); + add_credits(ses->server, &credits[j], optype); return rc; } - credits[i] = 1; + credits[i].value = 1; + credits[i].instance = instance; } /* @@ -902,7 +917,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, /* Update # of requests on wire to server */ for (j = 0; j < num_rqst; j++) - add_credits(ses->server, credits[j], optype); + add_credits(ses->server, &credits[j], optype); return PTR_ERR(midQ[i]); } @@ -933,7 +948,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, if (rc < 0) { /* Sending failed for some reason - return credits back */ for (i = 0; i < num_rqst; i++) - add_credits(ses->server, credits[i], optype); + add_credits(ses->server, &credits[i], optype); goto out; } @@ -970,7 +985,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, midQ[i]->mid_flags |= MID_WAIT_CANCELLED; midQ[i]->callback = cifs_cancelled_callback; cancelled_mid[i] = true; - credits[i] = 0; + credits[i].value = 0; } spin_unlock(&GlobalMid_Lock); } @@ -1096,6 +1111,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, unsigned int len = be32_to_cpu(in_buf->smb_buf_length); struct kvec iov = { .iov_base = in_buf, .iov_len = len }; struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; + struct cifs_credits credits = { .value = 1, .instance = 0 }; if (ses == NULL) { cifs_dbg(VFS, "Null smb session\n"); @@ -1119,7 +1135,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, return -EIO; } - rc = wait_for_free_request(ses->server, timeout, 0); + rc = wait_for_free_request(ses->server, timeout, 0, &credits.instance); if (rc) return rc; @@ -1133,7 +1149,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, if (rc) { mutex_unlock(&ses->server->srv_mutex); /* Update # of requests on wire to server */ - add_credits(ses->server, 1, 0); + add_credits(ses->server, &credits, 0); return rc; } @@ -1169,7 +1185,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, /* no longer considered to be "in-flight" */ midQ->callback = DeleteMidQEntry; spin_unlock(&GlobalMid_Lock); - add_credits(ses->server, 1, 0); + add_credits(ses->server, &credits, 0); return rc; } spin_unlock(&GlobalMid_Lock); @@ -1177,7 +1193,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, rc = cifs_sync_mid_result(midQ, ses->server); if (rc != 0) { - add_credits(ses->server, 1, 0); + add_credits(ses->server, &credits, 0); return rc; } @@ -1193,7 +1209,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, rc = cifs_check_receive(midQ, ses->server, 0); out: cifs_delete_mid(midQ); - add_credits(ses->server, 1, 0); + add_credits(ses->server, &credits, 0); return rc; } @@ -1235,6 +1251,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, unsigned int len = be32_to_cpu(in_buf->smb_buf_length); struct kvec iov = { .iov_base = in_buf, .iov_len = len }; struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; + unsigned int instance; if (tcon == NULL || tcon->ses == NULL) { cifs_dbg(VFS, "Null smb session\n"); @@ -1260,7 +1277,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, return -EIO; } - rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0); + rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0, + &instance); if (rc) return rc;