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:
"Mainly sending this off now for the writeback fixes, since they fix a
real regression introduced with the cgroup writeback changes. The
NVMe fix could wait for next pull for this series, but it's simple
enough that we might as well include it.

This contains:

- two cgroup writeback fixes from Tejun, fixing a user reported issue
with luks crypt devices hanging when being closed.

- NVMe error cleanup fix from Jon Derrick, fixing a case where we'd
attempt to free an unregistered IRQ"

* 'for-linus' of git://git.kernel.dk/linux-block:
NVMe: Fix irq freeing when queue_request_irq fails
writeback: don't drain bdi_writeback_congested on bdi destruction
writeback: don't embed root bdi_writeback_congested in bdi_writeback

+77 -52
+7 -2
drivers/block/nvme-core.c
··· 1474 1474 nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; 1475 1475 nvmeq->q_depth = depth; 1476 1476 nvmeq->qid = qid; 1477 + nvmeq->cq_vector = -1; 1477 1478 dev->queues[qid] = nvmeq; 1478 1479 1479 1480 /* make sure queue descriptor is set before queue count, for kthread */ ··· 1727 1726 1728 1727 nvmeq->cq_vector = 0; 1729 1728 result = queue_request_irq(dev, nvmeq, nvmeq->irqname); 1730 - if (result) 1729 + if (result) { 1730 + nvmeq->cq_vector = -1; 1731 1731 goto free_nvmeq; 1732 + } 1732 1733 1733 1734 return result; 1734 1735 ··· 2216 2213 dev->max_qid = nr_io_queues; 2217 2214 2218 2215 result = queue_request_irq(dev, adminq, adminq->irqname); 2219 - if (result) 2216 + if (result) { 2217 + adminq->cq_vector = -1; 2220 2218 goto free_queues; 2219 + } 2221 2220 2222 2221 /* Free previously allocated queues that are no longer usable */ 2223 2222 nvme_free_queues(dev, nr_io_queues + 1);
+3 -2
include/linux/backing-dev-defs.h
··· 50 50 */ 51 51 struct bdi_writeback_congested { 52 52 unsigned long state; /* WB_[a]sync_congested flags */ 53 + atomic_t refcnt; /* nr of attached wb's and blkg */ 53 54 54 55 #ifdef CONFIG_CGROUP_WRITEBACK 55 56 struct backing_dev_info *bdi; /* the associated bdi */ 56 - atomic_t refcnt; /* nr of attached wb's and blkg */ 57 57 int blkcg_id; /* ID of the associated blkcg */ 58 58 struct rb_node rb_node; /* on bdi->cgwb_congestion_tree */ 59 59 #endif ··· 150 150 atomic_long_t tot_write_bandwidth; 151 151 152 152 struct bdi_writeback wb; /* the root writeback info for this bdi */ 153 - struct bdi_writeback_congested wb_congested; /* its congested state */ 154 153 #ifdef CONFIG_CGROUP_WRITEBACK 155 154 struct radix_tree_root cgwb_tree; /* radix tree of active cgroup wbs */ 156 155 struct rb_root cgwb_congested_tree; /* their congested states */ 157 156 atomic_t usage_cnt; /* counts both cgwbs and cgwb_contested's */ 157 + #else 158 + struct bdi_writeback_congested *wb_congested; 158 159 #endif 159 160 wait_queue_head_t wb_waitq; 160 161
+5 -1
include/linux/backing-dev.h
··· 15 15 #include <linux/writeback.h> 16 16 #include <linux/blk-cgroup.h> 17 17 #include <linux/backing-dev-defs.h> 18 + #include <linux/slab.h> 18 19 19 20 int __must_check bdi_init(struct backing_dev_info *bdi); 20 21 void bdi_destroy(struct backing_dev_info *bdi); ··· 466 465 static inline struct bdi_writeback_congested * 467 466 wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp) 468 467 { 469 - return bdi->wb.congested; 468 + atomic_inc(&bdi->wb_congested->refcnt); 469 + return bdi->wb_congested; 470 470 } 471 471 472 472 static inline void wb_congested_put(struct bdi_writeback_congested *congested) 473 473 { 474 + if (atomic_dec_and_test(&congested->refcnt)) 475 + kfree(congested); 474 476 } 475 477 476 478 static inline struct bdi_writeback *wb_find_current(struct backing_dev_info *bdi)
+62 -47
mm/backing-dev.c
··· 287 287 #define INIT_BW (100 << (20 - PAGE_SHIFT)) 288 288 289 289 static int wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi, 290 - gfp_t gfp) 290 + int blkcg_id, gfp_t gfp) 291 291 { 292 292 int i, err; 293 293 ··· 311 311 INIT_LIST_HEAD(&wb->work_list); 312 312 INIT_DELAYED_WORK(&wb->dwork, wb_workfn); 313 313 314 + wb->congested = wb_congested_get_create(bdi, blkcg_id, gfp); 315 + if (!wb->congested) 316 + return -ENOMEM; 317 + 314 318 err = fprop_local_init_percpu(&wb->completions, gfp); 315 319 if (err) 316 - return err; 320 + goto out_put_cong; 317 321 318 322 for (i = 0; i < NR_WB_STAT_ITEMS; i++) { 319 323 err = percpu_counter_init(&wb->stat[i], 0, gfp); 320 - if (err) { 321 - while (--i) 322 - percpu_counter_destroy(&wb->stat[i]); 323 - fprop_local_destroy_percpu(&wb->completions); 324 - return err; 325 - } 324 + if (err) 325 + goto out_destroy_stat; 326 326 } 327 327 328 328 return 0; 329 + 330 + out_destroy_stat: 331 + while (--i) 332 + percpu_counter_destroy(&wb->stat[i]); 333 + fprop_local_destroy_percpu(&wb->completions); 334 + out_put_cong: 335 + wb_congested_put(wb->congested); 336 + return err; 329 337 } 330 338 331 339 /* ··· 369 361 percpu_counter_destroy(&wb->stat[i]); 370 362 371 363 fprop_local_destroy_percpu(&wb->completions); 364 + wb_congested_put(wb->congested); 372 365 } 373 366 374 367 #ifdef CONFIG_CGROUP_WRITEBACK ··· 401 392 struct bdi_writeback_congested *new_congested = NULL, *congested; 402 393 struct rb_node **node, *parent; 403 394 unsigned long flags; 404 - 405 - if (blkcg_id == 1) 406 - return &bdi->wb_congested; 407 395 retry: 408 396 spin_lock_irqsave(&cgwb_lock, flags); 409 397 ··· 425 419 new_congested = NULL; 426 420 rb_link_node(&congested->rb_node, parent, node); 427 421 rb_insert_color(&congested->rb_node, &bdi->cgwb_congested_tree); 428 - atomic_inc(&bdi->usage_cnt); 429 422 goto found; 430 423 } 431 424 ··· 455 450 */ 456 451 void wb_congested_put(struct bdi_writeback_congested *congested) 457 452 { 458 - struct backing_dev_info *bdi = congested->bdi; 459 453 unsigned long flags; 460 - 461 - if (congested->blkcg_id == 1) 462 - return; 463 454 464 455 local_irq_save(flags); 465 456 if (!atomic_dec_and_lock(&congested->refcnt, &cgwb_lock)) { ··· 463 462 return; 464 463 } 465 464 466 - rb_erase(&congested->rb_node, &congested->bdi->cgwb_congested_tree); 465 + /* bdi might already have been destroyed leaving @congested unlinked */ 466 + if (congested->bdi) { 467 + rb_erase(&congested->rb_node, 468 + &congested->bdi->cgwb_congested_tree); 469 + congested->bdi = NULL; 470 + } 471 + 467 472 spin_unlock_irqrestore(&cgwb_lock, flags); 468 473 kfree(congested); 469 - 470 - if (atomic_dec_and_test(&bdi->usage_cnt)) 471 - wake_up_all(&cgwb_release_wait); 472 474 } 473 475 474 476 static void cgwb_release_workfn(struct work_struct *work) ··· 484 480 485 481 css_put(wb->memcg_css); 486 482 css_put(wb->blkcg_css); 487 - wb_congested_put(wb->congested); 488 483 489 484 fprop_local_destroy_percpu(&wb->memcg_completions); 490 485 percpu_ref_exit(&wb->refcnt); ··· 544 541 if (!wb) 545 542 return -ENOMEM; 546 543 547 - ret = wb_init(wb, bdi, gfp); 544 + ret = wb_init(wb, bdi, blkcg_css->id, gfp); 548 545 if (ret) 549 546 goto err_free; 550 547 ··· 555 552 ret = fprop_local_init_percpu(&wb->memcg_completions, gfp); 556 553 if (ret) 557 554 goto err_ref_exit; 558 - 559 - wb->congested = wb_congested_get_create(bdi, blkcg_css->id, gfp); 560 - if (!wb->congested) { 561 - ret = -ENOMEM; 562 - goto err_fprop_exit; 563 - } 564 555 565 556 wb->memcg_css = memcg_css; 566 557 wb->blkcg_css = blkcg_css; ··· 585 588 if (ret) { 586 589 if (ret == -EEXIST) 587 590 ret = 0; 588 - goto err_put_congested; 591 + goto err_fprop_exit; 589 592 } 590 593 goto out_put; 591 594 592 - err_put_congested: 593 - wb_congested_put(wb->congested); 594 595 err_fprop_exit: 595 596 fprop_local_destroy_percpu(&wb->memcg_completions); 596 597 err_ref_exit: ··· 657 662 return wb; 658 663 } 659 664 660 - static void cgwb_bdi_init(struct backing_dev_info *bdi) 665 + static int cgwb_bdi_init(struct backing_dev_info *bdi) 661 666 { 662 - bdi->wb.memcg_css = mem_cgroup_root_css; 663 - bdi->wb.blkcg_css = blkcg_root_css; 664 - bdi->wb_congested.blkcg_id = 1; 667 + int ret; 668 + 665 669 INIT_RADIX_TREE(&bdi->cgwb_tree, GFP_ATOMIC); 666 670 bdi->cgwb_congested_tree = RB_ROOT; 667 671 atomic_set(&bdi->usage_cnt, 1); 672 + 673 + ret = wb_init(&bdi->wb, bdi, 1, GFP_KERNEL); 674 + if (!ret) { 675 + bdi->wb.memcg_css = mem_cgroup_root_css; 676 + bdi->wb.blkcg_css = blkcg_root_css; 677 + } 678 + return ret; 668 679 } 669 680 670 681 static void cgwb_bdi_destroy(struct backing_dev_info *bdi) 671 682 { 672 683 struct radix_tree_iter iter; 684 + struct bdi_writeback_congested *congested, *congested_n; 673 685 void **slot; 674 686 675 687 WARN_ON(test_bit(WB_registered, &bdi->wb.state)); 676 688 677 689 spin_lock_irq(&cgwb_lock); 690 + 678 691 radix_tree_for_each_slot(slot, &bdi->cgwb_tree, &iter, 0) 679 692 cgwb_kill(*slot); 693 + 694 + rbtree_postorder_for_each_entry_safe(congested, congested_n, 695 + &bdi->cgwb_congested_tree, rb_node) { 696 + rb_erase(&congested->rb_node, &bdi->cgwb_congested_tree); 697 + congested->bdi = NULL; /* mark @congested unlinked */ 698 + } 699 + 680 700 spin_unlock_irq(&cgwb_lock); 681 701 682 702 /* ··· 742 732 743 733 #else /* CONFIG_CGROUP_WRITEBACK */ 744 734 745 - static void cgwb_bdi_init(struct backing_dev_info *bdi) { } 735 + static int cgwb_bdi_init(struct backing_dev_info *bdi) 736 + { 737 + int err; 738 + 739 + bdi->wb_congested = kzalloc(sizeof(*bdi->wb_congested), GFP_KERNEL); 740 + if (!bdi->wb_congested) 741 + return -ENOMEM; 742 + 743 + err = wb_init(&bdi->wb, bdi, 1, GFP_KERNEL); 744 + if (err) { 745 + kfree(bdi->wb_congested); 746 + return err; 747 + } 748 + return 0; 749 + } 750 + 746 751 static void cgwb_bdi_destroy(struct backing_dev_info *bdi) { } 747 752 748 753 #endif /* CONFIG_CGROUP_WRITEBACK */ 749 754 750 755 int bdi_init(struct backing_dev_info *bdi) 751 756 { 752 - int err; 753 - 754 757 bdi->dev = NULL; 755 758 756 759 bdi->min_ratio = 0; ··· 772 749 INIT_LIST_HEAD(&bdi->bdi_list); 773 750 init_waitqueue_head(&bdi->wb_waitq); 774 751 775 - err = wb_init(&bdi->wb, bdi, GFP_KERNEL); 776 - if (err) 777 - return err; 778 - 779 - bdi->wb_congested.state = 0; 780 - bdi->wb.congested = &bdi->wb_congested; 781 - 782 - cgwb_bdi_init(bdi); 783 - return 0; 752 + return cgwb_bdi_init(bdi); 784 753 } 785 754 EXPORT_SYMBOL(bdi_init); 786 755