提交 1041e3f9 编写于 作者: J Jeff Layton

cifs: keep a reusable kvec array for receives

Having to continually allocate a new kvec array is expensive. Allocate
one that's big enough, and only reallocate it as needed.
Reviewed-and-Tested-by: NPavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: NJeff Layton <jlayton@redhat.com>
上级 42c4dfc2
...@@ -292,6 +292,8 @@ struct TCP_Server_Info { ...@@ -292,6 +292,8 @@ struct TCP_Server_Info {
bool sec_kerberos; /* supports plain Kerberos */ bool sec_kerberos; /* supports plain Kerberos */
bool sec_mskerberos; /* supports legacy MS Kerberos */ bool sec_mskerberos; /* supports legacy MS Kerberos */
struct delayed_work echo; /* echo ping workqueue job */ struct delayed_work echo; /* echo ping workqueue job */
struct kvec *iov; /* reusable kvec array for receives */
unsigned int nr_iov; /* number of kvecs in array */
#ifdef CONFIG_CIFS_FSCACHE #ifdef CONFIG_CIFS_FSCACHE
struct fscache_cookie *fscache; /* client index cache cookie */ struct fscache_cookie *fscache; /* client index cache cookie */
#endif #endif
......
...@@ -410,6 +410,24 @@ kvec_array_init(struct kvec *new, struct kvec *iov, unsigned int nr_segs, ...@@ -410,6 +410,24 @@ kvec_array_init(struct kvec *new, struct kvec *iov, unsigned int nr_segs,
return nr_segs; return nr_segs;
} }
static struct kvec *
get_server_iovec(struct TCP_Server_Info *server, unsigned int nr_segs)
{
struct kvec *new_iov;
if (server->iov && nr_segs <= server->nr_iov)
return server->iov;
/* not big enough -- allocate a new one and release the old */
new_iov = kmalloc(sizeof(*new_iov) * nr_segs, GFP_NOFS);
if (new_iov) {
kfree(server->iov);
server->iov = new_iov;
server->nr_iov = nr_segs;
}
return new_iov;
}
static int static int
readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig, readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
unsigned int nr_segs, unsigned int to_read) unsigned int nr_segs, unsigned int to_read)
...@@ -420,7 +438,7 @@ readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig, ...@@ -420,7 +438,7 @@ readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
struct msghdr smb_msg; struct msghdr smb_msg;
struct kvec *iov; struct kvec *iov;
iov = kmalloc(sizeof(*iov_orig) * nr_segs, GFP_NOFS); iov = get_server_iovec(server, nr_segs);
if (!iov) if (!iov)
return -ENOMEM; return -ENOMEM;
...@@ -464,7 +482,6 @@ readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig, ...@@ -464,7 +482,6 @@ readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
break; break;
} }
} }
kfree(iov);
return total_read; return total_read;
} }
...@@ -669,6 +686,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) ...@@ -669,6 +686,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
} }
kfree(server->hostname); kfree(server->hostname);
kfree(server->iov);
kfree(server); kfree(server);
length = atomic_dec_return(&tcpSesAllocCount); length = atomic_dec_return(&tcpSesAllocCount);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册