diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-30 16:39:04 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-30 16:39:04 -0400 |
| commit | fb64638566588392e4a544760b649fd7f857e33a (patch) | |
| tree | f31ebdb2f7def1b8001e2ba78ad831d83ebeac9d | |
| parent | 9f8f16c86e4d9e2afcbdcd6045981c4d9129450e (diff) | |
| parent | 52bd456a66c1abb7dd43628080025703248b1ea2 (diff) | |
Merge tag 'for-linus-20180830' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe:
"Small collection of fixes that should go into this series. This pull
contains:
- NVMe pull request with three small fixes (via Christoph)
- Kill useless NULL check before kmem_cache_destroy (Chengguang Xu)
- Xen block driver pull request with persistent grant flushing fixes
(Juergen Gross)
- Final wbt fixes, wrapping up the changes for this series. These
have been heavily tested (me)
- cdrom info leak fix (Scott Bauer)
- ATA dma quirk for SQ201 (Linus Walleij)
- Straight forward bsg refcount_t conversion (John Pittman)"
* tag 'for-linus-20180830' of git://git.kernel.dk/linux-block:
cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
nvmet: free workqueue object if module init fails
nvme-fcloop: Fix dropped LS's to removed target port
nvme-pci: add a memory barrier to nvme_dbbuf_update_and_check_event
block: bsg: move atomic_t ref_count variable to refcount API
block: remove unnecessary condition check
ata: ftide010: Add a quirk for SQ201
blk-wbt: remove dead code
blk-wbt: improve waking of tasks
blk-wbt: abstract out end IO completion handler
xen/blkback: remove unused pers_gnts_lock from struct xen_blkif_ring
xen/blkback: move persistent grants flags to bool
xen/blkfront: reorder tests in xlblk_init()
xen/blkfront: cleanup stale persistent grants
xen/blkback: don't keep persistent grants too long
| -rw-r--r-- | Documentation/ABI/testing/sysfs-driver-xen-blkback | 10 | ||||
| -rw-r--r-- | block/blk-wbt.c | 89 | ||||
| -rw-r--r-- | block/bsg.c | 8 | ||||
| -rw-r--r-- | block/elevator.c | 3 | ||||
| -rw-r--r-- | drivers/ata/pata_ftide010.c | 27 | ||||
| -rw-r--r-- | drivers/block/xen-blkback/blkback.c | 99 | ||||
| -rw-r--r-- | drivers/block/xen-blkback/common.h | 14 | ||||
| -rw-r--r-- | drivers/block/xen-blkfront.c | 110 | ||||
| -rw-r--r-- | drivers/cdrom/cdrom.c | 2 | ||||
| -rw-r--r-- | drivers/nvme/host/pci.c | 8 | ||||
| -rw-r--r-- | drivers/nvme/target/core.c | 4 | ||||
| -rw-r--r-- | drivers/nvme/target/fcloop.c | 3 |
12 files changed, 269 insertions, 108 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-xen-blkback b/Documentation/ABI/testing/sysfs-driver-xen-blkback index 8bb43b66eb55..4e7babb3ba1f 100644 --- a/Documentation/ABI/testing/sysfs-driver-xen-blkback +++ b/Documentation/ABI/testing/sysfs-driver-xen-blkback | |||
| @@ -15,3 +15,13 @@ Description: | |||
| 15 | blkback. If the frontend tries to use more than | 15 | blkback. If the frontend tries to use more than |
| 16 | max_persistent_grants, the LRU kicks in and starts | 16 | max_persistent_grants, the LRU kicks in and starts |
| 17 | removing 5% of max_persistent_grants every 100ms. | 17 | removing 5% of max_persistent_grants every 100ms. |
| 18 | |||
| 19 | What: /sys/module/xen_blkback/parameters/persistent_grant_unused_seconds | ||
| 20 | Date: August 2018 | ||
| 21 | KernelVersion: 4.19 | ||
| 22 | Contact: Roger Pau Monné <roger.pau@citrix.com> | ||
| 23 | Description: | ||
| 24 | How long a persistent grant is allowed to remain | ||
| 25 | allocated without being in use. The time is in | ||
| 26 | seconds, 0 means indefinitely long. | ||
| 27 | The default is 60 seconds. | ||
diff --git a/block/blk-wbt.c b/block/blk-wbt.c index 84507d3e9a98..8e20a0677dcf 100644 --- a/block/blk-wbt.c +++ b/block/blk-wbt.c | |||
| @@ -123,16 +123,11 @@ static void rwb_wake_all(struct rq_wb *rwb) | |||
| 123 | } | 123 | } |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct) | 126 | static void wbt_rqw_done(struct rq_wb *rwb, struct rq_wait *rqw, |
| 127 | enum wbt_flags wb_acct) | ||
| 127 | { | 128 | { |
| 128 | struct rq_wb *rwb = RQWB(rqos); | ||
| 129 | struct rq_wait *rqw; | ||
| 130 | int inflight, limit; | 129 | int inflight, limit; |
| 131 | 130 | ||
| 132 | if (!(wb_acct & WBT_TRACKED)) | ||
| 133 | return; | ||
| 134 | |||
| 135 | rqw = get_rq_wait(rwb, wb_acct); | ||
| 136 | inflight = atomic_dec_return(&rqw->inflight); | 131 | inflight = atomic_dec_return(&rqw->inflight); |
| 137 | 132 | ||
| 138 | /* | 133 | /* |
| @@ -166,10 +161,22 @@ static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct) | |||
| 166 | int diff = limit - inflight; | 161 | int diff = limit - inflight; |
| 167 | 162 | ||
| 168 | if (!inflight || diff >= rwb->wb_background / 2) | 163 | if (!inflight || diff >= rwb->wb_background / 2) |
| 169 | wake_up(&rqw->wait); | 164 | wake_up_all(&rqw->wait); |
| 170 | } | 165 | } |
| 171 | } | 166 | } |
| 172 | 167 | ||
| 168 | static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct) | ||
| 169 | { | ||
| 170 | struct rq_wb *rwb = RQWB(rqos); | ||
| 171 | struct rq_wait *rqw; | ||
| 172 | |||
| 173 | if (!(wb_acct & WBT_TRACKED)) | ||
| 174 | return; | ||
| 175 | |||
| 176 | rqw = get_rq_wait(rwb, wb_acct); | ||
| 177 | wbt_rqw_done(rwb, rqw, wb_acct); | ||
| 178 | } | ||
| 179 | |||
| 173 | /* | 180 | /* |
| 174 | * Called on completion of a request. Note that it's also called when | 181 | * Called on completion of a request. Note that it's also called when |
| 175 | * a request is merged, when the request gets freed. | 182 | * a request is merged, when the request gets freed. |
| @@ -481,6 +488,34 @@ static inline unsigned int get_limit(struct rq_wb *rwb, unsigned long rw) | |||
| 481 | return limit; | 488 | return limit; |
| 482 | } | 489 | } |
| 483 | 490 | ||
| 491 | struct wbt_wait_data { | ||
| 492 | struct wait_queue_entry wq; | ||
| 493 | struct task_struct *task; | ||
| 494 | struct rq_wb *rwb; | ||
| 495 | struct rq_wait *rqw; | ||
| 496 | unsigned long rw; | ||
| 497 | bool got_token; | ||
| 498 | }; | ||
| 499 | |||
| 500 | static int wbt_wake_function(struct wait_queue_entry *curr, unsigned int mode, | ||
| 501 | int wake_flags, void *key) | ||
| 502 | { | ||
| 503 | struct wbt_wait_data *data = container_of(curr, struct wbt_wait_data, | ||
| 504 | wq); | ||
| 505 | |||
| 506 | /* | ||
| 507 | * If we fail to get a budget, return -1 to interrupt the wake up | ||
| 508 | * loop in __wake_up_common. | ||
| 509 | */ | ||
| 510 | if (!rq_wait_inc_below(data->rqw, get_limit(data->rwb, data->rw))) | ||
| 511 | return -1; | ||
| 512 | |||
| 513 | data->got_token = true; | ||
| 514 | list_del_init(&curr->entry); | ||
| 515 | wake_up_process(data->task); | ||
| 516 | return 1; | ||
| 517 | } | ||
| 518 | |||
| 484 | /* | 519 | /* |
| 485 | * Block if we will exceed our limit, or if we are currently waiting for | 520 | * Block if we will exceed our limit, or if we are currently waiting for |
| 486 | * the timer to kick off queuing again. | 521 | * the timer to kick off queuing again. |
| @@ -491,19 +526,40 @@ static void __wbt_wait(struct rq_wb *rwb, enum wbt_flags wb_acct, | |||
| 491 | __acquires(lock) | 526 | __acquires(lock) |
| 492 | { | 527 | { |
| 493 | struct rq_wait *rqw = get_rq_wait(rwb, wb_acct); | 528 | struct rq_wait *rqw = get_rq_wait(rwb, wb_acct); |
| 494 | DECLARE_WAITQUEUE(wait, current); | 529 | struct wbt_wait_data data = { |
| 530 | .wq = { | ||
| 531 | .func = wbt_wake_function, | ||
| 532 | .entry = LIST_HEAD_INIT(data.wq.entry), | ||
| 533 | }, | ||
| 534 | .task = current, | ||
| 535 | .rwb = rwb, | ||
| 536 | .rqw = rqw, | ||
| 537 | .rw = rw, | ||
| 538 | }; | ||
| 495 | bool has_sleeper; | 539 | bool has_sleeper; |
| 496 | 540 | ||
| 497 | has_sleeper = wq_has_sleeper(&rqw->wait); | 541 | has_sleeper = wq_has_sleeper(&rqw->wait); |
| 498 | if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw))) | 542 | if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw))) |
| 499 | return; | 543 | return; |
| 500 | 544 | ||
| 501 | add_wait_queue_exclusive(&rqw->wait, &wait); | 545 | prepare_to_wait_exclusive(&rqw->wait, &data.wq, TASK_UNINTERRUPTIBLE); |
| 502 | do { | 546 | do { |
| 503 | set_current_state(TASK_UNINTERRUPTIBLE); | 547 | if (data.got_token) |
| 548 | break; | ||
| 504 | 549 | ||
| 505 | if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw))) | 550 | if (!has_sleeper && |
| 551 | rq_wait_inc_below(rqw, get_limit(rwb, rw))) { | ||
| 552 | finish_wait(&rqw->wait, &data.wq); | ||
| 553 | |||
| 554 | /* | ||
| 555 | * We raced with wbt_wake_function() getting a token, | ||
| 556 | * which means we now have two. Put our local token | ||
| 557 | * and wake anyone else potentially waiting for one. | ||
| 558 | */ | ||
| 559 | if (data.got_token) | ||
| 560 | wbt_rqw_done(rwb, rqw, wb_acct); | ||
| 506 | break; | 561 | break; |
| 562 | } | ||
| 507 | 563 | ||
| 508 | if (lock) { | 564 | if (lock) { |
| 509 | spin_unlock_irq(lock); | 565 | spin_unlock_irq(lock); |
| @@ -511,11 +567,11 @@ static void __wbt_wait(struct rq_wb *rwb, enum wbt_flags wb_acct, | |||
| 511 | spin_lock_irq(lock); | 567 | spin_lock_irq(lock); |
| 512 | } else | 568 | } else |
| 513 | io_schedule(); | 569 | io_schedule(); |
| 570 | |||
| 514 | has_sleeper = false; | 571 | has_sleeper = false; |
| 515 | } while (1); | 572 | } while (1); |
| 516 | 573 | ||
| 517 | __set_current_state(TASK_RUNNING); | 574 | finish_wait(&rqw->wait, &data.wq); |
| 518 | remove_wait_queue(&rqw->wait, &wait); | ||
| 519 | } | 575 | } |
| 520 | 576 | ||
| 521 | static inline bool wbt_should_throttle(struct rq_wb *rwb, struct bio *bio) | 577 | static inline bool wbt_should_throttle(struct rq_wb *rwb, struct bio *bio) |
| @@ -580,11 +636,6 @@ static void wbt_wait(struct rq_qos *rqos, struct bio *bio, spinlock_t *lock) | |||
| 580 | return; | 636 | return; |
| 581 | } | 637 | } |
| 582 | 638 | ||
| 583 | if (current_is_kswapd()) | ||
| 584 | flags |= WBT_KSWAPD; | ||
| 585 | if (bio_op(bio) == REQ_OP_DISCARD) | ||
| 586 | flags |= WBT_DISCARD; | ||
| 587 | |||
| 588 | __wbt_wait(rwb, flags, bio->bi_opf, lock); | 639 | __wbt_wait(rwb, flags, bio->bi_opf, lock); |
| 589 | 640 | ||
| 590 | if (!blk_stat_is_active(rwb->cb)) | 641 | if (!blk_stat_is_active(rwb->cb)) |
diff --git a/block/bsg.c b/block/bsg.c index db588add6ba6..9a442c23a715 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
| @@ -37,7 +37,7 @@ struct bsg_device { | |||
