diff options
author | Alex Shi <alex.shi@linaro.org> | 2016-09-20 10:18:39 +0800 |
---|---|---|
committer | Alex Shi <alex.shi@linaro.org> | 2016-09-20 10:18:39 +0800 |
commit | fabf4bd22caee598e1227f00a85973540a545be2 (patch) | |
tree | 4b52be781698d88db9e4f2aa709c5ca8d19371c0 /block | |
parent | 7b324954a4d9bbef9d6acd7c329f6e1289c1d7cb (diff) | |
parent | d2d693d1ba7d93ec7c5db8aca2da29a4c91f6782 (diff) |
Merge branch 'linux-linaro-lsk-v4.4' into linux-linaro-lsk-v4.4-rt
Diffstat (limited to 'block')
-rw-r--r-- | block/bio.c | 15 | ||||
-rw-r--r-- | block/blk-core.c | 4 | ||||
-rw-r--r-- | block/blk-merge.c | 22 | ||||
-rw-r--r-- | block/blk-mq.c | 6 | ||||
-rw-r--r-- | block/genhd.c | 2 |
5 files changed, 45 insertions, 4 deletions
diff --git a/block/bio.c b/block/bio.c index d4d144363250..46e2cc1d4016 100644 --- a/block/bio.c +++ b/block/bio.c @@ -584,6 +584,8 @@ void __bio_clone_fast(struct bio *bio, struct bio *bio_src) bio->bi_rw = bio_src->bi_rw; bio->bi_iter = bio_src->bi_iter; bio->bi_io_vec = bio_src->bi_io_vec; + + bio_clone_blkcg_association(bio, bio_src); } EXPORT_SYMBOL(__bio_clone_fast); @@ -689,6 +691,8 @@ integrity_clone: } } + bio_clone_blkcg_association(bio, bio_src); + return bio; } EXPORT_SYMBOL(bio_clone_bioset); @@ -2014,6 +2018,17 @@ void bio_disassociate_task(struct bio *bio) } } +/** + * bio_clone_blkcg_association - clone blkcg association from src to dst bio + * @dst: destination bio + * @src: source bio + */ +void bio_clone_blkcg_association(struct bio *dst, struct bio *src) +{ + if (src->bi_css) + WARN_ON(bio_associate_blkcg(dst, src->bi_css)); +} + #endif /* CONFIG_BLK_CGROUP */ static void __init biovec_init_slabs(void) diff --git a/block/blk-core.c b/block/blk-core.c index 842cfe492cf4..52d2fe2fec8f 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -518,7 +518,9 @@ EXPORT_SYMBOL_GPL(blk_queue_bypass_end); void blk_set_queue_dying(struct request_queue *q) { - queue_flag_set_unlocked(QUEUE_FLAG_DYING, q); + spin_lock_irq(q->queue_lock); + queue_flag_set(QUEUE_FLAG_DYING, q); + spin_unlock_irq(q->queue_lock); if (q->mq_ops) blk_mq_wake_waiters(q); diff --git a/block/blk-merge.c b/block/blk-merge.c index b966db8f3556..7225511cf0b4 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -92,9 +92,31 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, bool do_split = true; struct bio *new = NULL; const unsigned max_sectors = get_max_io_size(q, bio); + unsigned bvecs = 0; bio_for_each_segment(bv, bio, iter) { /* + * With arbitrary bio size, the incoming bio may be very + * big. We have to split the bio into small bios so that + * each holds at most BIO_MAX_PAGES bvecs because + * bio_clone() can fail to allocate big bvecs. + * + * It should have been better to apply the limit per + * request queue in which bio_clone() is involved, + * instead of globally. The biggest blocker is the + * bio_clone() in bio bounce. + * + * If bio is splitted by this reason, we should have + * allowed to continue bios merging, but don't do + * that now for making the change simple. + * + * TODO: deal with bio bounce's bio_clone() gracefully + * and convert the global limit into per-queue limit. + */ + if (bvecs++ >= BIO_MAX_PAGES) + goto split; + + /* * If the queue doesn't support SG gaps and adding this * offset would create a gap, disallow it. */ diff --git a/block/blk-mq.c b/block/blk-mq.c index 7cdf19e4aaea..0e205b886246 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -621,8 +621,10 @@ static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, * If a request wasn't started before the queue was * marked dying, kill it here or it'll go unnoticed. */ - if (unlikely(blk_queue_dying(rq->q))) - blk_mq_complete_request(rq, -EIO); + if (unlikely(blk_queue_dying(rq->q))) { + rq->errors = -EIO; + blk_mq_end_request(rq, rq->errors); + } return; } if (rq->cmd_flags & REQ_NO_TIMEOUT) diff --git a/block/genhd.c b/block/genhd.c index d2a1d43bf9fa..a5bed6bc869d 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -612,7 +612,7 @@ void add_disk(struct gendisk *disk) /* Register BDI before referencing it from bdev */ bdi = &disk->queue->backing_dev_info; - bdi_register_dev(bdi, disk_devt(disk)); + bdi_register_owner(bdi, disk_to_dev(disk)); blk_register_region(disk_devt(disk), disk->minors, NULL, exact_match, exact_lock, disk); |