diff --git a/CHANGELOG.md b/CHANGELOG.md index ffcb7bbc8..2839e8d05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. 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 The function `spdk_vhost_blk_get_dev` has been removed. diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index b95348e1a..055c3b11a 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -6587,6 +6587,7 @@ Example response: "recv_buf_size": 2097152, "send_buf_size": 2097152, "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 send_buf_size | Optional | number | Size of socket send buffer in bytes enable_recv_pipe | Optional | boolean | Enable or disable receive pipe +enable_zerocopy_send | Optional | boolean | Enable or disable zero copy on send ### Response @@ -6622,6 +6624,7 @@ Example request: "recv_buf_size": 2097152, "send_buf_size": 2097152, "enable_recv_pipe": false + "enable_zerocopy_send": true } } ~~~ diff --git a/include/spdk/sock.h b/include/spdk/sock.h index 1b3fd72b0..f70a2ac39 100644 --- a/include/spdk/sock.h +++ b/include/spdk/sock.h @@ -102,6 +102,11 @@ struct spdk_sock_impl_opts { * Enable or disable receive pipe. Used by posix socket module. */ bool enable_recv_pipe; + + /** + * Enable or disable use of zero copy flow on send. Used by posix socket module. + */ + bool enable_zerocopy_send; }; /** diff --git a/lib/sock/sock.c b/lib/sock/sock.c index 81b55d625..5ea90385c 100644 --- a/lib/sock/sock.c +++ b/lib/sock/sock.c @@ -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, "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_zerocopy_send", opts.enable_zerocopy_send); spdk_json_write_object_end(w); spdk_json_write_object_end(w); } else { diff --git a/lib/sock/sock_rpc.c b/lib/sock/sock_rpc.c index 8343fa2ec..c8686a068 100644 --- a/lib/sock/sock_rpc.c +++ b/lib/sock/sock_rpc.c @@ -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, "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_zerocopy_send", sock_opts.enable_zerocopy_send); spdk_json_write_object_end(w); spdk_jsonrpc_end_result(request, w); 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), 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 diff --git a/module/sock/posix/posix.c b/module/sock/posix/posix.c index 6e04c14ff..4eb1bf106 100644 --- a/module/sock/posix/posix.c +++ b/module/sock/posix/posix.c @@ -82,7 +82,8 @@ struct spdk_posix_sock_group_impl { static struct spdk_sock_impl_opts g_spdk_posix_sock_impl_opts = { .recv_buf_size = MIN_SO_RCVBUF_SIZE, .send_buf_size = MIN_SO_SNDBUF_SIZE, - .enable_recv_pipe = true + .enable_recv_pipe = true, + .enable_zerocopy_send = true }; static int @@ -326,7 +327,7 @@ posix_sock_alloc(int fd, bool enable_zero_copy) sock->fd = fd; #ifdef SPDK_ZEROCOPY - if (!enable_zero_copy) { + if (!enable_zero_copy || !g_spdk_posix_sock_impl_opts.enable_zerocopy_send) { 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(send_buf_size); GET_FIELD(enable_recv_pipe); + GET_FIELD(enable_zerocopy_send); #undef GET_FIELD #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(send_buf_size); SET_FIELD(enable_recv_pipe); + SET_FIELD(enable_zerocopy_send); #undef SET_FIELD #undef FIELD_OK diff --git a/scripts/rpc.py b/scripts/rpc.py index b20b10d29..84c502fe6 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -2398,7 +2398,8 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse impl_name=args.impl, recv_buf_size=args.recv_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.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') p.add_argument('--disable-recv-pipe', help='Disable receive 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): if name in deprecated_aliases: diff --git a/scripts/rpc/sock.py b/scripts/rpc/sock.py index d56d25357..34d7f100d 100644 --- a/scripts/rpc/sock.py +++ b/scripts/rpc/sock.py @@ -15,7 +15,8 @@ def sock_impl_set_options(client, impl_name=None, recv_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. Args: @@ -23,6 +24,7 @@ def sock_impl_set_options(client, recv_buf_size: size of socket receive 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_zerocopy_send: enable or disable zerocopy on send (optional) """ params = {} @@ -33,5 +35,7 @@ def sock_impl_set_options(client, params['send_buf_size'] = send_buf_size if enable_recv_pipe is not None: 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)