Re: [PATCH] cifs: Limit the overall credit acquired

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



merged into cifs-2.6.git for-next

On Tue, Sep 20, 2016 at 7:37 AM, Ross Lagerwall
<ross.lagerwall@xxxxxxxxxx> wrote:
> The kernel client requests 2 credits for many operations even though
> they only use 1 credit (presumably to build up a buffer of credit).
> Some servers seem to give the client as much credit as is requested.  In
> this case, the amount of credit the client has continues increasing to
> the point where (server->credits * MAX_BUFFER_SIZE) overflows in
> smb2_wait_mtu_credits().
>
> Fix this by throttling the credit requests if an set limit is reached.
> For async requests where the credit charge may be > 1, request as much
> credit as what is charged.
> The limit is chosen somewhat arbitrarily. The Windows client
> defaults to 128 credits, the Windows server allows clients up to
> 512 credits, and the NetApp server does not limit clients at all.
> Choose a high enough value such that the client shouldn't limit
> performance.
>
> This behavior was seen with a NetApp filer (NetApp Release 9.0RC2).
>
> Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
> ---
>  fs/cifs/smb2glob.h | 10 ++++++++++
>  fs/cifs/smb2pdu.c  | 18 +++++++++++++++++-
>  2 files changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h
> index 0ffa180..0e1d788 100644
> --- a/fs/cifs/smb2glob.h
> +++ b/fs/cifs/smb2glob.h
> @@ -61,4 +61,14 @@
>  /* Maximum buffer size value we can send with 1 credit */
>  #define SMB2_MAX_BUFFER_SIZE 65536
>
> +/*
> + * Maximum number of credits to keep available.
> + * This value is chosen somewhat arbitrarily. The Windows client
> + * defaults to 128 credits, the Windows server allows clients up to
> + * 512 credits, and the NetApp server does not limit clients at all.
> + * Choose a high enough value such that the client shouldn't limit
> + * performance.
> + */
> +#define SMB2_MAX_CREDITS_AVAILABLE 1024
> +
>  #endif /* _SMB2_GLOB_H */
> diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
> index 29e06db..967a790 100644
> --- a/fs/cifs/smb2pdu.c
> +++ b/fs/cifs/smb2pdu.c
> @@ -100,7 +100,21 @@ smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ ,
>         hdr->ProtocolId = SMB2_PROTO_NUMBER;
>         hdr->StructureSize = cpu_to_le16(64);
>         hdr->Command = smb2_cmd;
> -       hdr->CreditRequest = cpu_to_le16(2); /* BB make this dynamic */
> +       if (tcon && tcon->ses && tcon->ses->server) {
> +               struct TCP_Server_Info *server = tcon->ses->server;
> +
> +               spin_lock(&server->req_lock);
> +               /* Request up to 2 credits but don't go over the limit. */
> +               if (server->credits >= SMB2_MAX_CREDITS_AVAILABLE)
> +                       hdr->CreditRequest = cpu_to_le16(0);
> +               else
> +                       hdr->CreditRequest = cpu_to_le16(
> +                               min_t(int, SMB2_MAX_CREDITS_AVAILABLE -
> +                                               server->credits, 2));
> +               spin_unlock(&server->req_lock);
> +       } else {
> +               hdr->CreditRequest = cpu_to_le16(2);
> +       }
>         hdr->ProcessId = cpu_to_le32((__u16)current->tgid);
>
>         if (!tcon)
> @@ -2057,6 +2071,7 @@ smb2_async_readv(struct cifs_readdata *rdata)
>         if (rdata->credits) {
>                 buf->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
>                                                 SMB2_MAX_BUFFER_SIZE));
> +               buf->CreditRequest = buf->CreditCharge;
>                 spin_lock(&server->req_lock);
>                 server->credits += rdata->credits -
>                                                 le16_to_cpu(buf->CreditCharge);
> @@ -2243,6 +2258,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
>         if (wdata->credits) {
>                 req->hdr.CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
>                                                     SMB2_MAX_BUFFER_SIZE));
> +               req->hdr.CreditRequest = req->hdr.CreditCharge;
>                 spin_lock(&server->req_lock);
>                 server->credits += wdata->credits -
>                                         le16_to_cpu(req->hdr.CreditCharge);
> --
> 2.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Thanks,

Steve
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux