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 updates from Jens Axboe:
"This is a bit bigger than it should be, but I could (did) not want to
send it off last week due to both wanting extra testing, and expecting
a fix for the bounce regression as well. In any case, this contains:

- Fix for the blk-merge.c compilation warning on gcc 5.x from me.

- A set of back/front SG gap merge fixes, from me and from Sagi.
This ensures that we honor SG gapping for integrity payloads as
well.

- Two small fixes for null_blk from Matias, fixing a leak and a
capacity propagation issue.

- A blkcg fix from Tejun, fixing a NULL dereference.

- A fast clone optimization from Ming, fixing a performance
regression since the arbitrarily sized bio's were introduced.

- Also from Ming, a regression fix for bouncing IOs"

* 'for-linus' of git://git.kernel.dk/linux-block:
block: fix bounce_end_io
block: blk-merge: fast-clone bio when splitting rw bios
block: blkg_destroy_all() should clear q->root_blkg and ->root_rl.blkg
block: Copy a user iovec if it includes gaps
block: Refuse adding appending a gapped integrity page to a bio
block: Refuse request/bio merges with gaps in the integrity payload
block: Check for gaps on front and back merges
null_blk: fix wrong capacity when bs is not 512 bytes
null_blk: fix memory leak on cleanup
block: fix bogus compiler warnings in blk-merge.c

+129 -57
+5
block/bio-integrity.c
··· 140 140 141 141 iv = bip->bip_vec + bip->bip_vcnt; 142 142 143 + if (bip->bip_vcnt && 144 + bvec_gap_to_prev(bdev_get_queue(bio->bi_bdev), 145 + &bip->bip_vec[bip->bip_vcnt - 1], offset)) 146 + return 0; 147 + 143 148 iv->bv_page = page; 144 149 iv->bv_len = len; 145 150 iv->bv_offset = offset;
+3
block/blk-cgroup.c
··· 370 370 blkg_destroy(blkg); 371 371 spin_unlock(&blkcg->lock); 372 372 } 373 + 374 + q->root_blkg = NULL; 375 + q->root_rl.blkg = NULL; 373 376 } 374 377 375 378 /*
+3
block/blk-integrity.c
··· 204 204 q->limits.max_integrity_segments) 205 205 return false; 206 206 207 + if (integrity_req_gap_back_merge(req, next->bio)) 208 + return false; 209 + 207 210 return true; 208 211 } 209 212 EXPORT_SYMBOL(blk_integrity_merge_rq);
+24 -2
block/blk-map.c
··· 9 9 10 10 #include "blk.h" 11 11 12 + static bool iovec_gap_to_prv(struct request_queue *q, 13 + struct iovec *prv, struct iovec *cur) 14 + { 15 + unsigned long prev_end; 16 + 17 + if (!queue_virt_boundary(q)) 18 + return false; 19 + 20 + if (prv->iov_base == NULL && prv->iov_len == 0) 21 + /* prv is not set - don't check */ 22 + return false; 23 + 24 + prev_end = (unsigned long)(prv->iov_base + prv->iov_len); 25 + 26 + return (((unsigned long)cur->iov_base & queue_virt_boundary(q)) || 27 + prev_end & queue_virt_boundary(q)); 28 + } 29 + 12 30 int blk_rq_append_bio(struct request_queue *q, struct request *rq, 13 31 struct bio *bio) 14 32 { ··· 85 67 struct bio *bio; 86 68 int unaligned = 0; 87 69 struct iov_iter i; 88 - struct iovec iov; 70 + struct iovec iov, prv = {.iov_base = NULL, .iov_len = 0}; 89 71 90 72 if (!iter || !iter->count) 91 73 return -EINVAL; ··· 99 81 /* 100 82 * Keep going so we check length of all segments 101 83 */ 102 - if (uaddr & queue_dma_alignment(q)) 84 + if ((uaddr & queue_dma_alignment(q)) || 85 + iovec_gap_to_prv(q, &prv, &iov)) 103 86 unaligned = 1; 87 + 88 + prv.iov_base = iov.iov_base; 89 + prv.iov_len = iov.iov_len; 104 90 } 105 91 106 92 if (unaligned || (q->dma_pad_mask & iter->count) || map_data)
+23 -36
block/blk-merge.c
··· 66 66 struct bio *bio, 67 67 struct bio_set *bs) 68 68 { 69 - struct bio *split; 70 - struct bio_vec bv, bvprv; 69 + struct bio_vec bv, bvprv, *bvprvp = NULL; 71 70 struct bvec_iter iter; 72 71 unsigned seg_size = 0, nsegs = 0, sectors = 0; 73 - int prev = 0; 74 72 75 73 bio_for_each_segment(bv, bio, iter) { 76 - sectors += bv.bv_len >> 9; 77 - 78 - if (sectors > queue_max_sectors(q)) 74 + if (sectors + (bv.bv_len >> 9) > queue_max_sectors(q)) 79 75 goto split; 80 76 81 77 /* 82 78 * If the queue doesn't support SG gaps and adding this 83 79 * offset would create a gap, disallow it. 84 80 */ 85 - if (prev && bvec_gap_to_prev(q, &bvprv, bv.bv_offset)) 81 + if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset)) 86 82 goto split; 87 83 88 - if (prev && blk_queue_cluster(q)) { 84 + if (bvprvp && blk_queue_cluster(q)) { 89 85 if (seg_size + bv.bv_len > queue_max_segment_size(q)) 90 86 goto new_segment; 91 - if (!BIOVEC_PHYS_MERGEABLE(&bvprv, &bv)) 87 + if (!BIOVEC_PHYS_MERGEABLE(bvprvp, &bv)) 92 88 goto new_segment; 93 - if (!BIOVEC_SEG_BOUNDARY(q, &bvprv, &bv)) 89 + if (!BIOVEC_SEG_BOUNDARY(q, bvprvp, &bv)) 94 90 goto new_segment; 95 91 96 92 seg_size += bv.bv_len; 97 93 bvprv = bv; 98 - prev = 1; 94 + bvprvp = &bv; 95 + sectors += bv.bv_len >> 9; 99 96 continue; 100 97 } 101 98 new_segment: ··· 101 104 102 105 nsegs++; 103 106 bvprv = bv; 104 - prev = 1; 107 + bvprvp = &bv; 105 108 seg_size = bv.bv_len; 109 + sectors += bv.bv_len >> 9; 106 110 } 107 111 108 112 return NULL; 109 113 split: 110 - split = bio_clone_bioset(bio, GFP_NOIO, bs); 111 - 112 - split->bi_iter.bi_size -= iter.bi_size; 113 - bio->bi_iter = iter; 114 - 115 - if (bio_integrity(bio)) { 116 - bio_integrity_advance(bio, split->bi_iter.bi_size); 117 - bio_integrity_trim(split, 0, bio_sectors(split)); 118 - } 119 - 120 - return split; 114 + return bio_split(bio, sectors, GFP_NOIO, bs); 121 115 } 122 116 123 117 void blk_queue_split(struct request_queue *q, struct bio **bio, ··· 427 439 int ll_back_merge_fn(struct request_queue *q, struct request *req, 428 440 struct bio *bio) 429 441 { 442 + if (req_gap_back_merge(req, bio)) 443 + return 0; 444 + if (blk_integrity_rq(req) && 445 + integrity_req_gap_back_merge(req, bio)) 446 + return 0; 430 447 if (blk_rq_sectors(req) + bio_sectors(bio) > 431 448 blk_rq_get_max_sectors(req)) { 432 449 req->cmd_flags |= REQ_NOMERGE; ··· 450 457 int ll_front_merge_fn(struct request_queue *q, struct request *req, 451 458 struct bio *bio) 452 459 { 460 + 461 + if (req_gap_front_merge(req, bio)) 462 + return 0; 463 + if (blk_integrity_rq(req) && 464 + integrity_req_gap_front_merge(req, bio)) 465 + return 0; 453 466 if (blk_rq_sectors(req) + bio_sectors(bio) > 454 467 blk_rq_get_max_sectors(req)) { 455 468 req->cmd_flags |= REQ_NOMERGE; ··· 482 483 return !q->mq_ops && req->special; 483 484 } 484 485 485 - static int req_gap_to_prev(struct request *req, struct bio *next) 486 - { 487 - struct bio *prev = req->biotail; 488 - 489 - return bvec_gap_to_prev(req->q, &prev->bi_io_vec[prev->bi_vcnt - 1], 490 - next->bi_io_vec[0].bv_offset); 491 - } 492 - 493 486 static int ll_merge_requests_fn(struct request_queue *q, struct request *req, 494 487 struct request *next) 495 488 { ··· 496 505 if (req_no_special_merge(req) || req_no_special_merge(next)) 497 506 return 0; 498 507 499 - if (req_gap_to_prev(req, next->bio)) 508 + if (req_gap_back_merge(req, next->bio)) 500 509 return 0; 501 510 502 511 /* ··· 702 711 /* must be using the same buffer */ 703 712 if (rq->cmd_flags & REQ_WRITE_SAME && 704 713 !blk_write_same_mergeable(rq->bio, bio)) 705 - return false; 706 - 707 - /* Only check gaps if the bio carries data */ 708 - if (bio_has_data(bio) && req_gap_to_prev(rq, bio)) 709 714 return false; 710 715 711 716 return true;
+3 -1
block/bounce.c
··· 128 128 struct bio *bio_orig = bio->bi_private; 129 129 struct bio_vec *bvec, *org_vec; 130 130 int i; 131 + int start = bio_orig->bi_iter.bi_idx; 131 132 132 133 /* 133 134 * free up bounce indirect pages used 134 135 */ 135 136 bio_for_each_segment_all(bvec, bio, i) { 136 - org_vec = bio_orig->bi_io_vec + i; 137 + org_vec = bio_orig->bi_io_vec + i + start; 138 + 137 139 if (bvec->bv_page == org_vec->bv_page) 138 140 continue; 139 141
+18 -18
drivers/block/null_blk.c
··· 406 406 .complete = null_softirq_done_fn, 407 407 }; 408 408 409 + static void cleanup_queue(struct nullb_queue *nq) 410 + { 411 + kfree(nq->tag_map); 412 + kfree(nq->cmds); 413 + } 414 + 415 + static void cleanup_queues(struct nullb *nullb) 416 + { 417 + int i; 418 + 419 + for (i = 0; i < nullb->nr_queues; i++) 420 + cleanup_queue(&nullb->queues[i]); 421 + 422 + kfree(nullb->queues); 423 + } 424 + 409 425 static void null_del_dev(struct nullb *nullb) 410 426 { 411 427 list_del_init(&nullb->list); ··· 431 415 if (queue_mode == NULL_Q_MQ) 432 416 blk_mq_free_tag_set(&nullb->tag_set); 433 417 put_disk(nullb->disk); 418 + cleanup_queues(nullb); 434 419 kfree(nullb); 435 420 } 436 421 ··· 474 457 } 475 458 476 459 return 0; 477 - } 478 - 479 - static void cleanup_queue(struct nullb_queue *nq) 480 - { 481 - kfree(nq->tag_map); 482 - kfree(nq->cmds); 483 - } 484 - 485 - static void cleanup_queues(struct nullb *nullb) 486 - { 487 - int i; 488 - 489 - for (i = 0; i < nullb->nr_queues; i++) 490 - cleanup_queue(&nullb->queues[i]); 491 - 492 - kfree(nullb->queues); 493 460 } 494 461 495 462 static int setup_queues(struct nullb *nullb) ··· 589 588 blk_queue_physical_block_size(nullb->q, bs); 590 589 591 590 size = gb * 1024 * 1024 * 1024ULL; 592 - sector_div(size, bs); 593 - set_capacity(disk, size); 591 + set_capacity(disk, size >> 9); 594 592 595 593 disk->flags |= GENHD_FL_EXT_DEVT | GENHD_FL_SUPPRESS_PARTITION_INFO; 596 594 disk->major = null_major;
+50
include/linux/blkdev.h
··· 1368 1368 ((bprv->bv_offset + bprv->bv_len) & queue_virt_boundary(q)); 1369 1369 } 1370 1370 1371 + static inline bool bio_will_gap(struct request_queue *q, struct bio *prev, 1372 + struct bio *next) 1373 + { 1374 + if (!bio_has_data(prev)) 1375 + return false; 1376 + 1377 + return bvec_gap_to_prev(q, &prev->bi_io_vec[prev->bi_vcnt - 1], 1378 + next->bi_io_vec[0].bv_offset); 1379 + } 1380 + 1381 + static inline bool req_gap_back_merge(struct request *req, struct bio *bio) 1382 + { 1383 + return bio_will_gap(req->q, req->biotail, bio); 1384 + } 1385 + 1386 + static inline bool req_gap_front_merge(struct request *req, struct bio *bio) 1387 + { 1388 + return bio_will_gap(req->q, bio, req->bio); 1389 + } 1390 + 1371 1391 struct work_struct; 1372 1392 int kblockd_schedule_work(struct work_struct *work); 1373 1393 int kblockd_schedule_delayed_work(struct delayed_work *dwork, unsigned long delay); ··· 1514 1494 return q->limits.max_integrity_segments; 1515 1495 } 1516 1496 1497 + static inline bool integrity_req_gap_back_merge(struct request *req, 1498 + struct bio *next) 1499 + { 1500 + struct bio_integrity_payload *bip = bio_integrity(req->bio); 1501 + struct bio_integrity_payload *bip_next = bio_integrity(next); 1502 + 1503 + return bvec_gap_to_prev(req->q, &bip->bip_vec[bip->bip_vcnt - 1], 1504 + bip_next->bip_vec[0].bv_offset); 1505 + } 1506 + 1507 + static inline bool integrity_req_gap_front_merge(struct request *req, 1508 + struct bio *bio) 1509 + { 1510 + struct bio_integrity_payload *bip = bio_integrity(bio); 1511 + struct bio_integrity_payload *bip_next = bio_integrity(req->bio); 1512 + 1513 + return bvec_gap_to_prev(req->q, &bip->bip_vec[bip->bip_vcnt - 1], 1514 + bip_next->bip_vec[0].bv_offset); 1515 + } 1516 + 1517 1517 #else /* CONFIG_BLK_DEV_INTEGRITY */ 1518 1518 1519 1519 struct bio; ··· 1599 1559 static inline bool blk_integrity_is_initialized(struct gendisk *g) 1600 1560 { 1601 1561 return 0; 1562 + } 1563 + static inline bool integrity_req_gap_back_merge(struct request *req, 1564 + struct bio *next) 1565 + { 1566 + return false; 1567 + } 1568 + static inline bool integrity_req_gap_front_merge(struct request *req, 1569 + struct bio *bio) 1570 + { 1571 + return false; 1602 1572 } 1603 1573 1604 1574 #endif /* CONFIG_BLK_DEV_INTEGRITY */