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 tag 'for-linus-20180825' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
"A few small fixes for this merge window:

- Locking imbalance fix for bcache (Shan Hai)

- A few small fixes for wbt. One is a cleanup/prep, one is a fix for
an existing issue, and the last two are fixes for changes that went
into this merge window (me)"

* tag 'for-linus-20180825' of git://git.kernel.dk/linux-block:
blk-wbt: don't maintain inflight counts if disabled
blk-wbt: fix has-sleeper queueing check
blk-wbt: use wq_has_sleeper() for wq active check
blk-wbt: move disable check into get_limit()
bcache: release dc->writeback_lock properly in bch_writeback_thread()

+38 -22
+18 -1
block/blk-sysfs.c
··· 453 453 else if (val >= 0) 454 454 val *= 1000ULL; 455 455 456 - wbt_set_min_lat(q, val); 456 + /* 457 + * Ensure that the queue is idled, in case the latency update 458 + * ends up either enabling or disabling wbt completely. We can't 459 + * have IO inflight if that happens. 460 + */ 461 + if (q->mq_ops) { 462 + blk_mq_freeze_queue(q); 463 + blk_mq_quiesce_queue(q); 464 + } else 465 + blk_queue_bypass_start(q); 457 466 467 + wbt_set_min_lat(q, val); 458 468 wbt_update_limits(q); 469 + 470 + if (q->mq_ops) { 471 + blk_mq_unquiesce_queue(q); 472 + blk_mq_unfreeze_queue(q); 473 + } else 474 + blk_queue_bypass_end(q); 475 + 459 476 return count; 460 477 } 461 478
+17 -20
block/blk-wbt.c
··· 118 118 for (i = 0; i < WBT_NUM_RWQ; i++) { 119 119 struct rq_wait *rqw = &rwb->rq_wait[i]; 120 120 121 - if (waitqueue_active(&rqw->wait)) 121 + if (wq_has_sleeper(&rqw->wait)) 122 122 wake_up_all(&rqw->wait); 123 123 } 124 124 } ··· 162 162 if (inflight && inflight >= limit) 163 163 return; 164 164 165 - if (waitqueue_active(&rqw->wait)) { 165 + if (wq_has_sleeper(&rqw->wait)) { 166 166 int diff = limit - inflight; 167 167 168 168 if (!inflight || diff >= rwb->wb_background / 2) ··· 449 449 { 450 450 unsigned int limit; 451 451 452 + /* 453 + * If we got disabled, just return UINT_MAX. This ensures that 454 + * we'll properly inc a new IO, and dec+wakeup at the end. 455 + */ 456 + if (!rwb_enabled(rwb)) 457 + return UINT_MAX; 458 + 452 459 if ((rw & REQ_OP_MASK) == REQ_OP_DISCARD) 453 460 return rwb->wb_background; 454 461 ··· 492 485 { 493 486 struct rq_wait *rqw = get_rq_wait(rwb, wb_acct); 494 487 DECLARE_WAITQUEUE(wait, current); 488 + bool has_sleeper; 495 489 496 - /* 497 - * inc it here even if disabled, since we'll dec it at completion. 498 - * this only happens if the task was sleeping in __wbt_wait(), 499 - * and someone turned it off at the same time. 500 - */ 501 - if (!rwb_enabled(rwb)) { 502 - atomic_inc(&rqw->inflight); 503 - return; 504 - } 505 - 506 - if (!waitqueue_active(&rqw->wait) 507 - && rq_wait_inc_below(rqw, get_limit(rwb, rw))) 490 + has_sleeper = wq_has_sleeper(&rqw->wait); 491 + if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw))) 508 492 return; 509 493 510 494 add_wait_queue_exclusive(&rqw->wait, &wait); 511 495 do { 512 496 set_current_state(TASK_UNINTERRUPTIBLE); 513 497 514 - if (!rwb_enabled(rwb)) { 515 - atomic_inc(&rqw->inflight); 516 - break; 517 - } 518 - 519 - if (rq_wait_inc_below(rqw, get_limit(rwb, rw))) 498 + if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw))) 520 499 break; 521 500 522 501 if (lock) { ··· 511 518 spin_lock_irq(lock); 512 519 } else 513 520 io_schedule(); 521 + has_sleeper = false; 514 522 } while (1); 515 523 516 524 __set_current_state(TASK_RUNNING); ··· 539 545 static enum wbt_flags bio_to_wbt_flags(struct rq_wb *rwb, struct bio *bio) 540 546 { 541 547 enum wbt_flags flags = 0; 548 + 549 + if (!rwb_enabled(rwb)) 550 + return 0; 542 551 543 552 if (bio_op(bio) == REQ_OP_READ) { 544 553 flags = WBT_READ;
+3 -1
drivers/md/bcache/writeback.c
··· 685 685 * data on cache. BCACHE_DEV_DETACHING flag is set in 686 686 * bch_cached_dev_detach(). 687 687 */ 688 - if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags)) 688 + if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags)) { 689 + up_write(&dc->writeback_lock); 689 690 break; 691 + } 690 692 } 691 693 692 694 up_write(&dc->writeback_lock);