sock: Add sock_impl option to disable zero copy on send

Zero copy send can cause performance degradation with small
payloads. This patch adds an option to disable it if required. By
default zero copy is enabled.

Signed-off-by: Evgeniy Kochetov <evgeniik@mellanox.com>
Change-Id: I14f2b21ad375e770cb08f850360898bac675b351
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3344
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Evgeniy Kochetov 2020-07-14 22:03:45 +03:00 committed by Jim Harris
parent 63c5e51ebc
commit 29f31a90e1
8 changed files with 34 additions and 5 deletions

View File

@ -110,6 +110,9 @@ based socket tests for iSCSI target and also the tests for SPDK NVMe-oF tcp tran
Added `enable_recv_pipe` socket layer option to allow disabling of double buffering on receive. Added `enable_recv_pipe` socket layer option to allow disabling of double buffering on receive.
New option is used only in posix implementation. New option is used only in posix implementation.
Added `enable_zerocopy_send` socket layer option to allow disabling of zero copy flow on send.
New option is used only in posix implementation.
### vhost ### vhost
The function `spdk_vhost_blk_get_dev` has been removed. The function `spdk_vhost_blk_get_dev` has been removed.

View File

@ -6587,6 +6587,7 @@ Example response:
"recv_buf_size": 2097152, "recv_buf_size": 2097152,
"send_buf_size": 2097152, "send_buf_size": 2097152,
"enable_recv_pipe": true "enable_recv_pipe": true
"enable_zerocopy_send": true
} }
} }
~~~ ~~~
@ -6603,6 +6604,7 @@ impl_name | Required | string | Name of socket implementation
recv_buf_size | Optional | number | Size of socket receive buffer in bytes recv_buf_size | Optional | number | Size of socket receive buffer in bytes
send_buf_size | Optional | number | Size of socket send buffer in bytes send_buf_size | Optional | number | Size of socket send buffer in bytes
enable_recv_pipe | Optional | boolean | Enable or disable receive pipe enable_recv_pipe | Optional | boolean | Enable or disable receive pipe
enable_zerocopy_send | Optional | boolean | Enable or disable zero copy on send
### Response ### Response
@ -6622,6 +6624,7 @@ Example request:
"recv_buf_size": 2097152, "recv_buf_size": 2097152,
"send_buf_size": 2097152, "send_buf_size": 2097152,
"enable_recv_pipe": false "enable_recv_pipe": false
"enable_zerocopy_send": true
} }
} }
~~~ ~~~

View File

@ -102,6 +102,11 @@ struct spdk_sock_impl_opts {
* Enable or disable receive pipe. Used by posix socket module. * Enable or disable receive pipe. Used by posix socket module.
*/ */
bool enable_recv_pipe; bool enable_recv_pipe;
/**
* Enable or disable use of zero copy flow on send. Used by posix socket module.
*/
bool enable_zerocopy_send;
}; };
/** /**

View File

@ -776,6 +776,7 @@ spdk_sock_write_config_json(struct spdk_json_write_ctx *w)
spdk_json_write_named_uint32(w, "recv_buf_size", opts.recv_buf_size); spdk_json_write_named_uint32(w, "recv_buf_size", opts.recv_buf_size);
spdk_json_write_named_uint32(w, "send_buf_size", opts.send_buf_size); spdk_json_write_named_uint32(w, "send_buf_size", opts.send_buf_size);
spdk_json_write_named_bool(w, "enable_recv_pipe", opts.enable_recv_pipe); spdk_json_write_named_bool(w, "enable_recv_pipe", opts.enable_recv_pipe);
spdk_json_write_named_bool(w, "enable_zerocopy_send", opts.enable_zerocopy_send);
spdk_json_write_object_end(w); spdk_json_write_object_end(w);
spdk_json_write_object_end(w); spdk_json_write_object_end(w);
} else { } else {

View File

@ -74,6 +74,7 @@ rpc_sock_impl_get_options(struct spdk_jsonrpc_request *request,
spdk_json_write_named_uint32(w, "recv_buf_size", sock_opts.recv_buf_size); spdk_json_write_named_uint32(w, "recv_buf_size", sock_opts.recv_buf_size);
spdk_json_write_named_uint32(w, "send_buf_size", sock_opts.send_buf_size); spdk_json_write_named_uint32(w, "send_buf_size", sock_opts.send_buf_size);
spdk_json_write_named_bool(w, "enable_recv_pipe", sock_opts.enable_recv_pipe); spdk_json_write_named_bool(w, "enable_recv_pipe", sock_opts.enable_recv_pipe);
spdk_json_write_named_bool(w, "enable_zerocopy_send", sock_opts.enable_zerocopy_send);
spdk_json_write_object_end(w); spdk_json_write_object_end(w);
spdk_jsonrpc_end_result(request, w); spdk_jsonrpc_end_result(request, w);
free(impl_name); free(impl_name);
@ -103,6 +104,10 @@ static const struct spdk_json_object_decoder rpc_sock_impl_set_opts_decoders[] =
"enable_recv_pipe", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_recv_pipe), "enable_recv_pipe", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_recv_pipe),
spdk_json_decode_bool, true spdk_json_decode_bool, true
}, },
{
"enable_zerocopy_send", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_zerocopy_send),
spdk_json_decode_bool, true
},
}; };
static void static void

View File

@ -82,7 +82,8 @@ struct spdk_posix_sock_group_impl {
static struct spdk_sock_impl_opts g_spdk_posix_sock_impl_opts = { static struct spdk_sock_impl_opts g_spdk_posix_sock_impl_opts = {
.recv_buf_size = MIN_SO_RCVBUF_SIZE, .recv_buf_size = MIN_SO_RCVBUF_SIZE,
.send_buf_size = MIN_SO_SNDBUF_SIZE, .send_buf_size = MIN_SO_SNDBUF_SIZE,
.enable_recv_pipe = true .enable_recv_pipe = true,
.enable_zerocopy_send = true
}; };
static int static int
@ -326,7 +327,7 @@ posix_sock_alloc(int fd, bool enable_zero_copy)
sock->fd = fd; sock->fd = fd;
#ifdef SPDK_ZEROCOPY #ifdef SPDK_ZEROCOPY
if (!enable_zero_copy) { if (!enable_zero_copy || !g_spdk_posix_sock_impl_opts.enable_zerocopy_send) {
return sock; return sock;
} }
@ -1336,6 +1337,7 @@ posix_sock_impl_get_opts(struct spdk_sock_impl_opts *opts, size_t *len)
GET_FIELD(recv_buf_size); GET_FIELD(recv_buf_size);
GET_FIELD(send_buf_size); GET_FIELD(send_buf_size);
GET_FIELD(enable_recv_pipe); GET_FIELD(enable_recv_pipe);
GET_FIELD(enable_zerocopy_send);
#undef GET_FIELD #undef GET_FIELD
#undef FIELD_OK #undef FIELD_OK
@ -1363,6 +1365,7 @@ posix_sock_impl_set_opts(const struct spdk_sock_impl_opts *opts, size_t len)
SET_FIELD(recv_buf_size); SET_FIELD(recv_buf_size);
SET_FIELD(send_buf_size); SET_FIELD(send_buf_size);
SET_FIELD(enable_recv_pipe); SET_FIELD(enable_recv_pipe);
SET_FIELD(enable_zerocopy_send);
#undef SET_FIELD #undef SET_FIELD
#undef FIELD_OK #undef FIELD_OK

View File

@ -2398,7 +2398,8 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
impl_name=args.impl, impl_name=args.impl,
recv_buf_size=args.recv_buf_size, recv_buf_size=args.recv_buf_size,
send_buf_size=args.send_buf_size, send_buf_size=args.send_buf_size,
enable_recv_pipe=args.enable_recv_pipe) enable_recv_pipe=args.enable_recv_pipe,
enable_zerocopy_send=args.enable_zerocopy_send)
p = subparsers.add_parser('sock_impl_set_options', help="""Set options of socket layer implementation""") p = subparsers.add_parser('sock_impl_set_options', help="""Set options of socket layer implementation""")
p.add_argument('-i', '--impl', help='Socket implementation name, e.g. posix', required=True) p.add_argument('-i', '--impl', help='Socket implementation name, e.g. posix', required=True)
@ -2408,7 +2409,11 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
action='store_true', dest='enable_recv_pipe') action='store_true', dest='enable_recv_pipe')
p.add_argument('--disable-recv-pipe', help='Disable receive pipe', p.add_argument('--disable-recv-pipe', help='Disable receive pipe',
action='store_false', dest='enable_recv_pipe') action='store_false', dest='enable_recv_pipe')
p.set_defaults(func=sock_impl_set_options, enable_recv_pipe=None) p.add_argument('--enable-zerocopy-send', help='Enable zerocopy on send',
action='store_true', dest='enable_zerocopy_send')
p.add_argument('--disable-zerocopy-send', help='Disable zerocopy on send',
action='store_false', dest='enable_zerocopy_send')
p.set_defaults(func=sock_impl_set_options, enable_recv_pipe=None, enable_zerocopy_send=None)
def check_called_name(name): def check_called_name(name):
if name in deprecated_aliases: if name in deprecated_aliases:

View File

@ -15,7 +15,8 @@ def sock_impl_set_options(client,
impl_name=None, impl_name=None,
recv_buf_size=None, recv_buf_size=None,
send_buf_size=None, send_buf_size=None,
enable_recv_pipe=None): enable_recv_pipe=None,
enable_zerocopy_send=None):
"""Set parameters for the socket layer implementation. """Set parameters for the socket layer implementation.
Args: Args:
@ -23,6 +24,7 @@ def sock_impl_set_options(client,
recv_buf_size: size of socket receive buffer in bytes (optional) recv_buf_size: size of socket receive buffer in bytes (optional)
send_buf_size: size of socket send buffer in bytes (optional) send_buf_size: size of socket send buffer in bytes (optional)
enable_recv_pipe: enable or disable receive pipe (optional) enable_recv_pipe: enable or disable receive pipe (optional)
enable_zerocopy_send: enable or disable zerocopy on send (optional)
""" """
params = {} params = {}
@ -33,5 +35,7 @@ def sock_impl_set_options(client,
params['send_buf_size'] = send_buf_size params['send_buf_size'] = send_buf_size
if enable_recv_pipe is not None: if enable_recv_pipe is not None:
params['enable_recv_pipe'] = enable_recv_pipe params['enable_recv_pipe'] = enable_recv_pipe
if enable_zerocopy_send is not None:
params['enable_zerocopy_send'] = enable_zerocopy_send
return client.call('sock_impl_set_options', params) return client.call('sock_impl_set_options', params)