Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+24 -8
+16
block/blk-core.c
··· 207 207 EXPORT_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 + **/ 218 + void blk_start_queue_async(struct request_queue *q) 219 + { 220 + queue_flag_clear(QUEUE_FLAG_STOPPED, q); 221 + blk_run_queue_async(q); 222 + } 223 + EXPORT_SYMBOL(blk_start_queue_async); 224 + 225 + /** 210 226 * blk_start_queue - restart a previously stopped queue 211 227 * @q: The &struct request_queue in question 212 228 *
+1 -1
block/blk-merge.c
··· 81 81 struct bio *new = NULL; 82 82 83 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 85 goto split; 86 86 87 87 /*
+5 -6
drivers/block/null_blk.c
··· 232 232 break; 233 233 case NULL_Q_BIO: 234 234 bio_endio(cmd->bio); 235 - goto free_cmd; 235 + break; 236 236 } 237 237 238 + free_cmd(cmd); 239 + 238 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 242 unsigned long flags; 241 243 242 244 spin_lock_irqsave(q->queue_lock, flags); 243 - if (blk_queue_stopped(q)) 244 - blk_start_queue(q); 245 + blk_start_queue_async(q); 245 246 spin_unlock_irqrestore(q->queue_lock, flags); 246 247 } 247 - free_cmd: 248 - free_cmd(cmd); 249 248 } 250 249 251 250 static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer)
+1 -1
drivers/lightnvm/gennvm.c
··· 75 75 struct nvm_block *blk; 76 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 80 for (i = 0; i < nr_blocks; i++) { 81 81 if (blks[i] == 0)
+1
include/linux/blkdev.h
··· 797 797 extern int blk_queue_enter(struct request_queue *q, gfp_t gfp); 798 798 extern void blk_queue_exit(struct request_queue *q); 799 799 extern void blk_start_queue(struct request_queue *q); 800 + extern void blk_start_queue_async(struct request_queue *q); 800 801 extern void blk_stop_queue(struct request_queue *q); 801 802 extern void blk_sync_queue(struct request_queue *q); 802 803 extern void __blk_stop_queue(struct request_queue *q);