diff options
author | Yufen Yu <yuyufen@huawei.com> | 2019-04-24 23:19:05 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-09-16 08:22:12 +0200 |
commit | 69409854ba08d3aeb28a3989703381857842e2ab (patch) | |
tree | 451393411a5a9230d437b9e8388d742fc7c84bb7 /include | |
parent | 0fe097012b6ca7d5103eb6905ff6a2b640c78f67 (diff) | |
download | linux-stable-69409854ba08d3aeb28a3989703381857842e2ab.tar.gz linux-stable-69409854ba08d3aeb28a3989703381857842e2ab.tar.bz2 linux-stable-69409854ba08d3aeb28a3989703381857842e2ab.zip |
dm mpath: fix missing call of path selector type->end_io
[ Upstream commit 5de719e3d01b4abe0de0d7b857148a880ff2a90b ]
After commit 396eaf21ee17 ("blk-mq: improve DM's blk-mq IO merging via
blk_insert_cloned_request feedback"), map_request() will requeue the tio
when issued clone request return BLK_STS_RESOURCE or BLK_STS_DEV_RESOURCE.
Thus, if device driver status is error, a tio may be requeued multiple
times until the return value is not DM_MAPIO_REQUEUE. That means
type->start_io may be called multiple times, while type->end_io is only
called when IO complete.
In fact, even without commit 396eaf21ee17, setup_clone() failure can
also cause tio requeue and associated missed call to type->end_io.
The service-time path selector selects path based on in_flight_size,
which is increased by st_start_io() and decreased by st_end_io().
Missed calls to st_end_io() can lead to in_flight_size count error and
will cause the selector to make the wrong choice. In addition,
queue-length path selector will also be affected.
To fix the problem, call type->end_io in ->release_clone_rq before tio
requeue. map_info is passed to ->release_clone_rq() for map_request()
error path that result in requeue.
Fixes: 396eaf21ee17 ("blk-mq: improve DM's blk-mq IO merging via blk_insert_cloned_request feedback")
Cc: stable@vger.kernl.org
Signed-off-by: Yufen Yu <yuyufen@huawei.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/device-mapper.h | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index bef2e36c01b4..91f9f95ad506 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -62,7 +62,8 @@ typedef int (*dm_clone_and_map_request_fn) (struct dm_target *ti, struct request *rq, union map_info *map_context, struct request **clone); -typedef void (*dm_release_clone_request_fn) (struct request *clone); +typedef void (*dm_release_clone_request_fn) (struct request *clone, + union map_info *map_context); /* * Returns: |