From 26e0ef9a36d130455f2f95f73143e998e06104b5 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Thu, 9 Jul 2020 10:50:03 +0900 Subject: [PATCH] lib/nvmf: Make abort execution timeout value optional Make the abort execution timeout value as optional. Zero is acceptable and means immediate timeout. Signed-off-by: Shuhei Matsumoto Change-Id: Ia4b03c65b8bd15899f48be9476ee657446147581 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3104 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Aleksey Marchuk Reviewed-by: Michael Haeuptle Reviewed-by: Jim Harris --- doc/jsonrpc.md | 4 +++- include/spdk/nvmf.h | 1 + lib/nvmf/nvmf.c | 1 + lib/nvmf/nvmf_rpc.c | 5 +++++ lib/nvmf/rdma.c | 17 ++++++++++++----- lib/nvmf/tcp.c | 18 +++++++++++++----- scripts/rpc.py | 4 +++- scripts/rpc/nvmf.py | 6 +++++- 8 files changed, 43 insertions(+), 13 deletions(-) diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index 243c9777d..28e42a652 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -4120,6 +4120,7 @@ c2h_success | Optional | boolean | Disable C2H success optimizat dif_insert_or_strip | Optional | boolean | Enable DIF insert for write I/O and DIF strip for read I/O DIF sock_priority | Optional | number | The socket priority of the connection owned by this transport (TCP only) acceptor_backlog | Optional | number | The number of pending connections allowed in backlog before failing new connection attempts (RDMA only) +abort_timeout_sec | Optional | number | Abort execution timeout value, in seconds ### Example @@ -4655,7 +4656,8 @@ Example response: "max_io_qpairs_per_ctrlr": 64, "in_capsule_data_size": 4096, "max_io_size": 131072, - "io_unit_size": 131072 + "io_unit_size": 131072, + "abort_timeout_sec": 1 } ] } diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index 143e5ad35..86ca574f6 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -85,6 +85,7 @@ struct spdk_nvmf_transport_opts { bool dif_insert_or_strip; uint32_t sock_priority; int acceptor_backlog; + uint32_t abort_timeout_sec; }; struct spdk_nvmf_poll_group_stat { diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index bd996774c..94a483d92 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -546,6 +546,7 @@ spdk_nvmf_tgt_write_config_json(struct spdk_json_write_ctx *w, struct spdk_nvmf_ if (transport->ops->type == SPDK_NVME_TRANSPORT_RDMA) { spdk_json_write_named_uint32(w, "max_srq_depth", transport->opts.max_srq_depth); } + spdk_json_write_named_uint32(w, "abort_timeout_sec", transport->opts.abort_timeout_sec); spdk_json_write_object_end(w); spdk_json_write_object_end(w); diff --git a/lib/nvmf/nvmf_rpc.c b/lib/nvmf/nvmf_rpc.c index 9b3d2b73a..5dc9f42f0 100644 --- a/lib/nvmf/nvmf_rpc.c +++ b/lib/nvmf/nvmf_rpc.c @@ -1650,6 +1650,10 @@ static const struct spdk_json_object_decoder nvmf_rpc_create_transport_decoder[] "acceptor_backlog", offsetof(struct nvmf_rpc_create_transport_ctx, opts.acceptor_backlog), spdk_json_decode_int32, true }, + { + "abort_timeout_sec", offsetof(struct nvmf_rpc_create_transport_ctx, opts.abort_timeout_sec), + spdk_json_decode_uint32, true + }, { "tgt_name", offsetof(struct nvmf_rpc_create_transport_ctx, tgt_name), spdk_json_decode_string, true @@ -1802,6 +1806,7 @@ dump_nvmf_transport(struct spdk_json_write_ctx *w, struct spdk_nvmf_transport *t spdk_json_write_named_bool(w, "c2h_success", opts->c2h_success); spdk_json_write_named_uint32(w, "sock_priority", opts->sock_priority); } + spdk_json_write_named_uint32(w, "abort_timeout_sec", opts->abort_timeout_sec); spdk_json_write_object_end(w); } diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index 2f6349f43..88eb03573 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -2222,6 +2222,7 @@ nvmf_rdma_request_process(struct spdk_nvmf_rdma_transport *rtransport, #define SPDK_NVMF_RDMA_DEFAULT_NO_SRQ false #define SPDK_NVMF_RDMA_DIF_INSERT_OR_STRIP false #define SPDK_NVMF_RDMA_ACCEPTOR_BACKLOG 100 +#define SPDK_NVMF_RDMA_DEFAULT_ABORT_TIMEOUT_SEC 1 static void nvmf_rdma_opts_init(struct spdk_nvmf_transport_opts *opts) @@ -2238,6 +2239,7 @@ nvmf_rdma_opts_init(struct spdk_nvmf_transport_opts *opts) opts->no_srq = SPDK_NVMF_RDMA_DEFAULT_NO_SRQ; opts->dif_insert_or_strip = SPDK_NVMF_RDMA_DIF_INSERT_OR_STRIP; opts->acceptor_backlog = SPDK_NVMF_RDMA_ACCEPTOR_BACKLOG; + opts->abort_timeout_sec = SPDK_NVMF_RDMA_DEFAULT_ABORT_TIMEOUT_SEC; } const struct spdk_mem_map_ops g_nvmf_rdma_map_ops = { @@ -2299,7 +2301,7 @@ nvmf_rdma_create(struct spdk_nvmf_transport_opts *opts) " max_io_qpairs_per_ctrlr=%d, io_unit_size=%d,\n" " in_capsule_data_size=%d, max_aq_depth=%d,\n" " num_shared_buffers=%d, max_srq_depth=%d, no_srq=%d," - " acceptor_backlog=%d\n", + " acceptor_backlog=%d, abort_timeout_sec=%d\n", opts->max_queue_depth, opts->max_io_size, opts->max_qpairs_per_ctrlr - 1, @@ -2309,7 +2311,8 @@ nvmf_rdma_create(struct spdk_nvmf_transport_opts *opts) opts->num_shared_buffers, opts->max_srq_depth, opts->no_srq, - opts->acceptor_backlog); + opts->acceptor_backlog, + opts->abort_timeout_sec); /* I/O unit size cannot be larger than max I/O size */ if (opts->io_unit_size > opts->max_io_size) { @@ -4040,8 +4043,6 @@ nvmf_rdma_request_set_abort_status(struct spdk_nvmf_request *req, req->rsp->nvme_cpl.cdw0 &= ~1U; /* Command was successfully aborted. */ } -#define NVMF_RDMA_ABORT_TIMEOUT_SEC 1 - static int _nvmf_rdma_qpair_abort_request(void *ctx) { @@ -4103,11 +4104,16 @@ nvmf_rdma_qpair_abort_request(struct spdk_nvmf_qpair *qpair, struct spdk_nvmf_request *req) { struct spdk_nvmf_rdma_qpair *rqpair; + struct spdk_nvmf_rdma_transport *rtransport; + struct spdk_nvmf_transport *transport; uint16_t cid; uint32_t i; struct spdk_nvmf_rdma_request *rdma_req_to_abort = NULL; rqpair = SPDK_CONTAINEROF(qpair, struct spdk_nvmf_rdma_qpair, qpair); + rtransport = SPDK_CONTAINEROF(qpair->transport, struct spdk_nvmf_rdma_transport, transport); + transport = &rtransport->transport; + cid = req->cmd->nvme_cmd.cdw10_bits.abort.cid; for (i = 0; i < rqpair->max_queue_depth; i++) { @@ -4125,7 +4131,8 @@ nvmf_rdma_qpair_abort_request(struct spdk_nvmf_qpair *qpair, } req->req_to_abort = &rdma_req_to_abort->req; - req->timeout_tsc = spdk_get_ticks() + NVMF_RDMA_ABORT_TIMEOUT_SEC * spdk_get_ticks_hz(); + req->timeout_tsc = spdk_get_ticks() + + transport->opts.abort_timeout_sec * spdk_get_ticks_hz(); req->poller = NULL; _nvmf_rdma_qpair_abort_request(req); diff --git a/lib/nvmf/tcp.c b/lib/nvmf/tcp.c index 9d2f21c5f..798df4d54 100644 --- a/lib/nvmf/tcp.c +++ b/lib/nvmf/tcp.c @@ -474,7 +474,8 @@ nvmf_tcp_create(struct spdk_nvmf_transport_opts *opts) " max_io_qpairs_per_ctrlr=%d, io_unit_size=%d,\n" " in_capsule_data_size=%d, max_aq_depth=%d\n" " num_shared_buffers=%d, c2h_success=%d,\n" - " dif_insert_or_strip=%d, sock_priority=%d\n", + " dif_insert_or_strip=%d, sock_priority=%d\n" + " abort_timeout_sec=%d\n", opts->max_queue_depth, opts->max_io_size, opts->max_qpairs_per_ctrlr - 1, @@ -484,7 +485,8 @@ nvmf_tcp_create(struct spdk_nvmf_transport_opts *opts) opts->num_shared_buffers, opts->c2h_success, opts->dif_insert_or_strip, - opts->sock_priority); + opts->sock_priority, + opts->abort_timeout_sec); if (opts->sock_priority > SPDK_NVMF_TCP_DEFAULT_MAX_SOCK_PRIORITY) { SPDK_ERRLOG("Unsupported socket_priority=%d, the current range is: 0 to %d\n" @@ -2473,8 +2475,6 @@ nvmf_tcp_req_set_abort_status(struct spdk_nvmf_request *req, req->rsp->nvme_cpl.cdw0 &= ~1U; /* Command was successfully aborted. */ } -#define NVMF_TCP_ABORT_TIMEOUT_SEC 1 - static int _nvmf_tcp_qpair_abort_request(void *ctx) { @@ -2526,11 +2526,16 @@ nvmf_tcp_qpair_abort_request(struct spdk_nvmf_qpair *qpair, struct spdk_nvmf_request *req) { struct spdk_nvmf_tcp_qpair *tqpair; + struct spdk_nvmf_tcp_transport *ttransport; + struct spdk_nvmf_transport *transport; uint16_t cid; uint32_t i; struct spdk_nvmf_tcp_req *tcp_req_to_abort = NULL; tqpair = SPDK_CONTAINEROF(qpair, struct spdk_nvmf_tcp_qpair, qpair); + ttransport = SPDK_CONTAINEROF(qpair->transport, struct spdk_nvmf_tcp_transport, transport); + transport = &ttransport->transport; + cid = req->cmd->nvme_cmd.cdw10_bits.abort.cid; for (i = 0; i < tqpair->resource_count; i++) { @@ -2548,7 +2553,8 @@ nvmf_tcp_qpair_abort_request(struct spdk_nvmf_qpair *qpair, } req->req_to_abort = &tcp_req_to_abort->req; - req->timeout_tsc = spdk_get_ticks() + NVMF_TCP_ABORT_TIMEOUT_SEC * spdk_get_ticks_hz(); + req->timeout_tsc = spdk_get_ticks() + + transport->opts.abort_timeout_sec * spdk_get_ticks_hz(); req->poller = NULL; _nvmf_tcp_qpair_abort_request(req); @@ -2565,6 +2571,7 @@ nvmf_tcp_qpair_abort_request(struct spdk_nvmf_qpair *qpair, #define SPDK_NVMF_TCP_DEFAULT_SUCCESS_OPTIMIZATION true #define SPDK_NVMF_TCP_DEFAULT_DIF_INSERT_OR_STRIP false #define SPDK_NVMF_TCP_DEFAULT_SOCK_PRIORITY 0 +#define SPDK_NVMF_TCP_DEFAULT_ABORT_TIMEOUT_SEC 1 static void nvmf_tcp_opts_init(struct spdk_nvmf_transport_opts *opts) @@ -2580,6 +2587,7 @@ nvmf_tcp_opts_init(struct spdk_nvmf_transport_opts *opts) opts->c2h_success = SPDK_NVMF_TCP_DEFAULT_SUCCESS_OPTIMIZATION; opts->dif_insert_or_strip = SPDK_NVMF_TCP_DEFAULT_DIF_INSERT_OR_STRIP; opts->sock_priority = SPDK_NVMF_TCP_DEFAULT_SOCK_PRIORITY; + opts->abort_timeout_sec = SPDK_NVMF_TCP_DEFAULT_ABORT_TIMEOUT_SEC; } const struct spdk_nvmf_transport_ops spdk_nvmf_transport_tcp = { diff --git a/scripts/rpc.py b/scripts/rpc.py index e1fb4b626..941108b64 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -1727,7 +1727,8 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse c2h_success=args.c2h_success, dif_insert_or_strip=args.dif_insert_or_strip, sock_priority=args.sock_priority, - acceptor_backlog=args.acceptor_backlog) + acceptor_backlog=args.acceptor_backlog, + abort_timeout_sec=args.abort_timeout_sec) p = subparsers.add_parser('nvmf_create_transport', help='Create NVMf transport') p.add_argument('-t', '--trtype', help='Transport type (ex. RDMA)', type=str, required=True) @@ -1748,6 +1749,7 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse p.add_argument('-f', '--dif-insert-or-strip', action='store_true', help='Enable DIF insert/strip. Relevant only for TCP transport') p.add_argument('-y', '--sock-priority', help='The sock priority of the tcp connection. Relevant only for TCP transport', type=int) p.add_argument('-l', '--acceptor_backlog', help='Pending connections allowed at one time. Relevant only for RDMA transport', type=int) + p.add_argument('-x', '--abort-timeout-sec', help='Abort execution timeout value, in seconds', type=int) p.set_defaults(func=nvmf_create_transport) def nvmf_get_transports(args): diff --git a/scripts/rpc/nvmf.py b/scripts/rpc/nvmf.py index 968a95f87..7b2bc3bb6 100644 --- a/scripts/rpc/nvmf.py +++ b/scripts/rpc/nvmf.py @@ -108,7 +108,8 @@ def nvmf_create_transport(client, c2h_success=True, dif_insert_or_strip=None, sock_priority=None, - acceptor_backlog=None): + acceptor_backlog=None, + abort_timeout_sec=None): """NVMf Transport Create options. Args: @@ -127,6 +128,7 @@ def nvmf_create_transport(client, c2h_success: Boolean flag to disable the C2H success optimization - TCP specific (optional) dif_insert_or_strip: Boolean flag to enable DIF insert/strip for I/O - TCP specific (optional) acceptor_backlog: Pending connections allowed at one time - RDMA specific (optional) + abort_timeout_sec: Abort execution timeout value, in seconds (optional) Returns: True or False @@ -167,6 +169,8 @@ def nvmf_create_transport(client, params['sock_priority'] = sock_priority if acceptor_backlog is not None: params['acceptor_backlog'] = acceptor_backlog + if abort_timeout_sec: + params['abort_timeout_sec'] = abort_timeout_sec return client.call('nvmf_create_transport', params)