diff options
| author | Dmitry Shmidt <dimitrysh@google.com> | 2016-09-16 14:34:07 -0700 |
|---|---|---|
| committer | Dmitry Shmidt <dimitrysh@google.com> | 2016-09-16 14:34:07 -0700 |
| commit | a517d900c6b4996dd6a6ba2f600dabe1c4da717a (patch) | |
| tree | ceb85027033fa99487deb1da5e8fa5ddddb92823 /block | |
| parent | 441e10ac4ca3a476d76091a1bd250ac4ff7306c5 (diff) | |
| parent | 1d074db69c46d62ce82b331c2080e2fcb710bf4a (diff) | |
Merge tag 'v4.4.21' into android-4.4.y
This is the 4.4.21 stable release
Change-Id: I03e47d6fdca8084641c4b4f9658ea0b0edb8f297
Diffstat (limited to 'block')
| -rw-r--r-- | block/blk-core.c | 4 | ||||
| -rw-r--r-- | block/blk-merge.c | 22 | ||||
| -rw-r--r-- | block/blk-mq.c | 6 |
3 files changed, 29 insertions, 3 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 32e5bd63f6ae..25f25271b42a 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -517,7 +517,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 6d6f8feb48c0..839b1e17481b 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -601,8 +601,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) |
