summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2017-09-26 14:02:37 -0500
committerDavid Teigland <teigland@redhat.com>2017-10-18 10:05:16 -0500
commitd14d36b84acefbbfd3dd70ee21dfc2410dc02677 (patch)
treeee34de5def3f88b12b6b0f6c76b66e5aae2e7cde
parentae762dadd6912512eda788b468e4f6c2d7e5456a (diff)
downloadlvm2-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.c3
-rw-r--r--lib/commands/toolcontext.h1
-rw-r--r--lib/label/label.c45
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)