summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <stfrench@microsoft.com>2019-09-09 00:22:02 -0400
committerSteve French <stfrench@microsoft.com>2019-09-16 12:43:38 -0400
commit563317ec3083f7e126d7e30821ff8505ac338ee5 (patch)
tree1861eea90a780a694310c2d6a1551400333cdee1
parent35cf94a397280b9e27576ac1480f631bdd3e7b70 (diff)
smb3: enable offload of decryption of large reads via mount option
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>
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/connect.c13
-rw-r--r--fs/cifs/smb2ops.c4
4 files changed, 19 insertions, 2 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index b0ea332af35c..ebf85a5d95e4 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -559,6 +559,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
559 seq_printf(s, ",rsize=%u", cifs_sb->rsize); 559 seq_printf(s, ",rsize=%u", cifs_sb->rsize);
560 seq_printf(s, ",wsize=%u", cifs_sb->wsize); 560 seq_printf(s, ",wsize=%u", cifs_sb->wsize);
561 seq_printf(s, ",bsize=%u", cifs_sb->bsize); 561 seq_printf(s, ",bsize=%u", cifs_sb->bsize);
562 if (tcon->ses->server->min_offload)
563 seq_printf(s, ",esize=%u", tcon->ses->server->min_offload);
562 seq_printf(s, ",echo_interval=%lu", 564 seq_printf(s, ",echo_interval=%lu",
563 tcon->ses->server->echo_interval / HZ); 565 tcon->ses->server->echo_interval / HZ);
564 566
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index d66106ac031a..6987fbc5a24a 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -592,6 +592,7 @@ struct smb_vol {
592 unsigned int bsize; 592 unsigned int bsize;
593 unsigned int rsize; 593 unsigned int rsize;
594 unsigned int wsize; 594 unsigned int wsize;
595 unsigned int min_offload;
595 bool sockopt_tcp_nodelay:1; 596 bool sockopt_tcp_nodelay:1;
596 unsigned long actimeo; /* attribute cache timeout (jiffies) */ 597 unsigned long actimeo; /* attribute cache timeout (jiffies) */
597 struct smb_version_operations *ops; 598 struct smb_version_operations *ops;
@@ -745,6 +746,7 @@ struct TCP_Server_Info {
745#endif /* STATS2 */ 746#endif /* STATS2 */
746 unsigned int max_read; 747 unsigned int max_read;
747 unsigned int max_write; 748 unsigned int max_write;
749 unsigned int min_offload;
748 __le16 compress_algorithm; 750 __le16 compress_algorithm;
749 __le16 cipher_type; 751 __le16 cipher_type;
750 /* save initital negprot hash */ 752 /* save initital negprot hash */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 17882cede197..e70112d67b0e 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -103,6 +103,7 @@ enum {
103 Opt_backupuid, Opt_backupgid, Opt_uid, 103 Opt_backupuid, Opt_backupgid, Opt_uid,
104 Opt_cruid, Opt_gid, Opt_file_mode, 104 Opt_cruid, Opt_gid, Opt_file_mode,
105 Opt_dirmode, Opt_port, 105 Opt_dirmode, Opt_port,
106 Opt_min_enc_offload,
106 Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo, 107 Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo,
107 Opt_echo_interval, Opt_max_credits, Opt_handletimeout, 108 Opt_echo_interval, Opt_max_credits, Opt_handletimeout,
108 Opt_snapshot, 109 Opt_snapshot,
@@ -207,6 +208,7 @@ static const match_table_t cifs_mount_option_tokens = {
207 { Opt_dirmode, "dirmode=%s" }, 208 { Opt_dirmode, "dirmode=%s" },
208 { Opt_dirmode, "dir_mode=%s" }, 209 { Opt_dirmode, "dir_mode=%s" },
209 { Opt_port, "port=%s" }, 210 { Opt_port, "port=%s" },
211 { Opt_min_enc_offload, "esize=%s" },
210 { Opt_blocksize, "bsize=%s" }, 212 { Opt_blocksize, "bsize=%s" },
211 { Opt_rsize, "rsize=%s" }, 213 { Opt_rsize, "rsize=%s" },
212 { Opt_wsize, "wsize=%s" }, 214 { Opt_wsize, "wsize=%s" },
@@ -2016,6 +2018,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
2016 } 2018 }
2017 port = (unsigned short)option; 2019 port = (unsigned short)option;
2018 break; 2020 break;
2021 case Opt_min_enc_offload:
2022 if (get_option_ul(args, &option)) {
2023 cifs_dbg(VFS, "Invalid minimum encrypted read offload size (esize)\n");
2024 goto cifs_parse_mount_err;
2025 }
2026 vol->min_offload = option;
2027 break;
2019 case Opt_blocksize: 2028 case Opt_blocksize:
2020 if (get_option_ul(args, &option)) { 2029 if (get_option_ul(args, &option)) {
2021 cifs_dbg(VFS, "%s: Invalid blocksize value\n", 2030 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)
2616 if (server->ignore_signature != vol->ignore_signature) 2625 if (server->ignore_signature != vol->ignore_signature)
2617 return 0; 2626 return 0;
2618 2627
2628 if (server->min_offload != vol->min_offload)
2629 return 0;
2630
2619 return 1; 2631 return 1;
2620} 2632}
2621 2633
@@ -2790,6 +2802,7 @@ smbd_connected:
2790 module_put(THIS_MODULE); 2802 module_put(THIS_MODULE);
2791 goto out_err_crypto_release; 2803 goto out_err_crypto_release;
2792 } 2804 }
2805 tcp_ses->min_offload = volume_info->min_offload;
2793 tcp_ses->tcpStatus = CifsNeedNegotiate; 2806 tcp_ses->tcpStatus = CifsNeedNegotiate;
2794 2807
2795 tcp_ses->nr_targets = 1; 2808 tcp_ses->nr_targets = 1;
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index c74284484947..1cfb8d518132 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -4121,8 +4121,8 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
4121 * use more cores decrypting which can be expensive 4121 * use more cores decrypting which can be expensive
4122 */ 4122 */
4123 4123
4124 /* TODO: make the size limit to enable decrypt offload configurable */ 4124 if ((server->min_offload) &&
4125 if (server->pdu_size > (512 * 1024)) { 4125 (server->pdu_size >= server->min_offload)) {
4126 dw = kmalloc(sizeof(struct smb2_decrypt_work), GFP_KERNEL); 4126 dw = kmalloc(sizeof(struct smb2_decrypt_work), GFP_KERNEL);
4127 if (dw == NULL) 4127 if (dw == NULL)
4128 goto non_offloaded_decrypt; 4128 goto non_offloaded_decrypt;