summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-02-04 14:16:35 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-02-04 14:16:35 -0500
commit64b28683deba132f301d1cecfc25c32e295f53a1 (patch)
treebe38a4e77c530fb129339f983a9d307c60312df8 /block
parentd3658c2266012f270da52e3e0365536e394bd3bd (diff)
parent1d51877578799bfe0fcfe189d8233c9fccf05931 (diff)
Merge tag 'for-linus-20180204' of git://git.kernel.dk/linux-block
Pull more block updates from Jens Axboe: "Most of this is fixes and not new code/features: - skd fix from Arnd, fixing a build error dependent on sla allocator type. - blk-mq scheduler discard merging fixes, one from me and one from Keith. This fixes a segment miscalculation for blk-mq-sched, where we mistakenly think two segments are physically contigious even though the request isn't carrying real data. Also fixes a bio-to-rq merge case. - Don't re-set a bit on the buffer_head flags, if it's already set. This can cause scalability concerns on bigger machines and workloads. From Kemi Wang. - Add BLK_STS_DEV_RESOURCE return value to blk-mq, allowing us to distuingish between a local (device related) resource starvation and a global one. The latter might happen without IO being in flight, so it has to be handled a bit differently. From Ming" * tag 'for-linus-20180204' of git://git.kernel.dk/linux-block: block: skd: fix incorrect linux/slab_def.h inclusion buffer: Avoid setting buffer bits that are already set blk-mq-sched: Enable merging discard bio into request blk-mq: fix discard merge with scheduler attached blk-mq: introduce BLK_STS_DEV_RESOURCE
Diffstat (limited to 'block')
-rw-r--r--block/blk-core.c3
-rw-r--r--block/blk-merge.c29
-rw-r--r--block/blk-mq-sched.c2
-rw-r--r--block/blk-mq.c20
4 files changed, 47 insertions, 7 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index a2005a485335..d0d104268f1a 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -145,6 +145,7 @@ static const struct {
145 [BLK_STS_MEDIUM] = { -ENODATA, "critical medium" }, 145 [BLK_STS_MEDIUM] = { -ENODATA, "critical medium" },
146 [BLK_STS_PROTECTION] = { -EILSEQ, "protection" }, 146 [BLK_STS_PROTECTION] = { -EILSEQ, "protection" },
147 [BLK_STS_RESOURCE] = { -ENOMEM, "kernel resource" }, 147 [BLK_STS_RESOURCE] = { -ENOMEM, "kernel resource" },
148 [BLK_STS_DEV_RESOURCE] = { -EBUSY, "device resource" },
148 [BLK_STS_AGAIN] = { -EAGAIN, "nonblocking retry" }, 149 [BLK_STS_AGAIN] = { -EAGAIN, "nonblocking retry" },
149 150
150 /* device mapper special case, should not leak out: */ 151 /* device mapper special case, should not leak out: */
@@ -3282,6 +3283,8 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
3282{ 3283{
3283 if (bio_has_data(bio)) 3284 if (bio_has_data(bio))
3284 rq->nr_phys_segments = bio_phys_segments(q, bio); 3285 rq->nr_phys_segments = bio_phys_segments(q, bio);
3286 else if (bio_op(bio) == REQ_OP_DISCARD)
3287 rq->nr_phys_segments = 1;
3285 3288
3286 rq->__data_len = bio->bi_iter.bi_size; 3289 rq->__data_len = bio->bi_iter.bi_size;
3287 rq->bio = rq->biotail = bio; 3290 rq->bio = rq->biotail = bio;
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 8452fc7164cc..782940c65d8a 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -550,6 +550,24 @@ static bool req_no_special_merge(struct request *req)
550 return !q->mq_ops && req->special; 550 return !q->mq_ops && req->special;
551} 551}
552 552
553static bool req_attempt_discard_merge(struct request_queue *q, struct request *req,
554 struct request *next)
555{
556 unsigned short segments = blk_rq_nr_discard_segments(req);
557
558 if (segments >= queue_max_discard_segments(q))
559 goto no_merge;
560 if (blk_rq_sectors(req) + bio_sectors(next->bio) >
561 blk_rq_get_max_sectors(req, blk_rq_pos(req)))
562 goto no_merge;
563
564 req->nr_phys_segments = segments + blk_rq_nr_discard_segments(next);
565 return true;
566no_merge:
567 req_set_nomerge(q, req);
568 return false;
569}
570
553static int ll_merge_requests_fn(struct request_queue *q, struct request *req, 571static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
554 struct request *next) 572 struct request *next)
555{ 573{
@@ -683,9 +701,13 @@ static struct request *attempt_merge(struct request_queue *q,
683 * If we are allowed to merge, then append bio list 701 * If we are allowed to merge, then append bio list
684 * from next to rq and release next. merge_requests_fn 702 * from next to rq and release next. merge_requests_fn
685 * will have updated segment counts, update sector 703 * will have updated segment counts, update sector
686 * counts here. 704 * counts here. Handle DISCARDs separately, as they
705 * have separate settings.
687 */ 706 */
688 if (!ll_merge_requests_fn(q, req, next)) 707 if (req_op(req) == REQ_OP_DISCARD) {
708 if (!req_attempt_discard_merge(q, req, next))
709 return NULL;
710 } else if (!ll_merge_requests_fn(q, req, next))
689 return NULL; 711 return NULL;
690 712
691 /* 713 /*
@@ -715,7 +737,8 @@ static struct request *attempt_merge(struct request_queue *q,
715 737
716 req->__data_len += blk_rq_bytes(next); 738 req->__data_len += blk_rq_bytes(next);
717 739
718 elv_merge_requests(q, req, next); 740 if (req_op(req) != REQ_OP_DISCARD)
741 elv_merge_requests(q, req, next);
719 742
720 /* 743 /*
721 * 'next' is going away, so update stats accordingly 744 * 'next' is going away, so update stats accordingly
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 55c0a745b427..25c14c58385c 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -259,6 +259,8 @@ bool blk_mq_sched_try_merge(struct request_queue *q, struct bio *bio,
259 if (!*merged_request) 259 if (!*merged_request)
260 elv_merged_request(q, rq, ELEVATOR_FRONT_MERGE); 260 elv_merged_request(q, rq, ELEVATOR_FRONT_MERGE);
261 return true; 261 return true;
262 case ELEVATOR_DISCARD_MERGE:
263 return bio_attempt_discard_merge(q, rq, bio);
262 default: 264 default:
263 return false; 265 return false;
264 } 266 }
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 01f271d40825..df93102e2149 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1162,6 +1162,8 @@ static bool blk_mq_mark_tag_wait(struct blk_mq_hw_ctx **hctx,
1162 return true; 1162 return true;
1163} 1163}
1164 1164
1165#define BLK_MQ_RESOURCE_DELAY 3 /* ms units */
1166
1165bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list, 1167bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list,
1166 bool got_budget) 1168 bool got_budget)
1167{ 1169{
@@ -1169,6 +1171,7 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list,
1169 struct request *rq, *nxt; 1171 struct request *rq, *nxt;
1170 bool no_tag = false; 1172 bool no_tag = false;
1171 int errors, queued; 1173 int errors, queued;
1174 blk_status_t ret = BLK_STS_OK;
1172 1175
1173 if (list_empty(list)) 1176 if (list_empty(list))
1174 return false; 1177 return false;
@@ -1181,7 +1184,6 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list,
1181 errors = queued = 0; 1184 errors = queued = 0;
1182 do { 1185 do {
1183 struct blk_mq_queue_data bd; 1186 struct blk_mq_queue_data bd;
1184 blk_status_t ret;
1185 1187
1186 rq = list_first_entry(list, struct request, queuelist); 1188 rq = list_first_entry(list, struct request, queuelist);
1187 if (!blk_mq_get_driver_tag(rq, &hctx, false)) { 1189 if (!blk_mq_get_driver_tag(rq, &hctx, false)) {
@@ -1226,7 +1228,7 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list,
1226 } 1228 }
1227 1229
1228 ret = q->mq_ops->queue_rq(hctx, &bd); 1230 ret = q->mq_ops->queue_rq(hctx, &bd);
1229 if (ret == BLK_STS_RESOURCE) { 1231 if (ret == BLK_STS_RESOURCE || ret == BLK_STS_DEV_RESOURCE) {
1230 /* 1232 /*
1231 * If an I/O scheduler has been configured and we got a 1233 * If an I/O scheduler has been configured and we got a
1232 * driver tag for the next request already, free it 1234 * driver tag for the next request already, free it
@@ -1257,6 +1259,8 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list,
1257 * that is where we will continue on next queue run. 1259 * that is where we will continue on next queue run.
1258 */ 1260 */
1259 if (!list_empty(list)) { 1261 if (!list_empty(list)) {
1262 bool needs_restart;
1263
1260 spin_lock(&hctx->lock); 1264 spin_lock(&hctx->lock);
1261 list_splice_init(list, &hctx->dispatch); 1265 list_splice_init(list, &hctx->dispatch);
1262 spin_unlock(&hctx->lock); 1266 spin_unlock(&hctx->lock);
@@ -1280,10 +1284,17 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list,
1280 * - Some but not all block drivers stop a queue before 1284 * - Some but not all block drivers stop a queue before
1281 * returning BLK_STS_RESOURCE. Two exceptions are scsi-mq 1285 * returning BLK_STS_RESOURCE. Two exceptions are scsi-mq
1282 * and dm-rq. 1286 * and dm-rq.
1287 *
1288 * If driver returns BLK_STS_RESOURCE and SCHED_RESTART
1289 * bit is set, run queue after a delay to avoid IO stalls
1290 * that could otherwise occur if the queue is idle.
1283 */ 1291 */
1284 if (!blk_mq_sched_needs_restart(hctx) || 1292 needs_restart = blk_mq_sched_needs_restart(hctx);
1293 if (!needs_restart ||
1285 (no_tag && list_empty_careful(&hctx->dispatch_wait.entry))) 1294 (no_tag && list_empty_careful(&hctx->dispatch_wait.entry)))
1286 blk_mq_run_hw_queue(hctx, true); 1295 blk_mq_run_hw_queue(hctx, true);
1296 else if (needs_restart && (ret == BLK_STS_RESOURCE))
1297 blk_mq_delay_run_hw_queue(hctx, BLK_MQ_RESOURCE_DELAY);
1287 } 1298 }
1288 1299
1289 return (queued + errors) != 0; 1300 return (queued + errors) != 0;
@@ -1764,6 +1775,7 @@ static blk_status_t __blk_mq_issue_directly(struct blk_mq_hw_ctx *hctx,
1764 *cookie = new_cookie; 1775 *cookie = new_cookie;
1765 break; 1776 break;
1766 case BLK_STS_RESOURCE: 1777 case BLK_STS_RESOURCE:
1778 case BLK_STS_DEV_RESOURCE:
1767 __blk_mq_requeue_request(rq); 1779 __blk_mq_requeue_request(rq);
1768 break; 1780 break;
1769 default: 1781 default:
@@ -1826,7 +1838,7 @@ static void blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx,
1826 hctx_lock(hctx, &srcu_idx); 1838 hctx_lock(hctx, &srcu_idx);
1827 1839
1828 ret = __blk_mq_try_issue_directly(hctx, rq, cookie, false); 1840 ret = __blk_mq_try_issue_directly(hctx, rq, cookie, false);
1829 if (ret == BLK_STS_RESOURCE) 1841 if (ret == BLK_STS_RESOURCE || ret == BLK_STS_DEV_RESOURCE)
1830 blk_mq_sched_insert_request(rq, false, true, false); 1842 blk_mq_sched_insert_request(rq, false, true, false);
1831 else if (ret != BLK_STS_OK) 1843 else if (ret != BLK_STS_OK)
1832 blk_mq_end_request(rq, ret); 1844 blk_mq_end_request(rq, ret);