Commit 563317ec authored by Steve French's avatar Steve French

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: default avatarSteve French <stfrench@microsoft.com>
Signed-off-by: default avatarRonnie Sahlberg <lsahlber@redhat.com>
parent 35cf94a3
...@@ -559,6 +559,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) ...@@ -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, ",rsize=%u", cifs_sb->rsize);
seq_printf(s, ",wsize=%u", cifs_sb->wsize); seq_printf(s, ",wsize=%u", cifs_sb->wsize);
seq_printf(s, ",bsize=%u", cifs_sb->bsize); 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", seq_printf(s, ",echo_interval=%lu",
tcon->ses->server->echo_interval / HZ); tcon->ses->server->echo_interval / HZ);
......
...@@ -592,6 +592,7 @@ struct smb_vol { ...@@ -592,6 +592,7 @@ struct smb_vol {
unsigned int bsize; unsigned int bsize;
unsigned int rsize; unsigned int rsize;
unsigned int wsize; unsigned int wsize;
unsigned int min_offload;
bool sockopt_tcp_nodelay:1; bool sockopt_tcp_nodelay:1;
unsigned long actimeo; /* attribute cache timeout (jiffies) */ unsigned long actimeo; /* attribute cache timeout (jiffies) */
struct smb_version_operations *ops; struct smb_version_operations *ops;
...@@ -745,6 +746,7 @@ struct TCP_Server_Info { ...@@ -745,6 +746,7 @@ struct TCP_Server_Info {
#endif /* STATS2 */ #endif /* STATS2 */
unsigned int max_read; unsigned int max_read;
unsigned int max_write; unsigned int max_write;
unsigned int min_offload;
__le16 compress_algorithm; __le16 compress_algorithm;
__le16 cipher_type; __le16 cipher_type;
/* save initital negprot hash */ /* save initital negprot hash */
......
...@@ -103,6 +103,7 @@ enum { ...@@ -103,6 +103,7 @@ enum {
Opt_backupuid, Opt_backupgid, Opt_uid, Opt_backupuid, Opt_backupgid, Opt_uid,
Opt_cruid, Opt_gid, Opt_file_mode, Opt_cruid, Opt_gid, Opt_file_mode,
Opt_dirmode, Opt_port, Opt_dirmode, Opt_port,
Opt_min_enc_offload,
Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo, Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo,
Opt_echo_interval, Opt_max_credits, Opt_handletimeout, Opt_echo_interval, Opt_max_credits, Opt_handletimeout,
Opt_snapshot, Opt_snapshot,
...@@ -207,6 +208,7 @@ static const match_table_t cifs_mount_option_tokens = { ...@@ -207,6 +208,7 @@ static const match_table_t cifs_mount_option_tokens = {
{ Opt_dirmode, "dirmode=%s" }, { Opt_dirmode, "dirmode=%s" },
{ Opt_dirmode, "dir_mode=%s" }, { Opt_dirmode, "dir_mode=%s" },
{ Opt_port, "port=%s" }, { Opt_port, "port=%s" },
{ Opt_min_enc_offload, "esize=%s" },
{ Opt_blocksize, "bsize=%s" }, { Opt_blocksize, "bsize=%s" },
{ Opt_rsize, "rsize=%s" }, { Opt_rsize, "rsize=%s" },
{ Opt_wsize, "wsize=%s" }, { Opt_wsize, "wsize=%s" },
...@@ -2016,6 +2018,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, ...@@ -2016,6 +2018,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
} }
port = (unsigned short)option; port = (unsigned short)option;
break; 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: case Opt_blocksize:
if (get_option_ul(args, &option)) { if (get_option_ul(args, &option)) {
cifs_dbg(VFS, "%s: Invalid blocksize value\n", 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,6 +2625,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
if (server->ignore_signature != vol->ignore_signature) if (server->ignore_signature != vol->ignore_signature)
return 0; return 0;
if (server->min_offload != vol->min_offload)
return 0;
return 1; return 1;
} }
...@@ -2790,6 +2802,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) ...@@ -2790,6 +2802,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
module_put(THIS_MODULE); module_put(THIS_MODULE);
goto out_err_crypto_release; goto out_err_crypto_release;
} }
tcp_ses->min_offload = volume_info->min_offload;
tcp_ses->tcpStatus = CifsNeedNegotiate; tcp_ses->tcpStatus = CifsNeedNegotiate;
tcp_ses->nr_targets = 1; tcp_ses->nr_targets = 1;
......
...@@ -4121,8 +4121,8 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid, ...@@ -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 * use more cores decrypting which can be expensive
*/ */
/* TODO: make the size limit to enable decrypt offload configurable */ if ((server->min_offload) &&
if (server->pdu_size > (512 * 1024)) { (server->pdu_size >= server->min_offload)) {
dw = kmalloc(sizeof(struct smb2_decrypt_work), GFP_KERNEL); dw = kmalloc(sizeof(struct smb2_decrypt_work), GFP_KERNEL);
if (dw == NULL) if (dw == NULL)
goto non_offloaded_decrypt; goto non_offloaded_decrypt;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment