Commit b63349a7 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Mike Snitzer

dm mpath: requeue I/O during pg_init

When pg_init is running no I/O can be submitted to the underlying
devices, as the path priority etc might change.  When using queue_io for
this, requests will be piling up within multipath as the block I/O
scheduler just sees a _very fast_ device.  All of this queued I/O has to
be resubmitted from within multipathing once pg_init is done.

This approach has the problem that it's virtually impossible to
abort I/O when pg_init is running, and we're adding heavy load
to the devices after pg_init since all of the queued I/O needs to be
resubmitted _before_ any requests can be pulled off of the request queue
and normal operation continues.

This patch will requeue the I/O that triggers the pg_init call, and
return 'busy' when pg_init is in progress.  With these changes the block
I/O scheduler will stop submitting I/O during pg_init, resulting in a
quicker path switch and less I/O pressure (and memory consumption) after
pg_init.
Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
[patch header edited for clarity and typos by Mike Snitzer]
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 954a73d5
...@@ -391,13 +391,16 @@ static int map_io(struct multipath *m, struct request *clone, ...@@ -391,13 +391,16 @@ static int map_io(struct multipath *m, struct request *clone,
if (was_queued) if (was_queued)
m->queue_size--; m->queue_size--;
if ((pgpath && m->queue_io) || if (m->pg_init_required) {
(!pgpath && m->queue_if_no_path)) { if (!m->pg_init_in_progress)
queue_work(kmultipathd, &m->process_queued_ios);
r = DM_MAPIO_REQUEUE;
} else if ((pgpath && m->queue_io) ||
(!pgpath && m->queue_if_no_path)) {
/* Queue for the daemon to resubmit */ /* Queue for the daemon to resubmit */
list_add_tail(&clone->queuelist, &m->queued_ios); list_add_tail(&clone->queuelist, &m->queued_ios);
m->queue_size++; m->queue_size++;
if ((m->pg_init_required && !m->pg_init_in_progress) || if (!m->queue_io)
!m->queue_io)
queue_work(kmultipathd, &m->process_queued_ios); queue_work(kmultipathd, &m->process_queued_ios);
pgpath = NULL; pgpath = NULL;
r = DM_MAPIO_SUBMITTED; r = DM_MAPIO_SUBMITTED;
...@@ -1677,6 +1680,11 @@ static int multipath_busy(struct dm_target *ti) ...@@ -1677,6 +1680,11 @@ static int multipath_busy(struct dm_target *ti)
spin_lock_irqsave(&m->lock, flags); spin_lock_irqsave(&m->lock, flags);
/* pg_init in progress, requeue until done */
if (m->pg_init_in_progress) {
busy = 1;
goto out;
}
/* Guess which priority_group will be used at next mapping time */ /* Guess which priority_group will be used at next mapping time */
if (unlikely(!m->current_pgpath && m->next_pg)) if (unlikely(!m->current_pgpath && m->next_pg))
pg = m->next_pg; pg = m->next_pg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment