mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
dm: fix IO splitting
Commit882ec4e609
("dm table: stack 'chunk_sectors' limit to account for target-specific splitting") caused a couple regressions: 1) Using lcm_not_zero() when stacking chunk_sectors was a bug because chunk_sectors must reflect the most limited of all devices in the IO stack. 2) DM targets that set max_io_len but that do _not_ provide an .iterate_devices method no longer had there IO split properly. And commit5091cdec56
("dm: change max_io_len() to use blk_max_size_offset()") also caused a regression where DM no longer supported varied (per target) IO splitting. The implication being the potential for severely reduced performance for IO stacks that use a DM target like dm-cache to hide performance limitations of a slower device (e.g. one that requires 4K IO splitting). Coming full circle: Fix all these issues by discontinuing stacking chunk_sectors up using ti->max_io_len in dm_calculate_queue_limits(), add optional chunk_sectors override argument to blk_max_size_offset() and update DM's max_io_len() to pass ti->max_io_len to its blk_max_size_offset() call. Passing in an optional chunk_sectors override to blk_max_size_offset() allows for code reuse of block's centralized calculation for max IO size based on provided offset and split boundary. Fixes:882ec4e609
("dm table: stack 'chunk_sectors' limit to account for target-specific splitting") Fixes:5091cdec56
("dm: change max_io_len() to use blk_max_size_offset()") Cc: stable@vger.kernel.org Reported-by: John Dorminy <jdorminy@redhat.com> Reported-by: Bruce Johnston <bjohnsto@redhat.com> Reported-by: Kirill Tkhai <ktkhai@virtuozzo.com> Reviewed-by: John Dorminy <jdorminy@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Reviewed-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
@@ -1073,11 +1073,12 @@ static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q,
|
||||
* file system requests.
|
||||
*/
|
||||
static inline unsigned int blk_max_size_offset(struct request_queue *q,
|
||||
sector_t offset)
|
||||
sector_t offset,
|
||||
unsigned int chunk_sectors)
|
||||
{
|
||||
unsigned int chunk_sectors = q->limits.chunk_sectors;
|
||||
|
||||
if (!chunk_sectors)
|
||||
if (!chunk_sectors && q->limits.chunk_sectors)
|
||||
chunk_sectors = q->limits.chunk_sectors;
|
||||
else
|
||||
return q->limits.max_sectors;
|
||||
|
||||
if (likely(is_power_of_2(chunk_sectors)))
|
||||
@@ -1101,7 +1102,7 @@ static inline unsigned int blk_rq_get_max_sectors(struct request *rq,
|
||||
req_op(rq) == REQ_OP_SECURE_ERASE)
|
||||
return blk_queue_get_max_sectors(q, req_op(rq));
|
||||
|
||||
return min(blk_max_size_offset(q, offset),
|
||||
return min(blk_max_size_offset(q, offset, 0),
|
||||
blk_queue_get_max_sectors(q, req_op(rq)));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user