summaryrefslogtreecommitdiff
path: root/drivers/md
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2014-02-28 15:33:46 +0100
committerMike Snitzer <snitzer@redhat.com>2014-03-27 16:56:25 -0400
commite3bde04f1ecef9d0508af9ea78421863744f552b (patch)
tree848d74aa7167c665e5a828e70f2ad12f11d5df77 /drivers/md
parent3e9f1be1b4079bfe689ef6be5174f3177b3fd2aa (diff)
dm mpath: reduce memory pressure when requeuing
When multipath needs to requeue I/O in the block layer the per-request context shouldn't be allocated, as it will be freed immediately afterwards anyway. Avoiding this memory allocation will reduce memory pressure during requeuing. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Reviewed-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-mpath.c38
1 files changed, 15 insertions, 23 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 1c6a3f8da24d..2c2c33f24998 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -378,12 +378,12 @@ static int __must_push_back(struct multipath *m)
static int map_io(struct multipath *m, struct request *clone,
union map_info *map_context)
{
- int r = DM_MAPIO_REMAPPED;
+ int r = DM_MAPIO_REQUEUE;
size_t nr_bytes = blk_rq_bytes(clone);
unsigned long flags;
struct pgpath *pgpath;
struct block_device *bdev;
- struct dm_mpath_io *mpio = map_context->ptr;
+ struct dm_mpath_io *mpio;
spin_lock_irqsave(&m->lock, flags);
@@ -396,27 +396,29 @@ static int map_io(struct multipath *m, struct request *clone,
if (pgpath) {
if (pg_ready(m)) {
+ if (set_mapinfo(m, map_context) < 0)
+ /* ENOMEM, requeue */
+ goto out_unlock;
+
bdev = pgpath->path.dev->bdev;
clone->q = bdev_get_queue(bdev);
clone->rq_disk = bdev->bd_disk;
+ clone->cmd_flags |= REQ_FAILFAST_TRANSPORT;
+ mpio = map_context->ptr;
mpio->pgpath = pgpath;
mpio->nr_bytes = nr_bytes;
if (pgpath->pg->ps.type->start_io)
pgpath->pg->ps.type->start_io(&pgpath->pg->ps,
&pgpath->path,
nr_bytes);
- } else {
- __pg_init_all_paths(m);
- r = DM_MAPIO_REQUEUE;
+ r = DM_MAPIO_REMAPPED;
+ goto out_unlock;
}
- } else {
- /* No path */
- if (__must_push_back(m))
- r = DM_MAPIO_REQUEUE;
- else
- r = -EIO; /* Failed */
- }
+ __pg_init_all_paths(m);
+ } else if (!__must_push_back(m))
+ r = -EIO; /* Failed */
+out_unlock:
spin_unlock_irqrestore(&m->lock, flags);
return r;
@@ -912,19 +914,9 @@ static void multipath_dtr(struct dm_target *ti)
static int multipath_map(struct dm_target *ti, struct request *clone,
union map_info *map_context)
{
- int r;
struct multipath *m = (struct multipath *) ti->private;
- if (set_mapinfo(m, map_context) < 0)
- /* ENOMEM, requeue */
- return DM_MAPIO_REQUEUE;
-
- clone->cmd_flags |= REQ_FAILFAST_TRANSPORT;
- r = map_io(m, clone, map_context);
- if (r < 0 || r == DM_MAPIO_REQUEUE)
- clear_mapinfo(m, map_context);
-
- return r;
+ return map_io(m, clone, map_context);
}
/*