diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index 80ccfdfdb..e7fde2c4f 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -2907,6 +2907,7 @@ io_queue_requests | Optional | number | The number of requests all delay_cmd_submit | Optional | boolean | Enable delaying NVMe command submission to allow batching of multiple commands. Default: `true`. transport_retry_count | Optional | number | The number of attempts per I/O in the transport layer before an I/O fails. bdev_retry_count | Optional | number | The number of attempts per I/O in the bdev layer before an I/O fails. -1 means infinite retries. +transport_ack_timeout | Optional | number | Time to wait ack until packet retransmission. RDMA specific. Range 0-31 where 0 is driver-specific default value. #### Example diff --git a/module/bdev/nvme/bdev_nvme.c b/module/bdev/nvme/bdev_nvme.c index 49a1bfc19..f951eb122 100644 --- a/module/bdev/nvme/bdev_nvme.c +++ b/module/bdev/nvme/bdev_nvme.c @@ -138,6 +138,7 @@ static struct spdk_bdev_nvme_opts g_opts = { .io_queue_requests = 0, .delay_cmd_submit = SPDK_BDEV_NVME_DEFAULT_DELAY_CMD_SUBMIT, .bdev_retry_count = 3, + .transport_ack_timeout = 0, }; #define NVME_HOTPLUG_POLL_PERIOD_MAX 10000000ULL @@ -3980,6 +3981,7 @@ bdev_nvme_create(struct spdk_nvme_transport_id *trid, } ctx->opts.transport_retry_count = g_opts.transport_retry_count; + ctx->opts.transport_ack_timeout = g_opts.transport_ack_timeout; ctx->opts.keep_alive_timeout_ms = g_opts.keep_alive_timeout_ms; ctx->opts.disable_read_ana_log_page = true; @@ -5592,6 +5594,7 @@ bdev_nvme_opts_config_json(struct spdk_json_write_ctx *w) spdk_json_write_named_uint32(w, "io_queue_requests", g_opts.io_queue_requests); spdk_json_write_named_bool(w, "delay_cmd_submit", g_opts.delay_cmd_submit); spdk_json_write_named_int32(w, "bdev_retry_count", g_opts.bdev_retry_count); + spdk_json_write_named_uint8(w, "transport_ack_timeout", g_opts.transport_ack_timeout); spdk_json_write_object_end(w); spdk_json_write_object_end(w); diff --git a/module/bdev/nvme/bdev_nvme.h b/module/bdev/nvme/bdev_nvme.h index 2c4b11df2..0ea4c1e61 100644 --- a/module/bdev/nvme/bdev_nvme.h +++ b/module/bdev/nvme/bdev_nvme.h @@ -253,6 +253,7 @@ struct spdk_bdev_nvme_opts { bool delay_cmd_submit; /* The number of attempts per I/O in the bdev layer before an I/O fails. */ int32_t bdev_retry_count; + uint8_t transport_ack_timeout; }; struct spdk_nvme_qpair *bdev_nvme_get_io_qpair(struct spdk_io_channel *ctrlr_io_ch); diff --git a/module/bdev/nvme/bdev_nvme_rpc.c b/module/bdev/nvme/bdev_nvme_rpc.c index 9ee7acca0..d1d1f85b4 100644 --- a/module/bdev/nvme/bdev_nvme_rpc.c +++ b/module/bdev/nvme/bdev_nvme_rpc.c @@ -91,6 +91,7 @@ static const struct spdk_json_object_decoder rpc_bdev_nvme_options_decoders[] = {"delay_cmd_submit", offsetof(struct spdk_bdev_nvme_opts, delay_cmd_submit), spdk_json_decode_bool, true}, {"transport_retry_count", offsetof(struct spdk_bdev_nvme_opts, transport_retry_count), spdk_json_decode_uint32, true}, {"bdev_retry_count", offsetof(struct spdk_bdev_nvme_opts, bdev_retry_count), spdk_json_decode_int32, true}, + {"transport_ack_timeout", offsetof(struct spdk_bdev_nvme_opts, transport_ack_timeout), spdk_json_decode_uint8, true}, }; static void diff --git a/scripts/rpc.py b/scripts/rpc.py index ab034142b..f58ec9a60 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -479,7 +479,8 @@ if __name__ == "__main__": io_queue_requests=args.io_queue_requests, delay_cmd_submit=args.delay_cmd_submit, transport_retry_count=args.transport_retry_count, - bdev_retry_count=args.bdev_retry_count) + bdev_retry_count=args.bdev_retry_count, + transport_ack_timeout=args.transport_ack_timeout) p = subparsers.add_parser('bdev_nvme_set_options', aliases=['set_bdev_nvme_options'], help='Set options for the bdev nvme type. This is startup command.') @@ -514,6 +515,9 @@ if __name__ == "__main__": help='the number of attempts per I/O in the transport layer when an I/O fails.', type=int) p.add_argument('-r', '--bdev-retry-count', help='the number of attempts per I/O in the bdev layer when an I/O fails. -1 means infinite retries.', type=int) + p.add_argument('-e', '--transport-ack-timeout', + help="""Time to wait ack until packet retransmission. RDMA specific. + Range 0-31 where 0 is driver-specific default value.""", type=int) p.set_defaults(func=bdev_nvme_set_options) diff --git a/scripts/rpc/bdev.py b/scripts/rpc/bdev.py index 64b6482b7..ac81f2dc5 100644 --- a/scripts/rpc/bdev.py +++ b/scripts/rpc/bdev.py @@ -442,7 +442,8 @@ def bdev_nvme_set_options(client, action_on_timeout=None, timeout_us=None, timeo keep_alive_timeout_ms=None, retry_count=None, arbitration_burst=None, low_priority_weight=None, medium_priority_weight=None, high_priority_weight=None, nvme_adminq_poll_period_us=None, nvme_ioq_poll_period_us=None, io_queue_requests=None, - delay_cmd_submit=None, transport_retry_count=None, bdev_retry_count=None): + delay_cmd_submit=None, transport_retry_count=None, bdev_retry_count=None, + transport_ack_timeout=None): """Set options for the bdev nvme. This is startup command. Args: @@ -461,6 +462,8 @@ def bdev_nvme_set_options(client, action_on_timeout=None, timeout_us=None, timeo delay_cmd_submit: Enable delayed NVMe command submission to allow batching of multiple commands (optional) transport_retry_count: The number of attempts per I/O in the transport layer when an I/O fails (optional) bdev_retry_count: The number of attempts per I/O in the bdev layer when an I/O fails. -1 means infinite retries. (optional) + transport_ack_timeout: Time to wait ack until packet retransmission. RDMA specific. + Range 0-31 where 0 is driver-specific default value (optional) """ params = {} @@ -510,6 +513,9 @@ def bdev_nvme_set_options(client, action_on_timeout=None, timeout_us=None, timeo if bdev_retry_count is not None: params['bdev_retry_count'] = bdev_retry_count + if transport_ack_timeout is not None: + params['transport_ack_timeout'] = transport_ack_timeout + return client.call('bdev_nvme_set_options', params)