diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-06-11 21:42:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-06-11 21:42:59 -0400 |
commit | 8714f8f5fe396ca513ccaaac2304497439c181fb (patch) | |
tree | 080fbadd7f796cf45b514f031cd24badfb0ed8cd | |
parent | 3a7c114d358dbe1c5cba70e7d4c3cb39b3c8ecaa (diff) | |
parent | edb50a5403d2e2d2b2b63a8365c4378c9c300ed6 (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull block layer fixes from Jens Axboe:
"A small collection of fixes for the current series. This contains:
- Two fixes for xen-blkfront, from Bob Liu.
- A bug fix for NVMe, releasing only the specific resources we
requested.
- Fix for a debugfs flags entry for nbd, from Josef.
- Plug fix from Omar, fixing up a case of code being switched between
two functions.
- A missing bio_put() for the new discard callers of
submit_bio_wait(), fixing a regression causing a leak of the bio.
From Shaun.
- Improve dirty limit calculation precision in the writeback code,
fixing a case where setting a limit lower than 1% of memory would
end up being zero. From Tejun"
* 'for-linus' of git://git.kernel.dk/linux-block:
NVMe: Only release requested regions
xen-blkfront: fix resume issues after a migration
xen-blkfront: don't call talk_to_blkback when already connected to blkback
nbd: pass the nbd pointer for flags debugfs
block: missing bio_put following submit_bio_wait
blk-mq: really fix plug list flushing for nomerge queues
writeback: use higher precision calculation in domain_dirty_limits()
-rw-r--r-- | block/blk-lib.c | 12 | ||||
-rw-r--r-- | block/blk-mq.c | 17 | ||||
-rw-r--r-- | drivers/block/nbd.c | 2 | ||||
-rw-r--r-- | drivers/block/xen-blkfront.c | 35 | ||||
-rw-r--r-- | drivers/nvme/host/pci.c | 9 | ||||
-rw-r--r-- | mm/page-writeback.c | 21 |
6 files changed, 59 insertions, 37 deletions
diff --git a/block/blk-lib.c b/block/blk-lib.c index 23d7f301a196..9e29dc351695 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c | |||
@@ -113,6 +113,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
113 | ret = submit_bio_wait(type, bio); | 113 | ret = submit_bio_wait(type, bio); |
114 | if (ret == -EOPNOTSUPP) | 114 | if (ret == -EOPNOTSUPP) |
115 | ret = 0; | 115 | ret = 0; |
116 | bio_put(bio); | ||
116 | } | 117 | } |
117 | blk_finish_plug(&plug); | 118 | blk_finish_plug(&plug); |
118 | 119 | ||
@@ -165,8 +166,10 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector, | |||
165 | } | 166 | } |
166 | } | 167 | } |
167 | 168 | ||
168 | if (bio) | 169 | if (bio) { |
169 | ret = submit_bio_wait(REQ_WRITE | REQ_WRITE_SAME, bio); | 170 | ret = submit_bio_wait(REQ_WRITE | REQ_WRITE_SAME, bio); |
171 | bio_put(bio); | ||
172 | } | ||
170 | return ret != -EOPNOTSUPP ? ret : 0; | 173 | return ret != -EOPNOTSUPP ? ret : 0; |
171 | } | 174 | } |
172 | EXPORT_SYMBOL(blkdev_issue_write_same); | 175 | EXPORT_SYMBOL(blkdev_issue_write_same); |
@@ -206,8 +209,11 @@ static int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, | |||
206 | } | 209 | } |
207 | } | 210 | } |
208 | 211 | ||
209 | if (bio) | 212 | if (bio) { |
210 | return submit_bio_wait(WRITE, bio); | 213 | ret = submit_bio_wait(WRITE, bio); |
214 | bio_put(bio); | ||
215 | return ret; | ||
216 | } | ||
211 | return 0; | 217 | return 0; |
212 | } | 218 | } |
213 | 219 | ||
diff --git a/block/blk-mq.c b/block/blk-mq.c index 29cbc1b5fbdb..f9b9049b1284 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -1262,12 +1262,9 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) | |||
1262 | 1262 | ||
1263 | blk_queue_split(q, &bio, q->bio_split); | 1263 | blk_queue_split(q, &bio, q->bio_split); |
1264 | 1264 | ||
1265 | if (!is_flush_fua && !blk_queue_nomerges(q)) { | 1265 | if (!is_flush_fua && !blk_queue_nomerges(q) && |
1266 | if (blk_attempt_plug_merge(q, bio, &request_count, | 1266 | blk_attempt_plug_merge(q, bio, &request_count, &same_queue_rq)) |
1267 | &same_queue_rq)) | 1267 | return BLK_QC_T_NONE; |
1268 | return BLK_QC_T_NONE; | ||
1269 | } else | ||
1270 | request_count = blk_plug_queued_count(q); | ||
1271 | 1268 | ||
1272 | rq = blk_mq_map_request(q, bio, &data); | 1269 | rq = blk_mq_map_request(q, bio, &data); |
1273 | if (unlikely(!rq)) | 1270 | if (unlikely(!rq)) |
@@ -1358,9 +1355,11 @@ static blk_qc_t blk_sq_make_request(struct request_queue *q, struct bio *bio) | |||
1358 | 1355 | ||
1359 | blk_queue_split(q, &bio, q->bio_split); | 1356 | blk_queue_split(q, &bio, q->bio_split); |
1360 | 1357 | ||
1361 | if (!is_flush_fua && !blk_queue_nomerges(q) && | 1358 | if (!is_flush_fua && !blk_queue_nomerges(q)) { |
1362 | blk_attempt_plug_merge(q, bio, &request_count, NULL)) | 1359 | if (blk_attempt_plug_merge(q, bio, &request_count, NULL)) |
1363 | return BLK_QC_T_NONE; | 1360 | return BLK_QC_T_NONE; |
1361 | } else | ||
1362 | request_count = blk_plug_queued_count(q); | ||
1364 | 1363 | ||
1365 | rq = blk_mq_map_request(q, bio, &data); | 1364 | rq = blk_mq_map_request(q, bio, &data); |
1366 | if (unlikely(!rq)) | 1365 | if (unlikely(!rq)) |
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 31e73a7a40f2..6a48ed41963f 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -941,7 +941,7 @@ static int nbd_dev_dbg_init(struct nbd_device *nbd) | |||
941 | debugfs_create_u64("size_bytes", 0444, dir, &nbd->bytesize); | 941 | debugfs_create_u64("size_bytes", 0444, dir, &nbd->bytesize); |
942 | debugfs_create_u32("timeout", 0444, dir, &nbd->xmit_timeout); | 942 | debugfs_create_u32("timeout", 0444, dir, &nbd->xmit_timeout); |
943 | debugfs_create_u32("blocksize", 0444, dir, &nbd->blksize); | 943 | debugfs_create_u32("blocksize", 0444, dir, &nbd->blksize); |
944 | debugfs_create_file("flags", 0444, dir, &nbd, &nbd_dbg_flags_ops); | 944 | debugfs_create_file("flags", 0444, dir, nbd, &nbd_dbg_flags_ops); |
945 | 945 | ||
946 | return 0; | 946 | return 0; |
947 | } | 947 | } |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index ca13df854639..2e6d1e9c3345 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -874,8 +874,12 @@ static int blkif_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
874 | const struct blk_mq_queue_data *qd) | 874 | const struct blk_mq_queue_data *qd) |
875 | { | 875 | { |
876 | unsigned long flags; | 876 | unsigned long flags; |
877 | struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)hctx->driver_data; | 877 | int qid = hctx->queue_num; |
878 | struct blkfront_info *info = hctx->queue->queuedata; | ||
879 | struct blkfront_ring_info *rinfo = NULL; | ||
878 | 880 | ||
881 | BUG_ON(info->nr_rings <= qid); | ||
882 | rinfo = &info->rinfo[qid]; | ||
879 | blk_mq_start_request(qd->rq); | 883 | blk_mq_start_request(qd->rq); |
880 | spin_lock_irqsave(&rinfo->ring_lock, flags); | 884 | spin_lock_irqsave(&rinfo->ring_lock, flags); |
881 | if (RING_FULL(&rinfo->ring)) | 885 | if (RING_FULL(&rinfo->ring)) |
@@ -901,20 +905,9 @@ out_busy: | |||
901 | return BLK_MQ_RQ_QUEUE_BUSY; | 905 | return BLK_MQ_RQ_QUEUE_BUSY; |
902 | } | 906 | } |
903 | 907 | ||
904 | static int blk_mq_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, | ||
905 | unsigned int index) | ||
906 | { | ||
907 | struct blkfront_info *info = (struct blkfront_info *)data; | ||
908 | |||
909 | BUG_ON(info->nr_rings <= index); | ||
910 | hctx->driver_data = &info->rinfo[index]; | ||
911 | return 0; | ||
912 | } | ||
913 | |||
914 | static struct blk_mq_ops blkfront_mq_ops = { | 908 | static struct blk_mq_ops blkfront_mq_ops = { |
915 | .queue_rq = blkif_queue_rq, | 909 | .queue_rq = blkif_queue_rq, |
916 | .map_queue = blk_mq_map_queue, | 910 | .map_queue = blk_mq_map_queue, |
917 | .init_hctx = blk_mq_init_hctx, | ||
918 | }; | 911 | }; |
919 | 912 | ||
920 | static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, | 913 | static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, |
@@ -950,6 +943,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, | |||
950 | return PTR_ERR(rq); | 943 | return PTR_ERR(rq); |
951 | } | 944 | } |
952 | 945 | ||
946 | rq->queuedata = info; | ||
953 | queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq); | 947 | queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq); |
954 | 948 | ||
955 | if (info->feature_discard) { | 949 | if (info->feature_discard) { |
@@ -2149,6 +2143,8 @@ static int blkfront_resume(struct xenbus_device *dev) | |||
2149 | return err; | 2143 | return err; |
2150 | 2144 | ||
2151 | err = talk_to_blkback(dev, info); | 2145 | err = talk_to_blkback(dev, info); |
2146 | if (!err) | ||
2147 | blk_mq_update_nr_hw_queues(&info->tag_set, info->nr_rings); | ||
2152 | 2148 | ||
2153 | /* | 2149 | /* |
2154 | * We have to wait for the backend to switch to | 2150 | * We have to wait for the backend to switch to |
@@ -2485,10 +2481,23 @@ static void blkback_changed(struct xenbus_device *dev, | |||
2485 | break; | 2481 | break; |
2486 | 2482 | ||
2487 | case XenbusStateConnected: | 2483 | case XenbusStateConnected: |
2488 | if (dev->state != XenbusStateInitialised) { | 2484 | /* |
2485 | * talk_to_blkback sets state to XenbusStateInitialised | ||
2486 | * and blkfront_connect sets it to XenbusStateConnected | ||
2487 | * (if connection went OK). | ||
2488 | * | ||
2489 | * If the backend (or toolstack) decides to poke at backend | ||
2490 | * state (and re-trigger the watch by setting the state repeatedly | ||
2491 | * to XenbusStateConnected (4)) we need to deal with this. | ||
2492 | * This is allowed as this is used to communicate to the guest | ||
2493 | * that the size of disk has changed! | ||
2494 | */ | ||
2495 | if ((dev->state != XenbusStateInitialised) && | ||
2496 | (dev->state != XenbusStateConnected)) { | ||
2489 | if (talk_to_blkback(dev, info)) | 2497 | if (talk_to_blkback(dev, info)) |
2490 | break; | 2498 | break; |
2491 | } | 2499 | } |
2500 | |||
2492 | blkfront_connect(info); | 2501 | blkfront_connect(info); |
2493 | break; | 2502 | break; |
2494 | 2503 | ||
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 78dca3193ca4..befac5b19490 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
@@ -1679,9 +1679,14 @@ static int nvme_pci_enable(struct nvme_dev *dev) | |||
1679 | 1679 | ||
1680 | static void nvme_dev_unmap(struct nvme_dev *dev) | 1680 | static void nvme_dev_unmap(struct nvme_dev *dev) |
1681 | { | 1681 | { |
1682 | struct pci_dev *pdev = to_pci_dev(dev->dev); | ||
1683 | int bars; | ||
1684 | |||
1682 | if (dev->bar) | 1685 | if (dev->bar) |
1683 | iounmap(dev->bar); | 1686 | iounmap(dev->bar); |
1684 | pci_release_regions(to_pci_dev(dev->dev)); | 1687 | |
1688 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
1689 | pci_release_selected_regions(pdev, bars); | ||
1685 | } | 1690 | } |
1686 | 1691 | ||
1687 | static void nvme_pci_disable(struct nvme_dev *dev) | 1692 | static void nvme_pci_disable(struct nvme_dev *dev) |
@@ -1924,7 +1929,7 @@ static int nvme_dev_map(struct nvme_dev *dev) | |||
1924 | 1929 | ||
1925 | return 0; | 1930 | return 0; |
1926 | release: | 1931 | release: |
1927 | pci_release_regions(pdev); | 1932 | pci_release_selected_regions(pdev, bars); |
1928 | return -ENODEV; | 1933 | return -ENODEV; |
1929 | } | 1934 | } |
1930 | 1935 | ||
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index b9956fdee8f5..e2481949494c 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -373,8 +373,9 @@ static void domain_dirty_limits(struct dirty_throttle_control *dtc) | |||
373 | struct dirty_throttle_control *gdtc = mdtc_gdtc(dtc); | 373 | struct dirty_throttle_control *gdtc = mdtc_gdtc(dtc); |
374 | unsigned long bytes = vm_dirty_bytes; | 374 | unsigned long bytes = vm_dirty_bytes; |
375 | unsigned long bg_bytes = dirty_background_bytes; | 375 | unsigned long bg_bytes = dirty_background_bytes; |
376 | unsigned long ratio = vm_dirty_ratio; | 376 | /* convert ratios to per-PAGE_SIZE for higher precision */ |
377 | unsigned long bg_ratio = dirty_background_ratio; | 377 | unsigned long ratio = (vm_dirty_ratio * PAGE_SIZE) / 100; |
378 | unsigned long bg_ratio = (dirty_background_ratio * PAGE_SIZE) / 100; | ||
378 | unsigned long thresh; | 379 | unsigned long thresh; |
379 | unsigned long bg_thresh; | 380 | unsigned long bg_thresh; |
380 | struct task_struct *tsk; | 381 | struct task_struct *tsk; |
@@ -386,26 +387,28 @@ static void domain_dirty_limits(struct dirty_throttle_control *dtc) | |||
386 | /* | 387 | /* |
387 | * The byte settings can't be applied directly to memcg | 388 | * The byte settings can't be applied directly to memcg |
388 | * domains. Convert them to ratios by scaling against | 389 | * domains. Convert them to ratios by scaling against |
389 | * globally available memory. | 390 | * globally available memory. As the ratios are in |
391 | * per-PAGE_SIZE, they can be obtained by dividing bytes by | ||
392 | * number of pages. | ||
390 | */ | 393 | */ |
391 | if (bytes) | 394 | if (bytes) |
392 | ratio = min(DIV_ROUND_UP(bytes, PAGE_SIZE) * 100 / | 395 | ratio = min(DIV_ROUND_UP(bytes, global_avail), |
393 | global_avail, 100UL); | 396 | PAGE_SIZE); |
394 | if (bg_bytes) | 397 | if (bg_bytes) |
395 | bg_ratio = min(DIV_ROUND_UP(bg_bytes, PAGE_SIZE) * 100 / | 398 | bg_ratio = min(DIV_ROUND_UP(bg_bytes, global_avail), |
396 | global_avail, 100UL); | 399 | PAGE_SIZE); |
397 | bytes = bg_bytes = 0; | 400 | bytes = bg_bytes = 0; |
398 | } | 401 | } |
399 | 402 | ||
400 | if (bytes) | 403 | if (bytes) |
401 | thresh = DIV_ROUND_UP(bytes, PAGE_SIZE); | 404 | thresh = DIV_ROUND_UP(bytes, PAGE_SIZE); |
402 | else | 405 | else |
403 | thresh = (ratio * available_memory) / 100; | 406 | thresh = (ratio * available_memory) / PAGE_SIZE; |
404 | 407 | ||
405 | if (bg_bytes) | 408 | if (bg_bytes) |
406 | bg_thresh = DIV_ROUND_UP(bg_bytes, PAGE_SIZE); | 409 | bg_thresh = DIV_ROUND_UP(bg_bytes, PAGE_SIZE); |
407 | else | 410 | else |
408 | bg_thresh = (bg_ratio * available_memory) / 100; | 411 | bg_thresh = (bg_ratio * available_memory) / PAGE_SIZE; |
409 | 412 | ||
410 | if (bg_thresh >= thresh) | 413 | if (bg_thresh >= thresh) |
411 | bg_thresh = thresh / 2; | 414 | bg_thresh = thresh / 2; |