]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
smb3: enable offload of decryption of large reads via mount option
authorSteve French <stfrench@microsoft.com>
Mon, 9 Sep 2019 04:22:02 +0000 (23:22 -0500)
committerSteve French <stfrench@microsoft.com>
Mon, 16 Sep 2019 16:43:38 +0000 (11:43 -0500)
Disable offload of the decryption of encrypted read responses
by default (equivalent to setting this new mount option "esize=0").

Allow setting the minimum encrypted read response size that we
will choose to offload to a worker thread - it is now configurable
via on a new mount option "esize="

Depending on which encryption mechanism (GCM vs. CCM) and
the number of reads that will be issued in parallel and the
performance of the network and CPU on the client, it may make
sense to enable this since it can provide substantial benefit when
multiple large reads are in flight at the same time.

Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/smb2ops.c

index b0ea332af35ccfc04fd886c473db38baf7605436..ebf85a5d95e4e57d308fa6259ee108dc46a1f53d 100644 (file)
@@ -559,6 +559,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
        seq_printf(s, ",rsize=%u", cifs_sb->rsize);
        seq_printf(s, ",wsize=%u", cifs_sb->wsize);
        seq_printf(s, ",bsize=%u", cifs_sb->bsize);
+       if (tcon->ses->server->min_offload)
+               seq_printf(s, ",esize=%u", tcon->ses->server->min_offload);
        seq_printf(s, ",echo_interval=%lu",
                        tcon->ses->server->echo_interval / HZ);
 
index d66106ac031af605913f97ccad3ff7cae59d14d2..6987fbc5a24a40c9993a278bfe30b91a08db5ac1 100644 (file)
@@ -592,6 +592,7 @@ struct smb_vol {
        unsigned int bsize;
        unsigned int rsize;
        unsigned int wsize;
+       unsigned int min_offload;
        bool sockopt_tcp_nodelay:1;
        unsigned long actimeo; /* attribute cache timeout (jiffies) */
        struct smb_version_operations *ops;
@@ -745,6 +746,7 @@ struct TCP_Server_Info {
 #endif /* STATS2 */
        unsigned int    max_read;
        unsigned int    max_write;
+       unsigned int    min_offload;
        __le16  compress_algorithm;
        __le16  cipher_type;
         /* save initital negprot hash */
index 17882cede197a0f9dc776637cb1f109205295fbe..e70112d67b0e7459a9c16a409fe4020015628172 100644 (file)
@@ -103,6 +103,7 @@ enum {
        Opt_backupuid, Opt_backupgid, Opt_uid,
        Opt_cruid, Opt_gid, Opt_file_mode,
        Opt_dirmode, Opt_port,
+       Opt_min_enc_offload,
        Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo,
        Opt_echo_interval, Opt_max_credits, Opt_handletimeout,
        Opt_snapshot,
@@ -207,6 +208,7 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_dirmode, "dirmode=%s" },
        { Opt_dirmode, "dir_mode=%s" },
        { Opt_port, "port=%s" },
+       { Opt_min_enc_offload, "esize=%s" },
        { Opt_blocksize, "bsize=%s" },
        { Opt_rsize, "rsize=%s" },
        { Opt_wsize, "wsize=%s" },
@@ -2016,6 +2018,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        }
                        port = (unsigned short)option;
                        break;
+               case Opt_min_enc_offload:
+                       if (get_option_ul(args, &option)) {
+                               cifs_dbg(VFS, "Invalid minimum encrypted read offload size (esize)\n");
+                               goto cifs_parse_mount_err;
+                       }
+                       vol->min_offload = option;
+                       break;
                case Opt_blocksize:
                        if (get_option_ul(args, &option)) {
                                cifs_dbg(VFS, "%s: Invalid blocksize value\n",
@@ -2616,6 +2625,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
        if (server->ignore_signature != vol->ignore_signature)
                return 0;
 
+       if (server->min_offload != vol->min_offload)
+               return 0;
+
        return 1;
 }
 
@@ -2790,6 +2802,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
                module_put(THIS_MODULE);
                goto out_err_crypto_release;
        }
+       tcp_ses->min_offload = volume_info->min_offload;
        tcp_ses->tcpStatus = CifsNeedNegotiate;
 
        tcp_ses->nr_targets = 1;
index c742844849472bcab9f114028d840e48495f9dd3..1cfb8d51813272cce8ef29c2a9f785cb682dc480 100644 (file)
@@ -4121,8 +4121,8 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
         * use more cores decrypting which can be expensive
         */
 
-       /* TODO: make the size limit to enable decrypt offload configurable */
-       if (server->pdu_size > (512 * 1024)) {
+       if ((server->min_offload) &&
+           (server->pdu_size >= server->min_offload)) {
                dw = kmalloc(sizeof(struct smb2_decrypt_work), GFP_KERNEL);
                if (dw == NULL)
                        goto non_offloaded_decrypt;