aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-12-30 13:26:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-12-30 13:26:20 -0500
commitc6169202e40868fd00de7ce35ee16c81b1f9e123 (patch)
treede36c7ec8fce13d477bbbbc5942ecf0e1109f60f
parent866be88a1a313688d94a7708a1f4649af0cdbd97 (diff)
parentc3293a9ac2a4f9160b85b5e986a8e0c54986e7f7 (diff)
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe: "Make the block layer great again. Basically three amazing fixes in this pull request, split into 4 patches. Believe me, they should go into 4.4. Two of them fix a regression, the third and last fixes an easy-to-trigger bug. - Fix a bad irq enable through null_blk, for queue_mode=1 and using timer completions. Add a block helper to restart a queue asynchronously, and use that from null_blk. From me. - Fix a performance issue in NVMe. Some devices (Intel Pxxxx) expose a stripe boundary, and performance suffers if we cross it. We took that into account for merging, but not for the newer splitting code. Fix from Keith. - Fix a kernel oops in lightnvm with multiple channels. From Matias" * 'for-linus' of git://git.kernel.dk/linux-block: lightnvm: wrong offset in bad blk lun calculation null_blk: use async queue restart helper block: add blk_start_queue_async() block: Split bios on chunk boundaries
-rw-r--r--block/blk-core.c16
-rw-r--r--block/blk-merge.c2
-rw-r--r--drivers/block/null_blk.c11
-rw-r--r--drivers/lightnvm/gennvm.c2
-rw-r--r--include/linux/blkdev.h1
5 files changed, 24 insertions, 8 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index c487b94c59e3..33e2f62d5062 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -207,6 +207,22 @@ void blk_delay_queue(struct request_queue *q, unsigned long msecs)
207EXPORT_SYMBOL(blk_delay_queue); 207EXPORT_SYMBOL(blk_delay_queue);
208 208
209/** 209/**
210 * blk_start_queue_async - asynchronously restart a previously stopped queue
211 * @q: The &struct request_queue in question
212 *
213 * Description:
214 * blk_start_queue_async() will clear the stop flag on the queue, and
215 * ensure that the request_fn for the queue is run from an async
216 * context.
217 **/
218void blk_start_queue_async(struct request_queue *q)
219{
220 queue_flag_clear(QUEUE_FLAG_STOPPED, q);
221 blk_run_queue_async(q);
222}
223EXPORT_SYMBOL(blk_start_queue_async);
224
225/**
210 * blk_start_queue - restart a previously stopped queue 226 * blk_start_queue - restart a previously stopped queue
211 * @q: The &struct request_queue in question 227 * @q: The &struct request_queue in question
212 * 228 *
diff --git a/block/blk-merge.c b/block/blk-merge.c
index e01405a3e8b3..e73846a3d08a 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -81,7 +81,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
81 struct bio *new = NULL; 81 struct bio *new = NULL;
82 82
83 bio_for_each_segment(bv, bio, iter) { 83 bio_for_each_segment(bv, bio, iter) {
84 if (sectors + (bv.bv_len >> 9) > queue_max_sectors(q)) 84 if (sectors + (bv.bv_len >> 9) > blk_max_size_offset(q, bio->bi_iter.bi_sector))
85 goto split; 85 goto split;
86 86
87 /* 87 /*
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c
index a428e4ef71fd..09e3c0d87ecc 100644
--- a/drivers/block/null_blk.c
+++ b/drivers/block/null_blk.c
@@ -232,20 +232,19 @@ static void end_cmd(struct nullb_cmd *cmd)
232 break; 232 break;
233 case NULL_Q_BIO: 233 case NULL_Q_BIO:
234 bio_endio(cmd->bio); 234 bio_endio(cmd->bio);
235 goto free_cmd; 235 break;
236 } 236 }
237 237
238 free_cmd(cmd);
239
238 /* Restart queue if needed, as we are freeing a tag */ 240 /* Restart queue if needed, as we are freeing a tag */
239 if (q && !q->mq_ops && blk_queue_stopped(q)) { 241 if (queue_mode == NULL_Q_RQ && blk_queue_stopped(q)) {
240 unsigned long flags; 242 unsigned long flags;
241 243
242 spin_lock_irqsave(q->queue_lock, flags); 244 spin_lock_irqsave(q->queue_lock, flags);
243 if (blk_queue_stopped(q)) 245 blk_start_queue_async(q);
244 blk_start_queue(q);
245 spin_unlock_irqrestore(q->queue_lock, flags); 246 spin_unlock_irqrestore(q->queue_lock, flags);
246 } 247 }
247free_cmd:
248 free_cmd(cmd);
249} 248}
250 249
251static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) 250static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer)
diff --git a/drivers/lightnvm/gennvm.c b/drivers/lightnvm/gennvm.c
index f434e89e1c7a..a54b339951a3 100644
--- a/drivers/lightnvm/gennvm.c
+++ b/drivers/lightnvm/gennvm.c
@@ -75,7 +75,7 @@ static int gennvm_block_bb(struct ppa_addr ppa, int nr_blocks, u8 *blks,
75 struct nvm_block *blk; 75 struct nvm_block *blk;
76 int i; 76 int i;
77 77
78 lun = &gn->luns[(dev->nr_luns * ppa.g.ch) + ppa.g.lun]; 78 lun = &gn->luns[(dev->luns_per_chnl * ppa.g.ch) + ppa.g.lun];
79 79
80 for (i = 0; i < nr_blocks; i++) { 80 for (i = 0; i < nr_blocks; i++) {
81 if (blks[i] == 0) 81 if (blks[i] == 0)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 0169ba2e2e64..c70e3588a48c 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -797,6 +797,7 @@ extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t,
797extern int blk_queue_enter(struct request_queue *q, gfp_t gfp); 797extern int blk_queue_enter(struct request_queue *q, gfp_t gfp);
798extern void blk_queue_exit(struct request_queue *q); 798extern void blk_queue_exit(struct request_queue *q);
799extern void blk_start_queue(struct request_queue *q); 799extern void blk_start_queue(struct request_queue *q);
800extern void blk_start_queue_async(struct request_queue *q);
800extern void blk_stop_queue(struct request_queue *q); 801extern void blk_stop_queue(struct request_queue *q);
801extern void blk_sync_queue(struct request_queue *q); 802extern void blk_sync_queue(struct request_queue *q);
802extern void __blk_stop_queue(struct request_queue *q); 803extern void __blk_stop_queue(struct request_queue *q);