Commit 3cecf486 authored by Ronnie Sahlberg's avatar Ronnie Sahlberg Committed by Steve French

cifs: avoid a kmalloc in smb2_send_recv/SendReceive2 for the common case

In both functions, use an array of 8 (arbitrary but should be big enough
for all current uses) iov and avoid having to kmalloc the array
for the common case.

If 8 is too small, then fall back to the original behaviour and use
kmalloc/kfree.

This should not change any behaviour but should save us a tiny amount of
cpu cycles.
Signed-off-by: default avatarRonnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
Reviewed-by: default avatarPavel Shilovsky <pshilov@microsoft.com>
parent 305428ac
...@@ -38,6 +38,9 @@ ...@@ -38,6 +38,9 @@
#include "cifsproto.h" #include "cifsproto.h"
#include "cifs_debug.h" #include "cifs_debug.h"
/* Max number of iovectors we can use off the stack when sending requests. */
#define CIFS_MAX_IOV_SIZE 8
void void
cifs_wake_up_task(struct mid_q_entry *mid) cifs_wake_up_task(struct mid_q_entry *mid)
{ {
...@@ -803,12 +806,16 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, ...@@ -803,12 +806,16 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
const int flags, struct kvec *resp_iov) const int flags, struct kvec *resp_iov)
{ {
struct smb_rqst rqst; struct smb_rqst rqst;
struct kvec *new_iov; struct kvec s_iov[CIFS_MAX_IOV_SIZE], *new_iov;
int rc; int rc;
new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1), GFP_KERNEL); if (n_vec + 1 > CIFS_MAX_IOV_SIZE) {
if (!new_iov) new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1),
return -ENOMEM; GFP_KERNEL);
if (!new_iov)
return -ENOMEM;
} else
new_iov = s_iov;
/* 1st iov is a RFC1001 length followed by the rest of the packet */ /* 1st iov is a RFC1001 length followed by the rest of the packet */
memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec)); memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec));
...@@ -823,7 +830,8 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, ...@@ -823,7 +830,8 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
rqst.rq_nvec = n_vec + 1; rqst.rq_nvec = n_vec + 1;
rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov); rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov);
kfree(new_iov); if (n_vec + 1 > CIFS_MAX_IOV_SIZE)
kfree(new_iov);
return rc; return rc;
} }
...@@ -834,15 +842,19 @@ smb2_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -834,15 +842,19 @@ smb2_send_recv(const unsigned int xid, struct cifs_ses *ses,
const int flags, struct kvec *resp_iov) const int flags, struct kvec *resp_iov)
{ {
struct smb_rqst rqst; struct smb_rqst rqst;
struct kvec *new_iov; struct kvec s_iov[CIFS_MAX_IOV_SIZE], *new_iov;
int rc; int rc;
int i; int i;
__u32 count; __u32 count;
__be32 rfc1002_marker; __be32 rfc1002_marker;
new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1), GFP_KERNEL); if (n_vec + 1 > CIFS_MAX_IOV_SIZE) {
if (!new_iov) new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1),
return -ENOMEM; GFP_KERNEL);
if (!new_iov)
return -ENOMEM;
} else
new_iov = s_iov;
/* 1st iov is an RFC1002 Session Message length */ /* 1st iov is an RFC1002 Session Message length */
memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec)); memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec));
...@@ -861,7 +873,8 @@ smb2_send_recv(const unsigned int xid, struct cifs_ses *ses, ...@@ -861,7 +873,8 @@ smb2_send_recv(const unsigned int xid, struct cifs_ses *ses,
rqst.rq_nvec = n_vec + 1; rqst.rq_nvec = n_vec + 1;
rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov); rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov);
kfree(new_iov); if (n_vec + 1 > CIFS_MAX_IOV_SIZE)
kfree(new_iov);
return rc; return rc;
} }
......
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