ANDROID: block: Do not set the I/O priority for zoned writes
The I/O priority set by the ionice command or by the blk-ioprio cgroup policy may cause the mq-deadline I/O scheduler to submit zoned writes in the wrong order and hence to trigger unaligned write errors. Fix this by not applying these I/O priority policies on sequential zoned writes. Bug: 269471019 Bug: 415836627 Change-Id: I88ae04b697239f1aa27404cbf35c5a96d3a73a1f Signed-off-by: Bart Van Assche <bvanassche@google.com>
This commit is contained in:
@@ -882,8 +882,41 @@ end_io:
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(submit_bio_noacct);
|
EXPORT_SYMBOL(submit_bio_noacct);
|
||||||
|
|
||||||
|
#ifdef CONFIG_BLK_DEV_ZONED
|
||||||
|
/**
|
||||||
|
* blk_bio_is_seq_zoned_write() - Check if @bio requires write serialization.
|
||||||
|
* @bio: Bio to examine.
|
||||||
|
*
|
||||||
|
* Note: REQ_OP_ZONE_APPEND bios do not require serialization.
|
||||||
|
* Note: this function treats conventional zones on a zoned block device as
|
||||||
|
* sequential zones. This is fine since zoned UFS devices have no conventional
|
||||||
|
* zones.
|
||||||
|
*/
|
||||||
|
static bool blk_bio_is_seq_zoned_write(struct bio *bio)
|
||||||
|
{
|
||||||
|
if (!bdev_is_zoned(bio->bi_bdev))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return bio_op(bio) == REQ_OP_WRITE ||
|
||||||
|
bio_op(bio) == REQ_OP_WRITE_ZEROES;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static bool blk_bio_is_seq_zoned_write(struct bio *bio)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void bio_set_ioprio(struct bio *bio)
|
static void bio_set_ioprio(struct bio *bio)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Do not set the I/O priority of sequential zoned write bios because
|
||||||
|
* this could lead to reordering by the mq-deadline I/O scheduler and
|
||||||
|
* hence to unaligned write errors.
|
||||||
|
*/
|
||||||
|
if (blk_bio_is_seq_zoned_write(bio))
|
||||||
|
return;
|
||||||
|
|
||||||
/* Nobody set ioprio so far? Initialize it based on task's nice value */
|
/* Nobody set ioprio so far? Initialize it based on task's nice value */
|
||||||
if (IOPRIO_PRIO_CLASS(bio->bi_ioprio) == IOPRIO_CLASS_NONE)
|
if (IOPRIO_PRIO_CLASS(bio->bi_ioprio) == IOPRIO_CLASS_NONE)
|
||||||
bio->bi_ioprio = get_current_ioprio();
|
bio->bi_ioprio = get_current_ioprio();
|
||||||
|
|||||||
Reference in New Issue
Block a user