diff options
author | Hannes Reinecke <hare@suse.de> | 2014-02-28 14:33:46 (GMT) |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2014-03-27 20:56:25 (GMT) |
commit | e3bde04f1ecef9d0508af9ea78421863744f552b (patch) | |
tree | 848d74aa7167c665e5a828e70f2ad12f11d5df77 | |
parent | 3e9f1be1b4079bfe689ef6be5174f3177b3fd2aa (diff) | |
download | linux-e3bde04f1ecef9d0508af9ea78421863744f552b.tar.xz |
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>
-rw-r--r-- | drivers/md/dm-mpath.c | 38 |
1 files changed, 15 insertions, 23 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 1c6a3f8..2c2c33f 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); } /* |