aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/block/queue-sysfs.txt9
-rw-r--r--block/bio.c11
-rw-r--r--block/blk-core.c5
-rw-r--r--block/blk-lib.c178
-rw-r--r--block/blk-mq-tag.c12
-rw-r--r--block/blk-mq.c5
-rw-r--r--block/blk-settings.c26
-rw-r--r--block/blk-sysfs.c39
-rw-r--r--block/blk-throttle.c5
-rw-r--r--drivers/block/skd_main.c2
-rw-r--r--drivers/scsi/sd.c2
-rw-r--r--include/linux/bio.h11
-rw-r--r--include/linux/blk-mq.h2
-rw-r--r--include/linux/blk_types.h2
-rw-r--r--include/linux/blkdev.h7
-rw-r--r--include/linux/blktrace_api.h9
-rw-r--r--kernel/trace/blktrace.c2
17 files changed, 190 insertions, 137 deletions
diff --git a/Documentation/block/queue-sysfs.txt b/Documentation/block/queue-sysfs.txt
index e5d914845be6..dce25d848d92 100644
--- a/Documentation/block/queue-sysfs.txt
+++ b/Documentation/block/queue-sysfs.txt
@@ -141,6 +141,15 @@ control of this block device to that new IO scheduler. Note that writing
141an IO scheduler name to this file will attempt to load that IO scheduler 141an IO scheduler name to this file will attempt to load that IO scheduler
142module, if it isn't already present in the system. 142module, if it isn't already present in the system.
143 143
144write_cache (RW)
145----------------
146When read, this file will display whether the device has write back
147caching enabled or not. It will return "write back" for the former
148case, and "write through" for the latter. Writing to this file can
149change the kernels view of the device, but it doesn't alter the
150device state. This means that it might not be safe to toggle the
151setting from "write back" to "write through", since that will also
152eliminate cache flushes issued by the kernel.
144 153
145 154
146Jens Axboe <jens.axboe@oracle.com>, February 2009 155Jens Axboe <jens.axboe@oracle.com>, February 2009
diff --git a/block/bio.c b/block/bio.c
index 807d25e466ec..0e4aa42bc30d 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -311,17 +311,6 @@ static void bio_chain_endio(struct bio *bio)
311 bio_endio(__bio_chain_endio(bio)); 311 bio_endio(__bio_chain_endio(bio));
312} 312}
313 313
314/*
315 * Increment chain count for the bio. Make sure the CHAIN flag update
316 * is visible before the raised count.
317 */
318static inline void bio_inc_remaining(struct bio *bio)
319{
320 bio_set_flag(bio, BIO_CHAIN);
321 smp_mb__before_atomic();
322 atomic_inc(&bio->__bi_remaining);
323}
324
325/** 314/**
326 * bio_chain - chain bio completions 315 * bio_chain - chain bio completions
327 * @bio: the target bio 316 * @bio: the target bio
diff --git a/block/blk-core.c b/block/blk-core.c
index b60537b2c35b..c50227796a26 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1523,6 +1523,7 @@ EXPORT_SYMBOL(blk_put_request);
1523 * blk_add_request_payload - add a payload to a request 1523 * blk_add_request_payload - add a payload to a request
1524 * @rq: request to update 1524 * @rq: request to update
1525 * @page: page backing the payload 1525 * @page: page backing the payload
1526 * @offset: offset in page
1526 * @len: length of the payload. 1527 * @len: length of the payload.
1527 * 1528 *
1528 * This allows to later add a payload to an already submitted request by 1529 * This allows to later add a payload to an already submitted request by
@@ -1533,12 +1534,12 @@ EXPORT_SYMBOL(blk_put_request);
1533 * discard requests should ever use it. 1534 * discard requests should ever use it.
1534 */ 1535 */
1535void blk_add_request_payload(struct request *rq, struct page *page, 1536void blk_add_request_payload(struct request *rq, struct page *page,
1536 unsigned int len) 1537 int offset, unsigned int len)
1537{ 1538{
1538 struct bio *bio = rq->bio; 1539 struct bio *bio = rq->bio;
1539 1540
1540 bio->bi_io_vec->bv_page = page; 1541 bio->bi_io_vec->bv_page = page;
1541 bio->bi_io_vec->bv_offset = 0; 1542 bio->bi_io_vec->bv_offset = offset;
1542 bio->bi_io_vec->bv_len = len; 1543 bio->bi_io_vec->bv_len = len;
1543 1544
1544 bio->bi_iter.bi_size = len; 1545 bio->bi_iter.bi_size = len;
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 9ebf65379556..23d7f301a196 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -9,82 +9,46 @@
9 9
10#include "blk.h" 10#include "blk.h"
11 11
12struct bio_batch { 12static struct bio *next_bio(struct bio *bio, int rw, unsigned int nr_pages,
13 atomic_t done; 13 gfp_t gfp)
14 int error;
15 struct completion *wait;
16};
17
18static void bio_batch_end_io(struct bio *bio)
19{ 14{
20 struct bio_batch *bb = bio->bi_private; 15 struct bio *new = bio_alloc(gfp, nr_pages);
16
17 if (bio) {
18 bio_chain(bio, new);
19 submit_bio(rw, bio);
20 }
21 21
22 if (bio->bi_error && bio->bi_error != -EOPNOTSUPP) 22 return new;
23 bb->error = bio->bi_error;
24 if (atomic_dec_and_test(&bb->done))
25 complete(bb->wait);
26 bio_put(bio);
27} 23}
28 24
29/** 25int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
30 * blkdev_issue_discard - queue a discard 26 sector_t nr_sects, gfp_t gfp_mask, int type, struct bio **biop)
31 * @bdev: blockdev to issue discard for
32 * @sector: start sector
33 * @nr_sects: number of sectors to discard
34 * @gfp_mask: memory allocation flags (for bio_alloc)
35 * @flags: BLKDEV_IFL_* flags to control behaviour
36 *
37 * Description:
38 * Issue a discard request for the sectors in question.
39 */
40int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
41 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags)
42{ 27{
43 DECLARE_COMPLETION_ONSTACK(wait);
44 struct request_queue *q = bdev_get_queue(bdev); 28 struct request_queue *q = bdev_get_queue(bdev);
45 int type = REQ_WRITE | REQ_DISCARD; 29 struct bio *bio = *biop;
46 unsigned int granularity; 30 unsigned int granularity;
47 int alignment; 31 int alignment;
48 struct bio_batch bb;
49 struct bio *bio;
50 int ret = 0;
51 struct blk_plug plug;
52 32
53 if (!q) 33 if (!q)
54 return -ENXIO; 34 return -ENXIO;
55
56 if (!blk_queue_discard(q)) 35 if (!blk_queue_discard(q))
57 return -EOPNOTSUPP; 36 return -EOPNOTSUPP;
37 if ((type & REQ_SECURE) && !blk_queue_secdiscard(q))
38 return -EOPNOTSUPP;
58 39
59 /* Zero-sector (unknown) and one-sector granularities are the same. */ 40 /* Zero-sector (unknown) and one-sector granularities are the same. */
60 granularity = max(q->limits.discard_granularity >> 9, 1U); 41 granularity = max(q->limits.discard_granularity >> 9, 1U);
61 alignment = (bdev_discard_alignment(bdev) >> 9) % granularity; 42 alignment = (bdev_discard_alignment(bdev) >> 9) % granularity;
62 43
63 if (flags & BLKDEV_DISCARD_SECURE) {
64 if (!blk_queue_secdiscard(q))
65 return -EOPNOTSUPP;
66 type |= REQ_SECURE;
67 }
68
69 atomic_set(&bb.done, 1);
70 bb.error = 0;
71 bb.wait = &wait;
72
73 blk_start_plug(&plug);
74 while (nr_sects) { 44 while (nr_sects) {
75 unsigned int req_sects; 45 unsigned int req_sects;
76 sector_t end_sect, tmp; 46 sector_t end_sect, tmp;
77 47
78 bio = bio_alloc(gfp_mask, 1);
79 if (!bio) {
80 ret = -ENOMEM;
81 break;
82 }
83
84 /* Make sure bi_size doesn't overflow */ 48 /* Make sure bi_size doesn't overflow */
85 req_sects = min_t(sector_t, nr_sects, UINT_MAX >> 9); 49 req_sects = min_t(sector_t, nr_sects, UINT_MAX >> 9);
86 50
87 /* 51 /**
88 * If splitting a request, and the next starting sector would be 52 * If splitting a request, and the next starting sector would be
89 * misaligned, stop the discard at the previous aligned sector. 53 * misaligned, stop the discard at the previous aligned sector.
90 */ 54 */
@@ -98,18 +62,14 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
98 req_sects = end_sect - sector; 62 req_sects = end_sect - sector;
99 } 63 }
100 64
65 bio = next_bio(bio, type, 1, gfp_mask);
101 bio->bi_iter.bi_sector = sector; 66 bio->bi_iter.bi_sector = sector;
102 bio->bi_end_io = bio_batch_end_io;
103 bio->bi_bdev = bdev; 67 bio->bi_bdev = bdev;
104 bio->bi_private = &bb;
105 68
106 bio->bi_iter.bi_size = req_sects << 9; 69 bio->bi_iter.bi_size = req_sects << 9;
107 nr_sects -= req_sects; 70 nr_sects -= req_sects;
108 sector = end_sect; 71 sector = end_sect;
109 72
110 atomic_inc(&bb.done);
111 submit_bio(type, bio);
112
113 /* 73 /*
114 * We can loop for a long time in here, if someone does 74 * We can loop for a long time in here, if someone does
115 * full device discards (like mkfs). Be nice and allow 75 * full device discards (like mkfs). Be nice and allow
@@ -118,14 +78,44 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
118 */ 78 */
119 cond_resched(); 79 cond_resched();
120 } 80 }
121 blk_finish_plug(&plug);
122 81
123 /* Wait for bios in-flight */ 82 *biop = bio;
124 if (!atomic_dec_and_test(&bb.done)) 83 return 0;
125 wait_for_completion_io(&wait); 84}
85EXPORT_SYMBOL(__blkdev_issue_discard);
86
87/**
88 * blkdev_issue_discard - queue a discard
89 * @bdev: blockdev to issue discard for
90 * @sector: start sector
91 * @nr_sects: number of sectors to discard
92 * @gfp_mask: memory allocation flags (for bio_alloc)
93 * @flags: BLKDEV_IFL_* flags to control behaviour
94 *
95 * Description:
96 * Issue a discard request for the sectors in question.
97 */
98int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
99 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags)
100{
101 int type = REQ_WRITE | REQ_DISCARD;
102 struct bio *bio = NULL;
103 struct blk_plug plug;
104 int ret;
105
106 if (flags & BLKDEV_DISCARD_SECURE)
107 type |= REQ_SECURE;
108
109 blk_start_plug(&plug);
110 ret = __blkdev_issue_discard(bdev, sector, nr_sects, gfp_mask, type,
111 &bio);
112 if (!ret && bio) {
113 ret = submit_bio_wait(type, bio);
114 if (ret == -EOPNOTSUPP)
115 ret = 0;
116 }
117 blk_finish_plug(&plug);
126 118
127 if (bb.error)
128 return bb.error;
129 return ret; 119 return ret;
130} 120}
131EXPORT_SYMBOL(blkdev_issue_discard); 121EXPORT_SYMBOL(blkdev_issue_discard);
@@ -145,11 +135,9 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
145 sector_t nr_sects, gfp_t gfp_mask, 135 sector_t nr_sects, gfp_t gfp_mask,
146 struct page *page) 136 struct page *page)
147{ 137{
148 DECLARE_COMPLETION_ONSTACK(wait);
149 struct request_queue *q = bdev_get_queue(bdev); 138 struct request_queue *q = bdev_get_queue(bdev);
150 unsigned int max_write_same_sectors; 139 unsigned int max_write_same_sectors;
151 struct bio_batch bb; 140 struct bio *bio = NULL;
152 struct bio *bio;
153 int ret = 0; 141 int ret = 0;
154 142
155 if (!q) 143 if (!q)
@@ -158,21 +146,10 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
158 /* Ensure that max_write_same_sectors doesn't overflow bi_size */ 146 /* Ensure that max_write_same_sectors doesn't overflow bi_size */
159 max_write_same_sectors = UINT_MAX >> 9; 147 max_write_same_sectors = UINT_MAX >> 9;
160 148
161 atomic_set(&bb.done, 1);
162 bb.error = 0;
163 bb.wait = &wait;
164
165 while (nr_sects) { 149 while (nr_sects) {
166 bio = bio_alloc(gfp_mask, 1); 150 bio = next_bio(bio, REQ_WRITE | REQ_WRITE_SAME, 1, gfp_mask);
167 if (!bio) {
168 ret = -ENOMEM;
169 break;
170 }
171
172 bio->bi_iter.bi_sector = sector; 151 bio->bi_iter.bi_sector = sector;
173 bio->bi_end_io = bio_batch_end_io;
174 bio->bi_bdev = bdev; 152 bio->bi_bdev = bdev;
175 bio->bi_private = &bb;
176 bio->bi_vcnt = 1; 153 bio->bi_vcnt = 1;
177 bio->bi_io_vec->bv_page = page; 154 bio->bi_io_vec->bv_page = page;
178 bio->bi_io_vec->bv_offset = 0; 155 bio->bi_io_vec->bv_offset = 0;
@@ -186,18 +163,11 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
186 bio->bi_iter.bi_size = nr_sects << 9; 163 bio->bi_iter.bi_size = nr_sects << 9;
187 nr_sects = 0; 164 nr_sects = 0;
188 } 165 }
189
190 atomic_inc(&bb.done);
191 submit_bio(REQ_WRITE | REQ_WRITE_SAME, bio);
192 } 166 }
193 167
194 /* Wait for bios in-flight */ 168 if (bio)
195 if (!atomic_dec_and_test(&bb.done)) 169 ret = submit_bio_wait(REQ_WRITE | REQ_WRITE_SAME, bio);
196 wait_for_completion_io(&wait); 170 return ret != -EOPNOTSUPP ? ret : 0;
197
198 if (bb.error)
199 return bb.error;
200 return ret;
201} 171}
202EXPORT_SYMBOL(blkdev_issue_write_same); 172EXPORT_SYMBOL(blkdev_issue_write_same);
203 173
@@ -216,28 +186,15 @@ static int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
216 sector_t nr_sects, gfp_t gfp_mask) 186 sector_t nr_sects, gfp_t gfp_mask)
217{ 187{
218 int ret; 188 int ret;
219 struct bio *bio; 189 struct bio *bio = NULL;
220 struct bio_batch bb;
221 unsigned int sz; 190 unsigned int sz;
222 DECLARE_COMPLETION_ONSTACK(wait);
223
224 atomic_set(&bb.done, 1);
225 bb.error = 0;
226 bb.wait = &wait;
227 191
228 ret = 0;
229 while (nr_sects != 0) { 192 while (nr_sects != 0) {
230 bio = bio_alloc(gfp_mask, 193 bio = next_bio(bio, WRITE,
231 min(nr_sects, (sector_t)BIO_MAX_PAGES)); 194 min(nr_sects, (sector_t)BIO_MAX_PAGES),
232 if (!bio) { 195 gfp_mask);
233 ret = -ENOMEM;
234 break;
235 }
236
237 bio->bi_iter.bi_sector = sector; 196 bio->bi_iter.bi_sector = sector;
238 bio->bi_bdev = bdev; 197 bio->bi_bdev = bdev;
239 bio->bi_end_io = bio_batch_end_io;
240 bio->bi_private = &bb;
241 198
242 while (nr_sects != 0) { 199 while (nr_sects != 0) {
243 sz = min((sector_t) PAGE_SIZE >> 9 , nr_sects); 200 sz = min((sector_t) PAGE_SIZE >> 9 , nr_sects);
@@ -247,18 +204,11 @@ static int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
247 if (ret < (sz << 9)) 204 if (ret < (sz << 9))
248 break; 205 break;
249 } 206 }
250 ret = 0;
251 atomic_inc(&bb.done);
252 submit_bio(WRITE, bio);
253 } 207 }
254 208
255 /* Wait for bios in-flight */ 209 if (bio)
256 if (!atomic_dec_and_test(&bb.done)) 210 return submit_bio_wait(WRITE, bio);
257 wait_for_completion_io(&wait); 211 return 0;
258
259 if (bb.error)
260 return bb.error;
261 return ret;
262} 212}
263 213
264/** 214/**
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
index abdbb47405cb..2fd04286f103 100644
--- a/block/blk-mq-tag.c
+++ b/block/blk-mq-tag.c
@@ -474,6 +474,18 @@ void blk_mq_all_tag_busy_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn,
474} 474}
475EXPORT_SYMBOL(blk_mq_all_tag_busy_iter); 475EXPORT_SYMBOL(blk_mq_all_tag_busy_iter);
476 476
477void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset,
478 busy_tag_iter_fn *fn, void *priv)
479{
480 int i;
481
482 for (i = 0; i < tagset->nr_hw_queues; i++) {
483 if (tagset->tags && tagset->tags[i])
484 blk_mq_all_tag_busy_iter(tagset->tags[i], fn, priv);
485 }
486}
487EXPORT_SYMBOL(blk_mq_tagset_busy_iter);
488
477void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn, 489void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn,
478 void *priv) 490 void *priv)
479{ 491{
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 1699baf39b78..7df9c9263b21 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1122,8 +1122,7 @@ static void blk_mq_bio_to_request(struct request *rq, struct bio *bio)
1122{ 1122{
1123 init_request_from_bio(rq, bio); 1123 init_request_from_bio(rq, bio);
1124 1124
1125 if (blk_do_io_stat(rq)) 1125 blk_account_io_start(rq, 1);
1126 blk_account_io_start(rq, 1);
1127} 1126}
1128 1127
1129static inline bool hctx_allow_merges(struct blk_mq_hw_ctx *hctx) 1128static inline bool hctx_allow_merges(struct blk_mq_hw_ctx *hctx)
@@ -1496,7 +1495,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set,
1496 int to_do; 1495 int to_do;
1497 void *p; 1496 void *p;
1498 1497
1499 while (left < order_to_size(this_order - 1) && this_order) 1498 while (this_order && left < order_to_size(this_order - 1))
1500 this_order--; 1499 this_order--;
1501 1500
1502 do { 1501 do {
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 331e4eee0dda..c903bee43cf8 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -846,6 +846,32 @@ void blk_queue_flush_queueable(struct request_queue *q, bool queueable)
846} 846}
847EXPORT_SYMBOL_GPL(blk_queue_flush_queueable); 847EXPORT_SYMBOL_GPL(blk_queue_flush_queueable);
848 848
849/**
850 * blk_queue_write_cache - configure queue's write cache
851 * @q: the request queue for the device
852 * @wc: write back cache on or off
853 * @fua: device supports FUA writes, if true
854 *
855 * Tell the block layer about the write cache of @q.
856 */
857void blk_queue_write_cache(struct request_queue *q, bool wc, bool fua)
858{
859 spin_lock_irq(q->queue_lock);
860 if (wc) {
861 queue_flag_set(QUEUE_FLAG_WC, q);
862 q->flush_flags = REQ_FLUSH;
863 } else
864 queue_flag_clear(QUEUE_FLAG_WC, q);
865 if (fua) {
866 if (wc)
867 q->flush_flags |= REQ_FUA;
868 queue_flag_set(QUEUE_FLAG_FUA, q);
869 } else
870 queue_flag_clear(QUEUE_FLAG_FUA, q);
871 spin_unlock_irq(q->queue_lock);
872}
873EXPORT_SYMBOL_GPL(blk_queue_write_cache);
874
849static int __init blk_settings_init(void) 875static int __init blk_settings_init(void)
850{ 876{
851 blk_max_low_pfn = max_low_pfn - 1; 877 blk_max_low_pfn = max_low_pfn - 1;
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 995b58d46ed1..99205965f559 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -347,6 +347,38 @@ static ssize_t queue_poll_store(struct request_queue *q, const char *page,
347 return ret; 347 return ret;
348} 348}
349 349
350static ssize_t queue_wc_show(struct request_queue *q, char *page)
351{
352 if (test_bit(QUEUE_FLAG_WC, &q->queue_flags))
353 return sprintf(page, "write back\n");
354
355 return sprintf(page, "write through\n");
356}
357
358static ssize_t queue_wc_store(struct request_queue *q, const char *page,
359 size_t count)
360{
361 int set = -1;
362
363 if (!strncmp(page, "write back", 10))
364 set = 1;
365 else if (!strncmp(page, "write through", 13) ||
366 !strncmp(page, "none", 4))
367 set = 0;
368
369 if (set == -1)
370 return -EINVAL;
371
372 spin_lock_irq(q->queue_lock);
373 if (set)
374 queue_flag_set(QUEUE_FLAG_WC, q);
375 else
376 queue_flag_clear(QUEUE_FLAG_WC, q);
377 spin_unlock_irq(q->queue_lock);
378
379 return count;
380}
381
350static struct queue_sysfs_entry queue_requests_entry = { 382static struct queue_sysfs_entry queue_requests_entry = {
351 .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR }, 383 .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
352 .show = queue_requests_show, 384 .show = queue_requests_show,
@@ -478,6 +510,12 @@ static struct queue_sysfs_entry queue_poll_entry = {
478 .store = queue_poll_store, 510 .store = queue_poll_store,
479}; 511};
480 512
513static struct queue_sysfs_entry queue_wc_entry = {
514 .attr = {.name = "write_cache", .mode = S_IRUGO | S_IWUSR },
515 .show = queue_wc_show,
516 .store = queue_wc_store,
517};
518
481static struct attribute *default_attrs[] = { 519static struct attribute *default_attrs[] = {
482 &queue_requests_entry.attr, 520 &queue_requests_entry.attr,
483 &queue_ra_entry.attr, 521 &queue_ra_entry.attr,
@@ -503,6 +541,7 @@ static struct attribute *default_attrs[] = {
503 &queue_iostats_entry.attr, 541 &queue_iostats_entry.attr,
504 &queue_random_entry.attr, 542 &queue_random_entry.attr,
505 &queue_poll_entry.attr, 543 &queue_poll_entry.attr,
544 &queue_wc_entry.attr,
506 NULL, 545 NULL,
507}; 546};
508 547
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index 2149a1ddbacf..47a3e540631a 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -211,15 +211,14 @@ static struct throtl_data *sq_to_td(struct throtl_service_queue *sq)
211 * 211 *
212 * The messages are prefixed with "throtl BLKG_NAME" if @sq belongs to a 212 * The messages are prefixed with "throtl BLKG_NAME" if @sq belongs to a
213 * throtl_grp; otherwise, just "throtl". 213 * throtl_grp; otherwise, just "throtl".
214 *
215 * TODO: this should be made a function and name formatting should happen
216 * after testing whether blktrace is enabled.
217 */ 214 */
218#define throtl_log(sq, fmt, args...) do { \ 215#define throtl_log(sq, fmt, args...) do { \
219 struct throtl_grp *__tg = sq_to_tg((sq)); \ 216 struct throtl_grp *__tg = sq_to_tg((sq)); \
220 struct throtl_data *__td = sq_to_td((sq)); \ 217 struct throtl_data *__td = sq_to_td((sq)); \
221 \ 218 \
222 (void)__td; \ 219 (void)__td; \
220 if (likely(!blk_trace_note_message_enabled(__td->queue))) \
221 break; \
223 if ((__tg)) { \ 222 if ((__tg)) { \
224 char __pbuf[128]; \ 223 char __pbuf[128]; \
225 \ 224 \
diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c
index 586f9168ffa4..9a9ec212fab8 100644
--- a/drivers/block/skd_main.c
+++ b/drivers/block/skd_main.c
@@ -562,7 +562,7 @@ skd_prep_discard_cdb(struct skd_scsi_request *scsi_req,
562 put_unaligned_be32(count, &buf[16]); 562 put_unaligned_be32(count, &buf[16]);
563 563
564 req = skreq->req; 564 req = skreq->req;
565 blk_add_request_payload(req, page, len); 565 blk_add_request_payload(req, page, 0, len);
566} 566}
567 567
568static void skd_request_fn_not_online(struct request_queue *q); 568static void skd_request_fn_not_online(struct request_queue *q);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index f52b74cf8d1e..69b0a4a7a15f 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -779,7 +779,7 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
779 * discarded on disk. This allows us to report completion on the full 779 * discarded on disk. This allows us to report completion on the full
780 * amount of blocks described by the request. 780 * amount of blocks described by the request.
781 */ 781 */
782 blk_add_request_payload(rq, page, len); 782 blk_add_request_payload(rq, page, 0, len);
783 ret = scsi_init_io(cmd); 783 ret = scsi_init_io(cmd);
784 rq->__data_len = nr_bytes; 784 rq->__data_len = nr_bytes;
785 785
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 6b7481f62218..9faebf7f9a33 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -703,6 +703,17 @@ static inline struct bio *bio_list_get(struct bio_list *bl)
703} 703}
704 704
705/* 705/*
706 * Increment chain count for the bio. Make sure the CHAIN flag update
707 * is visible before the raised count.
708 */
709static inline void bio_inc_remaining(struct bio *bio)
710{
711 bio_set_flag(bio, BIO_CHAIN);
712 smp_mb__before_atomic();
713 atomic_inc(&bio->__bi_remaining);
714}
715
716/*
706 * bio_set is used to allow other portions of the IO system to 717 * bio_set is used to allow other portions of the IO system to
707 * allocate their own private memory pools for bio and iovec structures. 718 * allocate their own private memory pools for bio and iovec structures.
708 * These memory pools in turn all allocate from the bio_slab 719 * These memory pools in turn all allocate from the bio_slab
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 9ac9799b702b..c808fec1ce44 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -240,6 +240,8 @@ void blk_mq_run_hw_queues(struct request_queue *q, bool async);
240void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs); 240void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs);
241void blk_mq_all_tag_busy_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn, 241void blk_mq_all_tag_busy_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn,
242 void *priv); 242 void *priv);
243void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset,
244 busy_tag_iter_fn *fn, void *priv);
243void blk_mq_freeze_queue(struct request_queue *q); 245void blk_mq_freeze_queue(struct request_queue *q);
244void blk_mq_unfreeze_queue(struct request_queue *q); 246void blk_mq_unfreeze_queue(struct request_queue *q);
245void blk_mq_freeze_queue_start(struct request_queue *q); 247void blk_mq_freeze_queue_start(struct request_queue *q);
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 86a38ea1823f..77e5d81f07aa 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -208,7 +208,7 @@ enum rq_flag_bits {
208#define REQ_COMMON_MASK \ 208#define REQ_COMMON_MASK \
209 (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \ 209 (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
210 REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \ 210 REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \
211 REQ_SECURE | REQ_INTEGRITY) 211 REQ_SECURE | REQ_INTEGRITY | REQ_NOMERGE)
212#define REQ_CLONE_MASK REQ_COMMON_MASK 212#define REQ_CLONE_MASK REQ_COMMON_MASK
213 213
214#define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME) 214#define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 669e419d6234..b79131acf6c0 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -491,6 +491,8 @@ struct request_queue {
491#define QUEUE_FLAG_INIT_DONE 20 /* queue is initialized */ 491#define QUEUE_FLAG_INIT_DONE 20 /* queue is initialized */
492#define QUEUE_FLAG_NO_SG_MERGE 21 /* don't attempt to merge SG segments*/ 492#define QUEUE_FLAG_NO_SG_MERGE 21 /* don't attempt to merge SG segments*/
493#define QUEUE_FLAG_POLL 22 /* IO polling enabled if set */ 493#define QUEUE_FLAG_POLL 22 /* IO polling enabled if set */
494#define QUEUE_FLAG_WC 23 /* Write back caching */
495#define QUEUE_FLAG_FUA 24 /* device supports FUA writes */
494 496
495#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ 497#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
496 (1 << QUEUE_FLAG_STACKABLE) | \ 498 (1 << QUEUE_FLAG_STACKABLE) | \
@@ -779,7 +781,7 @@ extern struct request *blk_make_request(struct request_queue *, struct bio *,
779extern void blk_rq_set_block_pc(struct request *); 781extern void blk_rq_set_block_pc(struct request *);
780extern void blk_requeue_request(struct request_queue *, struct request *); 782extern void blk_requeue_request(struct request_queue *, struct request *);
781extern void blk_add_request_payload(struct request *rq, struct page *page, 783extern void blk_add_request_payload(struct request *rq, struct page *page,
782 unsigned int len); 784 int offset, unsigned int len);
783extern int blk_lld_busy(struct request_queue *q); 785extern int blk_lld_busy(struct request_queue *q);
784extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src, 786extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src,
785 struct bio_set *bs, gfp_t gfp_mask, 787 struct bio_set *bs, gfp_t gfp_mask,
@@ -1009,6 +1011,7 @@ extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *);
1009extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); 1011extern void blk_queue_rq_timeout(struct request_queue *, unsigned int);
1010extern void blk_queue_flush(struct request_queue *q, unsigned int flush); 1012extern void blk_queue_flush(struct request_queue *q, unsigned int flush);
1011extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable); 1013extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable);
1014extern void blk_queue_write_cache(struct request_queue *q, bool enabled, bool fua);
1012extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); 1015extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
1013 1016
1014extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); 1017extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *);
@@ -1128,6 +1131,8 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
1128extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *); 1131extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *);
1129extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector, 1132extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
1130 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags); 1133 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
1134extern int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
1135 sector_t nr_sects, gfp_t gfp_mask, int type, struct bio **biop);
1131extern int blkdev_issue_write_same(struct block_device *bdev, sector_t sector, 1136extern int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
1132 sector_t nr_sects, gfp_t gfp_mask, struct page *page); 1137 sector_t nr_sects, gfp_t gfp_mask, struct page *page);
1133extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, 1138extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index afc1343df3c7..0f3172b8b225 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -57,6 +57,14 @@ void __trace_note_message(struct blk_trace *, const char *fmt, ...);
57 } while (0) 57 } while (0)
58#define BLK_TN_MAX_MSG 128 58#define BLK_TN_MAX_MSG 128
59 59
60static inline bool blk_trace_note_message_enabled(struct request_queue *q)
61{
62 struct blk_trace *bt = q->blk_trace;
63 if (likely(!bt))
64 return false;
65 return bt->act_mask & BLK_TC_NOTIFY;
66}
67
60extern void blk_add_driver_data(struct request_queue *q, struct request *rq, 68extern void blk_add_driver_data(struct request_queue *q, struct request *rq,
61 void *data, size_t len); 69 void *data, size_t len);
62extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, 70extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
@@ -79,6 +87,7 @@ extern struct attribute_group blk_trace_attr_group;
79# define blk_trace_remove(q) (-ENOTTY) 87# define blk_trace_remove(q) (-ENOTTY)
80# define blk_add_trace_msg(q, fmt, ...) do { } while (0) 88# define blk_add_trace_msg(q, fmt, ...) do { } while (0)
81# define blk_trace_remove_sysfs(dev) do { } while (0) 89# define blk_trace_remove_sysfs(dev) do { } while (0)
90# define blk_trace_note_message_enabled(q) (false)
82static inline int blk_trace_init_sysfs(struct device *dev) 91static inline int blk_trace_init_sysfs(struct device *dev)
83{ 92{
84 return 0; 93 return 0;
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index f94e7a21f52d..9aef8654e90d 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -1349,6 +1349,7 @@ static enum print_line_t print_one_line(struct trace_iterator *iter,
1349 if (t->action == BLK_TN_MESSAGE) { 1349 if (t->action == BLK_TN_MESSAGE) {
1350 log_action(iter, long_act ? "message" : "m"); 1350 log_action(iter, long_act ? "message" : "m");
1351 blk_log_msg(s, iter->ent); 1351 blk_log_msg(s, iter->ent);
1352 return trace_handle_return(s);
1352 } 1353 }
1353 1354
1354 if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act))) 1355 if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act)))
@@ -1551,6 +1552,7 @@ static const struct {
1551 { BLK_TC_COMPLETE, "complete" }, 1552 { BLK_TC_COMPLETE, "complete" },
1552 { BLK_TC_FS, "fs" }, 1553 { BLK_TC_FS, "fs" },
1553 { BLK_TC_PC, "pc" }, 1554 { BLK_TC_PC, "pc" },
1555 { BLK_TC_NOTIFY, "notify" },
1554 { BLK_TC_AHEAD, "ahead" }, 1556 { BLK_TC_AHEAD, "ahead" },
1555 { BLK_TC_META, "meta" }, 1557 { BLK_TC_META, "meta" },
1556 { BLK_TC_DISCARD, "discard" }, 1558 { BLK_TC_DISCARD, "discard" },