aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2014-02-28 09:33:46 -0500
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)
378static int map_io(struct multipath *m, struct request *clone, 378static int map_io(struct multipath *m, struct request *clone,
379 union map_info *map_context) 379 union map_info *map_context)
380{ 380{
381 int r = DM_MAPIO_REMAPPED; 381 int r = DM_MAPIO_REQUEUE;
382 size_t nr_bytes = blk_rq_bytes(clone); 382 size_t nr_bytes = blk_rq_bytes(clone);
383 unsigned long flags; 383 unsigned long flags;
384 struct pgpath *pgpath; 384 struct pgpath *pgpath;
385 struct block_device *bdev; 385 struct block_device *bdev;
386 struct dm_mpath_io *mpio = map_context->ptr; 386 struct dm_mpath_io *mpio;
387 387
388 spin_lock_irqsave(&m->lock, flags); 388 spin_lock_irqsave(&m->lock, flags);
389 389
@@ -396,27 +396,29 @@ static int map_io(struct multipath *m, struct request *clone,
396 396
397 if (pgpath) { 397 if (pgpath) {
398 if (pg_ready(m)) { 398 if (pg_ready(m)) {
399 if (set_mapinfo(m, map_context) < 0)
400 /* ENOMEM, requeue */
401 goto out_unlock;
402
399 bdev = pgpath->path.dev->bdev; 403 bdev = pgpath->path.dev->bdev;
400 clone->q = bdev_get_queue(bdev); 404 clone->q = bdev_get_queue(bdev);
401 clone->rq_disk = bdev->bd_disk; 405 clone->rq_disk = bdev->bd_disk;
406 clone->cmd_flags |= REQ_FAILFAST_TRANSPORT;
407 mpio = map_context->ptr;
402 mpio->pgpath = pgpath; 408 mpio->pgpath = pgpath;
403 mpio->nr_bytes = nr_bytes; 409 mpio->nr_bytes = nr_bytes;
404 if (pgpath->pg->ps.type->start_io) 410 if (pgpath->pg->ps.type->start_io)
405 pgpath->pg->ps.type->start_io(&pgpath->pg->ps, 411 pgpath->pg->ps.type->start_io(&pgpath->pg->ps,
406 &pgpath->path, 412 &pgpath->path,
407 nr_bytes); 413 nr_bytes);
408 } else { 414 r = DM_MAPIO_REMAPPED;
409 __pg_init_all_paths(m); 415 goto out_unlock;
410 r = DM_MAPIO_REQUEUE;
411 } 416 }
412 } else { 417 __pg_init_all_paths(m);
413 /* No path */ 418 } else if (!__must_push_back(m))
414 if (__must_push_back(m)) 419 r = -EIO; /* Failed */
415 r = DM_MAPIO_REQUEUE;
416 else
417 r = -EIO; /* Failed */
418 }
419 420
421out_unlock:
420 spin_unlock_irqrestore(&m->lock, flags); 422 spin_unlock_irqrestore(&m->lock, flags);
421 423
422 return r; 424 return r;
@@ -912,19 +914,9 @@ static void multipath_dtr(struct dm_target *ti)
912static int multipath_map(struct dm_target *ti, struct request *clone, 914static int multipath_map(struct dm_target *ti, struct request *clone,
913 union map_info *map_context) 915 union map_info *map_context)
914{ 916{
915 int r;
916 struct multipath *m = (struct multipath *) ti->private; 917 struct multipath *m = (struct multipath *) ti->private;
917 918
918 if (set_mapinfo(m, map_context) < 0) 919 return map_io(m, clone, map_context);
919 /* ENOMEM, requeue */
920 return DM_MAPIO_REQUEUE;
921
922 clone->cmd_flags |= REQ_FAILFAST_TRANSPORT;
923 r = map_io(m, clone, map_context);
924 if (r < 0 || r == DM_MAPIO_REQUEUE)
925 clear_mapinfo(m, map_context);
926
927 return r;
928} 920}
929 921
930/* 922/*