diff options
author | David Teigland <teigland@redhat.com> | 2017-09-26 14:02:37 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2017-10-18 10:05:16 -0500 |
commit | d14d36b84acefbbfd3dd70ee21dfc2410dc02677 (patch) | |
tree | ee34de5def3f88b12b6b0f6c76b66e5aae2e7cde | |
parent | ae762dadd6912512eda788b468e4f6c2d7e5456a (diff) | |
download | lvm2-dev-dct-new-scan-7.tar.gz |
label_scan: use a single aio contextdev-dct-new-scan-7
A new aio context was being created, io_setup(2), in each
call to rescan labels. This is an expensive call, so keep
the aio context around to reuse in each call.
-rw-r--r-- | lib/commands/toolcontext.c | 3 | ||||
-rw-r--r-- | lib/commands/toolcontext.h | 1 | ||||
-rw-r--r-- | lib/label/label.c | 45 |
3 files changed, 15 insertions, 34 deletions
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c index e0dbad9a8..0c8e7a4c9 100644 --- a/lib/commands/toolcontext.c +++ b/lib/commands/toolcontext.c @@ -2246,6 +2246,9 @@ void destroy_toolcontext(struct cmd_context *cmd) !cmd->filter->dump(cmd->filter, 1)) stack; + if (cmd->ac) + dev_async_context_destroy(cmd->ac); + archive_exit(cmd); backup_exit(cmd); lvmcache_destroy(cmd, 0, 0); diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h index 702cc1680..b98bb9b68 100644 --- a/lib/commands/toolcontext.h +++ b/lib/commands/toolcontext.h @@ -225,6 +225,7 @@ struct cmd_context { const char *time_format; unsigned rand_seed; struct dm_list unused_duplicate_devs; /* save preferences between lvmcache instances */ + struct dev_async_context *ac; /* for async i/o */ }; /* diff --git a/lib/label/label.c b/lib/label/label.c index 7d2ebfbff..7a7167956 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -746,9 +746,12 @@ static int _label_scan_async(struct cmd_context *cmd, int skip_cached) * concurrent async reads that can be submitted. After * all of those are used, we revert to synchronous reads. */ - if (!(ac = dev_async_context_setup(async_event_count))) { - log_debug_devs("async io setup error, reverting to sync io."); - return_0; + if (!cmd->ac) { + if (!(ac = dev_async_context_setup(async_event_count))) { + log_debug_devs("async io setup error, reverting to sync io."); + return_0; + } + cmd->ac = ac; } log_debug_devs("Finding devices to scan"); @@ -812,7 +815,7 @@ static int _label_scan_async(struct cmd_context *cmd, int skip_cached) * fail and the next loop will try a sync read for it. */ dm_list_iterate_items(ld, &label_read_list) { - if (!_label_read_async_start(ac, ld)) + if (!_label_read_async_start(cmd->ac, ld)) ld->try_sync = 1; else log_debug_devs("Reading sectors from device %s async", dev_name(ld->dev)); @@ -870,7 +873,7 @@ static int _label_scan_async(struct cmd_context *cmd, int skip_cached) * Wait for more devices to finish reading label sectors. */ if (need_wait_count) { - if (_label_read_async_wait(ac, need_wait_count)) + if (_label_read_async_wait(cmd->ac, need_wait_count)) goto check_aio; /* TODO: handle this error */ @@ -879,8 +882,6 @@ static int _label_scan_async(struct cmd_context *cmd, int skip_cached) log_error(INTERNAL_ERROR "aio getevents error"); } - dev_async_context_destroy(ac); - dm_list_iterate_items(ld, &label_read_list) dev_close(ld->dev); @@ -892,7 +893,6 @@ bad: log_error("async data scan failed, reverting to sync scan."); dev_iter_destroy(iter); - dev_async_context_destroy(ac); dm_list_iterate_items(ld, &label_read_list) { dev_close(ld->dev); @@ -925,34 +925,15 @@ static int _label_scan_devs_async(struct cmd_context *cmd, struct dm_list *devs) struct label_read_data *ld, *ld2; struct device_list *devl; struct device *dev; - struct dev_async_context *ac; int buf_len; int need_wait_count; int need_process_count; int dev_count = 0; - int async_event_count; - int num_devs; buf_len = _get_scan_size(cmd); dm_list_init(&tmp_label_read_list); - async_event_count = find_config_tree_int(cmd, devices_async_events_CFG, NULL); - num_devs = dm_list_size(devs); - - if (num_devs < async_event_count) - async_event_count = num_devs; - - /* - * Should we set up one global aio context when the command starts, - * and then use/reuse that one context from multiple calls to - * label_scan/label_scan_devs? - */ - if (!(ac = dev_async_context_setup(async_event_count))) { - log_debug_devs("async io setup error, reverting to sync io."); - return_0; - } - log_debug_devs("Scanning data from devs async"); dm_list_iterate_items(devl, devs) { @@ -990,7 +971,7 @@ static int _label_scan_devs_async(struct cmd_context *cmd, struct dm_list *devs) ld->aio->done = 0; ld->process_done = 0; - if (!_label_read_async_start(ac, ld)) + if (!_label_read_async_start(cmd->ac, ld)) ld->try_sync = 1; else log_debug_devs("Reading sectors from device %s async", dev_name(ld->dev)); @@ -1056,7 +1037,7 @@ static int _label_scan_devs_async(struct cmd_context *cmd, struct dm_list *devs) * Wait for more devices to finish reading label sectors. */ if (need_wait_count) { - if (_label_read_async_wait(ac, need_wait_count)) + if (_label_read_async_wait(cmd->ac, need_wait_count)) goto check_aio; /* TODO: handle this error */ @@ -1065,8 +1046,6 @@ static int _label_scan_devs_async(struct cmd_context *cmd, struct dm_list *devs) log_error(INTERNAL_ERROR "aio getevents error"); } - dev_async_context_destroy(ac); - dm_list_iterate_items(ld, &tmp_label_read_list) dev_close(ld->dev); @@ -1083,8 +1062,6 @@ bad: /* caller will try sync scan */ log_error("async data scan failed, reverting to sync scan."); - dev_async_context_destroy(ac); - dm_list_iterate_items(ld, &label_read_list) { dev_close(ld->dev); if (ld->aio) @@ -1331,7 +1308,7 @@ int label_scan_devs(struct cmd_context *cmd, struct dm_list *devs) { int ret = 0; - if (cmd->use_aio) + if (cmd->use_aio && cmd->ac) ret = _label_scan_devs_async(cmd, devs); if (!ret) |