diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index 358562e86..1e62a9f6d 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -903,7 +903,8 @@ Name | Optional | Type | Description action_on_timeout | Optional | string | Action to take on command time out: none, reset or abort timeout_us | Optional | number | Timeout for each command, in microseconds. If 0, don't track timeouts retry_count | Optional | number | The number of attempts per I/O before an I/O fails -nvme_adminq_poll_period_us | Optional | number | How often the admin queue is polled for asynchronous events in microsecond +nvme_adminq_poll_period_us | Optional | number | How often the admin queue is polled for asynchronous events in microseconds +nvme_ioq_poll_period_us | Optional | number | How often I/O queues are polled for completions, in microseconds. Default: 0 (as fast as possible). ### Example diff --git a/etc/spdk/iscsi.conf.in b/etc/spdk/iscsi.conf.in index 2f725dc13..1a5dc9a80 100644 --- a/etc/spdk/iscsi.conf.in +++ b/etc/spdk/iscsi.conf.in @@ -118,6 +118,9 @@ # Set how often the admin queue is polled for asynchronous events. # Units in microseconds. AdminPollRate 100000 + # Set how often I/O queues are polled from completions. + # Units in microseconds. + IOPollRate 0 # Disable handling of hotplug (runtime insert and remove) events, # users can set to Yes if want to enable it. diff --git a/etc/spdk/nvmf.conf.in b/etc/spdk/nvmf.conf.in index 66ca5a0cd..3be1005d3 100644 --- a/etc/spdk/nvmf.conf.in +++ b/etc/spdk/nvmf.conf.in @@ -109,6 +109,9 @@ # Set how often the admin queue is polled for asynchronous events. # Units in microseconds. AdminPollRate 100000 + # Set how often I/O queues are polled from completions. + # Units in microseconds. + IOPollRate 0 # Disable handling of hotplug (runtime insert and remove) events, # users can set to Yes if want to enable it. diff --git a/etc/spdk/vhost.conf.in b/etc/spdk/vhost.conf.in index 1605749d5..1a414cf11 100644 --- a/etc/spdk/vhost.conf.in +++ b/etc/spdk/vhost.conf.in @@ -99,6 +99,9 @@ # Set how often the admin queue is polled for asynchronous events. # Units in microseconds. AdminPollRate 100000 + # Set how often I/O queues are polled from completions. + # Units in microseconds. + IOPollRate 0 # The Split virtual block device slices block devices into multiple smaller bdevs. [Split] diff --git a/lib/bdev/nvme/bdev_nvme.c b/lib/bdev/nvme/bdev_nvme.c index f2787d425..5b98a1e72 100644 --- a/lib/bdev/nvme/bdev_nvme.c +++ b/lib/bdev/nvme/bdev_nvme.c @@ -98,6 +98,7 @@ static struct spdk_bdev_nvme_opts g_opts = { .timeout_us = 0, .retry_count = SPDK_NVME_DEFAULT_RETRY_COUNT, .nvme_adminq_poll_period_us = 1000000ULL, + .nvme_ioq_poll_period_us = 0, }; #define NVME_HOTPLUG_POLL_PERIOD_MAX 10000000ULL @@ -532,7 +533,7 @@ bdev_nvme_create_cb(void *io_device, void *ctx_buf) return -1; } - ch->poller = spdk_poller_register(bdev_nvme_poll, ch, 0); + ch->poller = spdk_poller_register(bdev_nvme_poll, ch, g_opts.nvme_ioq_poll_period_us); return 0; } @@ -1308,6 +1309,11 @@ bdev_nvme_library_init(void) g_opts.nvme_adminq_poll_period_us = intval; } + intval = spdk_conf_section_get_intval(sp, "IOPollRate"); + if (intval > 0) { + g_opts.nvme_ioq_poll_period_us = intval; + } + if (spdk_process_is_primary()) { hotplug_enabled = spdk_conf_section_get_boolval(sp, "HotplugEnable", false); } @@ -1732,6 +1738,7 @@ bdev_nvme_get_spdk_running_config(FILE *fp) "# Set how often the admin queue is polled for asynchronous events.\n" "# Units in microseconds.\n"); fprintf(fp, "AdminPollRate %"PRIu64"\n", g_opts.nvme_adminq_poll_period_us); + fprintf(fp, "IOPollRate %" PRIu64"\n", g_opts.nvme_ioq_poll_period_us); fprintf(fp, "\n" "# Disable handling of hotplug (runtime insert and remove) events,\n" "# users can set to Yes if want to enable it.\n" @@ -1773,6 +1780,7 @@ bdev_nvme_config_json(struct spdk_json_write_ctx *w) spdk_json_write_named_uint64(w, "timeout_us", g_opts.timeout_us); spdk_json_write_named_uint32(w, "retry_count", g_opts.retry_count); spdk_json_write_named_uint64(w, "nvme_adminq_poll_period_us", g_opts.nvme_adminq_poll_period_us); + spdk_json_write_named_uint64(w, "nvme_ioq_poll_period_us", g_opts.nvme_ioq_poll_period_us); spdk_json_write_object_end(w); spdk_json_write_object_end(w); diff --git a/lib/bdev/nvme/bdev_nvme.h b/lib/bdev/nvme/bdev_nvme.h index f48c696b0..3afd0e0bd 100644 --- a/lib/bdev/nvme/bdev_nvme.h +++ b/lib/bdev/nvme/bdev_nvme.h @@ -53,6 +53,7 @@ struct spdk_bdev_nvme_opts { uint64_t timeout_us; uint32_t retry_count; uint64_t nvme_adminq_poll_period_us; + uint64_t nvme_ioq_poll_period_us; }; struct nvme_ctrlr { diff --git a/lib/bdev/nvme/bdev_nvme_rpc.c b/lib/bdev/nvme/bdev_nvme_rpc.c index a9154d4e5..9f5ccbf33 100644 --- a/lib/bdev/nvme/bdev_nvme_rpc.c +++ b/lib/bdev/nvme/bdev_nvme_rpc.c @@ -73,6 +73,7 @@ static const struct spdk_json_object_decoder rpc_bdev_nvme_options_decoders[] = {"timeout_us", offsetof(struct spdk_bdev_nvme_opts, timeout_us), spdk_json_decode_uint64, true}, {"retry_count", offsetof(struct spdk_bdev_nvme_opts, retry_count), spdk_json_decode_uint32, true}, {"nvme_adminq_poll_period_us", offsetof(struct spdk_bdev_nvme_opts, nvme_adminq_poll_period_us), spdk_json_decode_uint64, true}, + {"nvme_ioq_poll_period_us", offsetof(struct spdk_bdev_nvme_opts, nvme_ioq_poll_period_us), spdk_json_decode_uint64, true}, }; static void diff --git a/scripts/rpc.py b/scripts/rpc.py index 7f2698f80..5ee4ef97a 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -224,7 +224,8 @@ if __name__ == "__main__": action_on_timeout=args.action_on_timeout, timeout_us=args.timeout_us, retry_count=args.retry_count, - nvme_adminq_poll_period_us=args.nvme_adminq_poll_period_us) + nvme_adminq_poll_period_us=args.nvme_adminq_poll_period_us, + nvme_ioq_poll_period_us=args.nvme_ioq_poll_period_us) p = subparsers.add_parser('set_bdev_nvme_options', help='Set options for the bdev nvme type. This is startup command.') @@ -236,6 +237,8 @@ if __name__ == "__main__": help='the number of attempts per I/O when an I/O fails', type=int) p.add_argument('-p', '--nvme-adminq-poll-period-us', help='How often the admin queue is polled for asynchronous events', type=int) + p.add_argument('-i', '--nvme-ioq-poll-period-us', + help='How often to poll I/O queues for completions', type=int) p.set_defaults(func=set_bdev_nvme_options) @call_cmd diff --git a/scripts/rpc/bdev.py b/scripts/rpc/bdev.py index ada9448ea..b1278c897 100755 --- a/scripts/rpc/bdev.py +++ b/scripts/rpc/bdev.py @@ -147,14 +147,16 @@ def delete_aio_bdev(client, name): return client.call('delete_aio_bdev', params) -def set_bdev_nvme_options(client, action_on_timeout=None, timeout_us=None, retry_count=None, nvme_adminq_poll_period_us=None): +def set_bdev_nvme_options(client, action_on_timeout=None, timeout_us=None, retry_count=None, + nvme_adminq_poll_period_us=None, nvme_ioq_poll_period_us=None): """Set options for the bdev nvme. This is startup command. Args: action_on_timeout: action to take on command time out. Valid values are: none, reset, abort (optional) timeout_us: Timeout for each command, in microseconds. If 0, don't track timeouts (optional) retry_count: The number of attempts per I/O when an I/O fails (optional) - nvme_adminq_poll_period_us: how often the admin queue is polled for asynchronous events in microsecon (optional) + nvme_adminq_poll_period_us: How often the admin queue is polled for asynchronous events in microseconds (optional) + nvme_ioq_poll_period_us: How often to poll I/O queues for completions in microseconds (optional) """ params = {} @@ -170,6 +172,9 @@ def set_bdev_nvme_options(client, action_on_timeout=None, timeout_us=None, retry if nvme_adminq_poll_period_us: params['nvme_adminq_poll_period_us'] = nvme_adminq_poll_period_us + if nvme_ioq_poll_period_us: + params['nvme_ioq_poll_period_us'] = nvme_ioq_poll_period_us + return client.call('set_bdev_nvme_options', params)