Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'bcache-updates-6.19' into for-6.19/block

Merge bcache updates from Coly for 6.19:

"The major change is from me, which is to remove useless discard
interface and code for cache device (not the backing device). And the
last patch about gc latency is a cooperative result from Robert Pang
(Google), Mingzhe Zou (Easystack) and me, by inspired from their
previous works, I compose the final version and Robert prvides positive
benchmark result.

Marco contributes 2 patches to improve the usage of per-cpu system
work queue. Gustavo contributes a patch to fix the not-at-end
flexible-array member warning by gcc14. And Qianfeng contributes a code
cleanup patch to remove redundant __GFP_NOWARN."

Link: https://lore.kernel.org/linux-block/20251113053630.54218-1-colyli@fnnas.com/
Signed-off-by: Jens Axboe <axboe@kernel.dk>

* bcache-updates-6.19:
bcache: Avoid -Wflex-array-member-not-at-end warning
bcache: WQ_PERCPU added to alloc_workqueue users
bcache: replace use of system_wq with system_percpu_wq
bcache: remove redundant __GFP_NOWARN
bcache: reduce gc latency by processing less nodes and sleep less time
bcache: remove discard sysfs interface document
bcache: drop discard sysfs interface
bcache: remove discard code from alloc.c
bcache: get rid of discard code from journal

+71 -200
-7
Documentation/ABI/testing/sysfs-block-bcache
··· 106 106 will be discarded from the cache. Should not be turned off with 107 107 writeback caching enabled. 108 108 109 - What: /sys/block/<disk>/bcache/discard 110 - Date: November 2010 111 - Contact: Kent Overstreet <kent.overstreet@gmail.com> 112 - Description: 113 - For a cache, a boolean allowing discard/TRIM to be turned off 114 - or back on if the device supports it. 115 - 116 109 What: /sys/block/<disk>/bcache/bucket_size 117 110 Date: November 2010 118 111 Contact: Kent Overstreet <kent.overstreet@gmail.com>
+2 -11
Documentation/admin-guide/bcache.rst
··· 17 17 It's designed around the performance characteristics of SSDs - it only allocates 18 18 in erase block sized buckets, and it uses a hybrid btree/log to track cached 19 19 extents (which can be anywhere from a single sector to the bucket size). It's 20 - designed to avoid random writes at all costs; it fills up an erase block 21 - sequentially, then issues a discard before reusing it. 20 + designed to avoid random writes at all costs. 22 21 23 22 Both writethrough and writeback caching are supported. Writeback defaults to 24 23 off, but can be switched on and off arbitrarily at runtime. Bcache goes to ··· 617 618 cache_replacement_policy 618 619 One of either lru, fifo or random. 619 620 620 - discard 621 - Boolean; if on a discard/TRIM will be issued to each bucket before it is 622 - reused. Defaults to off, since SATA TRIM is an unqueued command (and thus 623 - slow). 624 - 625 621 freelist_percent 626 622 Size of the freelist as a percentage of nbuckets. Can be written to to 627 623 increase the number of buckets kept on the freelist, which lets you 628 624 artificially reduce the size of the cache at runtime. Mostly for testing 629 - purposes (i.e. testing how different size caches affect your hit rate), but 630 - since buckets are discarded when they move on to the freelist will also make 631 - the SSD's garbage collection easier by effectively giving it more reserved 632 - space. 625 + purposes (i.e. testing how different size caches affect your hit rate). 633 626 634 627 io_errors 635 628 Number of errors that have occurred, decayed by io_error_halflife.
+8 -17
drivers/md/bcache/alloc.c
··· 24 24 * Since the gens and priorities are all stored contiguously on disk, we can 25 25 * batch this up: We fill up the free_inc list with freshly invalidated buckets, 26 26 * call prio_write(), and when prio_write() finishes we pull buckets off the 27 - * free_inc list and optionally discard them. 27 + * free_inc list. 28 28 * 29 29 * free_inc isn't the only freelist - if it was, we'd often to sleep while 30 30 * priorities and gens were being written before we could allocate. c->free is a 31 31 * smaller freelist, and buckets on that list are always ready to be used. 32 - * 33 - * If we've got discards enabled, that happens when a bucket moves from the 34 - * free_inc list to the free list. 35 32 * 36 33 * There is another freelist, because sometimes we have buckets that we know 37 34 * have nothing pointing into them - these we can reuse without waiting for 38 35 * priorities to be rewritten. These come from freed btree nodes and buckets 39 36 * that garbage collection discovered no longer had valid keys pointing into 40 37 * them (because they were overwritten). That's the unused list - buckets on the 41 - * unused list move to the free list, optionally being discarded in the process. 38 + * unused list move to the free list. 42 39 * 43 40 * It's also important to ensure that gens don't wrap around - with respect to 44 41 * either the oldest gen in the btree or the gen on disk. This is quite ··· 115 118 /* 116 119 * Background allocation thread: scans for buckets to be invalidated, 117 120 * invalidates them, rewrites prios/gens (marking them as invalidated on disk), 118 - * then optionally issues discard commands to the newly free buckets, then puts 119 - * them on the various freelists. 121 + * then puts them on the various freelists. 120 122 */ 121 123 122 124 static inline bool can_inc_bucket_gen(struct bucket *b) ··· 317 321 while (1) { 318 322 /* 319 323 * First, we pull buckets off of the unused and free_inc lists, 320 - * possibly issue discards to them, then we add the bucket to 321 - * the free list: 324 + * then we add the bucket to the free list: 322 325 */ 323 326 while (1) { 324 327 long bucket; 325 328 326 329 if (!fifo_pop(&ca->free_inc, bucket)) 327 330 break; 328 - 329 - if (ca->discard) { 330 - mutex_unlock(&ca->set->bucket_lock); 331 - blkdev_issue_discard(ca->bdev, 332 - bucket_to_sector(ca->set, bucket), 333 - ca->sb.bucket_size, GFP_KERNEL); 334 - mutex_lock(&ca->set->bucket_lock); 335 - } 336 331 337 332 allocator_wait(ca, bch_allocator_push(ca, bucket)); 338 333 wake_up(&ca->set->btree_cache_wait); ··· 399 412 TASK_UNINTERRUPTIBLE); 400 413 401 414 mutex_unlock(&ca->set->bucket_lock); 415 + 416 + atomic_inc(&ca->set->bucket_wait_cnt); 402 417 schedule(); 418 + atomic_dec(&ca->set->bucket_wait_cnt); 419 + 403 420 mutex_lock(&ca->set->bucket_lock); 404 421 } while (!fifo_pop(&ca->free[RESERVE_NONE], r) && 405 422 !fifo_pop(&ca->free[reserve], r));
+2 -4
drivers/md/bcache/bcache.h
··· 447 447 * free_inc: Incoming buckets - these are buckets that currently have 448 448 * cached data in them, and we can't reuse them until after we write 449 449 * their new gen to disk. After prio_write() finishes writing the new 450 - * gens/prios, they'll be moved to the free list (and possibly discarded 451 - * in the process) 450 + * gens/prios, they'll be moved to the free list. 452 451 */ 453 452 DECLARE_FIFO(long, free)[RESERVE_NR]; 454 453 DECLARE_FIFO(long, free_inc); ··· 465 466 * cpu 466 467 */ 467 468 unsigned int invalidate_needs_gc; 468 - 469 - bool discard; /* Get rid of? */ 470 469 471 470 struct journal_device journal; 472 471 ··· 604 607 */ 605 608 atomic_t prio_blocked; 606 609 wait_queue_head_t bucket_wait; 610 + atomic_t bucket_wait_cnt; 607 611 608 612 /* 609 613 * For any bio we don't skip we subtract the number of sectors from
+6 -2
drivers/md/bcache/bset.h
··· 327 327 /* Fixed-size btree_iter that can be allocated on the stack */ 328 328 329 329 struct btree_iter_stack { 330 - struct btree_iter iter; 331 - struct btree_iter_set stack_data[MAX_BSETS]; 330 + /* Must be last as it ends in a flexible-array member. */ 331 + TRAILING_OVERLAP(struct btree_iter, iter, data, 332 + struct btree_iter_set stack_data[MAX_BSETS]; 333 + ); 332 334 }; 335 + static_assert(offsetof(struct btree_iter_stack, iter.data) == 336 + offsetof(struct btree_iter_stack, stack_data)); 333 337 334 338 typedef bool (*ptr_filter_fn)(struct btree_keys *b, const struct bkey *k); 335 339
+27 -26
drivers/md/bcache/btree.c
··· 89 89 * Test module load/unload 90 90 */ 91 91 92 - #define MAX_GC_TIMES 100 93 - #define MIN_GC_NODES 100 92 + #define MAX_GC_TIMES_SHIFT 7 /* 128 loops */ 93 + #define GC_NODES_MIN 10 94 + #define GC_SLEEP_MS_MIN 10 94 95 #define GC_SLEEP_MS 100 95 96 96 97 #define PTR_DIRTY_BIT (((uint64_t) 1 << 36)) ··· 372 371 SET_PTR_OFFSET(&k.key, 0, PTR_OFFSET(&k.key, 0) + 373 372 bset_sector_offset(&b->keys, i)); 374 373 375 - if (!bch_bio_alloc_pages(b->bio, __GFP_NOWARN|GFP_NOWAIT)) { 374 + if (!bch_bio_alloc_pages(b->bio, GFP_NOWAIT)) { 376 375 struct bio_vec *bv; 377 376 void *addr = (void *) ((unsigned long) i & ~(PAGE_SIZE - 1)); 378 377 struct bvec_iter_all iter_all; ··· 1579 1578 1580 1579 static size_t btree_gc_min_nodes(struct cache_set *c) 1581 1580 { 1582 - size_t min_nodes; 1581 + size_t min_nodes = GC_NODES_MIN; 1583 1582 1584 - /* 1585 - * Since incremental GC would stop 100ms when front 1586 - * side I/O comes, so when there are many btree nodes, 1587 - * if GC only processes constant (100) nodes each time, 1588 - * GC would last a long time, and the front side I/Os 1589 - * would run out of the buckets (since no new bucket 1590 - * can be allocated during GC), and be blocked again. 1591 - * So GC should not process constant nodes, but varied 1592 - * nodes according to the number of btree nodes, which 1593 - * realized by dividing GC into constant(100) times, 1594 - * so when there are many btree nodes, GC can process 1595 - * more nodes each time, otherwise, GC will process less 1596 - * nodes each time (but no less than MIN_GC_NODES) 1597 - */ 1598 - min_nodes = c->gc_stats.nodes / MAX_GC_TIMES; 1599 - if (min_nodes < MIN_GC_NODES) 1600 - min_nodes = MIN_GC_NODES; 1583 + if (atomic_read(&c->search_inflight) == 0) { 1584 + size_t n = c->gc_stats.nodes >> MAX_GC_TIMES_SHIFT; 1585 + 1586 + if (min_nodes < n) 1587 + min_nodes = n; 1588 + } 1601 1589 1602 1590 return min_nodes; 1603 1591 } 1604 1592 1593 + static uint64_t btree_gc_sleep_ms(struct cache_set *c) 1594 + { 1595 + uint64_t sleep_ms; 1596 + 1597 + if (atomic_read(&c->bucket_wait_cnt) > 0) 1598 + sleep_ms = GC_SLEEP_MS_MIN; 1599 + else 1600 + sleep_ms = GC_SLEEP_MS; 1601 + 1602 + return sleep_ms; 1603 + } 1605 1604 1606 1605 static int btree_gc_recurse(struct btree *b, struct btree_op *op, 1607 1606 struct closure *writes, struct gc_stat *gc) ··· 1669 1668 memmove(r + 1, r, sizeof(r[0]) * (GC_MERGE_NODES - 1)); 1670 1669 r->b = NULL; 1671 1670 1672 - if (atomic_read(&b->c->search_inflight) && 1673 - gc->nodes >= gc->nodes_pre + btree_gc_min_nodes(b->c)) { 1671 + if (gc->nodes >= (gc->nodes_pre + btree_gc_min_nodes(b->c))) { 1674 1672 gc->nodes_pre = gc->nodes; 1675 1673 ret = -EAGAIN; 1676 1674 break; ··· 1846 1846 cond_resched(); 1847 1847 1848 1848 if (ret == -EAGAIN) 1849 - schedule_timeout_interruptible(msecs_to_jiffies 1850 - (GC_SLEEP_MS)); 1849 + schedule_timeout_interruptible( 1850 + msecs_to_jiffies(btree_gc_sleep_ms(c))); 1851 1851 else if (ret) 1852 1852 pr_warn("gc failed!\n"); 1853 1853 } while (ret && !test_bit(CACHE_SET_IO_DISABLE, &c->flags)); ··· 2822 2822 2823 2823 int __init bch_btree_init(void) 2824 2824 { 2825 - btree_io_wq = alloc_workqueue("bch_btree_io", WQ_MEM_RECLAIM, 0); 2825 + btree_io_wq = alloc_workqueue("bch_btree_io", 2826 + WQ_MEM_RECLAIM | WQ_PERCPU, 0); 2826 2827 if (!btree_io_wq) 2827 2828 return -ENOMEM; 2828 2829
+8 -85
drivers/md/bcache/journal.c
··· 275 275 * ja->cur_idx 276 276 */ 277 277 ja->cur_idx = i; 278 - ja->last_idx = ja->discard_idx = (i + 1) % 279 - ca->sb.njournal_buckets; 278 + ja->last_idx = (i + 1) % ca->sb.njournal_buckets; 280 279 281 280 } 282 281 ··· 335 336 } 336 337 } 337 338 338 - static bool is_discard_enabled(struct cache_set *s) 339 - { 340 - struct cache *ca = s->cache; 341 - 342 - if (ca->discard) 343 - return true; 344 - 345 - return false; 346 - } 347 - 348 339 int bch_journal_replay(struct cache_set *s, struct list_head *list) 349 340 { 350 341 int ret = 0, keys = 0, entries = 0; ··· 349 360 BUG_ON(i->pin && atomic_read(i->pin) != 1); 350 361 351 362 if (n != i->j.seq) { 352 - if (n == start && is_discard_enabled(s)) 353 - pr_info("journal entries %llu-%llu may be discarded! (replaying %llu-%llu)\n", 354 - n, i->j.seq - 1, start, end); 355 - else { 356 - pr_err("journal entries %llu-%llu missing! (replaying %llu-%llu)\n", 357 - n, i->j.seq - 1, start, end); 358 - ret = -EIO; 359 - goto err; 360 - } 363 + pr_err("journal entries %llu-%llu missing! (replaying %llu-%llu)\n", 364 + n, i->j.seq - 1, start, end); 365 + ret = -EIO; 366 + goto err; 361 367 } 362 368 363 369 for (k = i->j.start; ··· 552 568 553 569 #define last_seq(j) ((j)->seq - fifo_used(&(j)->pin) + 1) 554 570 555 - static void journal_discard_endio(struct bio *bio) 556 - { 557 - struct journal_device *ja = 558 - container_of(bio, struct journal_device, discard_bio); 559 - struct cache *ca = container_of(ja, struct cache, journal); 560 - 561 - atomic_set(&ja->discard_in_flight, DISCARD_DONE); 562 - 563 - closure_wake_up(&ca->set->journal.wait); 564 - closure_put(&ca->set->cl); 565 - } 566 - 567 - static void journal_discard_work(struct work_struct *work) 568 - { 569 - struct journal_device *ja = 570 - container_of(work, struct journal_device, discard_work); 571 - 572 - submit_bio(&ja->discard_bio); 573 - } 574 - 575 - static void do_journal_discard(struct cache *ca) 576 - { 577 - struct journal_device *ja = &ca->journal; 578 - struct bio *bio = &ja->discard_bio; 579 - 580 - if (!ca->discard) { 581 - ja->discard_idx = ja->last_idx; 582 - return; 583 - } 584 - 585 - switch (atomic_read(&ja->discard_in_flight)) { 586 - case DISCARD_IN_FLIGHT: 587 - return; 588 - 589 - case DISCARD_DONE: 590 - ja->discard_idx = (ja->discard_idx + 1) % 591 - ca->sb.njournal_buckets; 592 - 593 - atomic_set(&ja->discard_in_flight, DISCARD_READY); 594 - fallthrough; 595 - 596 - case DISCARD_READY: 597 - if (ja->discard_idx == ja->last_idx) 598 - return; 599 - 600 - atomic_set(&ja->discard_in_flight, DISCARD_IN_FLIGHT); 601 - 602 - bio_init_inline(bio, ca->bdev, 1, REQ_OP_DISCARD); 603 - bio->bi_iter.bi_sector = bucket_to_sector(ca->set, 604 - ca->sb.d[ja->discard_idx]); 605 - bio->bi_iter.bi_size = bucket_bytes(ca); 606 - bio->bi_end_io = journal_discard_endio; 607 - 608 - closure_get(&ca->set->cl); 609 - INIT_WORK(&ja->discard_work, journal_discard_work); 610 - queue_work(bch_journal_wq, &ja->discard_work); 611 - } 612 - } 613 - 614 571 static unsigned int free_journal_buckets(struct cache_set *c) 615 572 { 616 573 struct journal *j = &c->journal; ··· 560 635 unsigned int n; 561 636 562 637 /* In case njournal_buckets is not power of 2 */ 563 - if (ja->cur_idx >= ja->discard_idx) 564 - n = ca->sb.njournal_buckets + ja->discard_idx - ja->cur_idx; 638 + if (ja->cur_idx >= ja->last_idx) 639 + n = ca->sb.njournal_buckets + ja->last_idx - ja->cur_idx; 565 640 else 566 - n = ja->discard_idx - ja->cur_idx; 641 + n = ja->last_idx - ja->cur_idx; 567 642 568 643 if (n > (1 + j->do_reserve)) 569 644 return n - (1 + j->do_reserve); ··· 592 667 ja->seq[ja->last_idx] < last_seq) 593 668 ja->last_idx = (ja->last_idx + 1) % 594 669 ca->sb.njournal_buckets; 595 - 596 - do_journal_discard(ca); 597 670 598 671 if (c->journal.blocks_free) 599 672 goto out;
-13
drivers/md/bcache/journal.h
··· 139 139 /* Last journal bucket that still contains an open journal entry */ 140 140 unsigned int last_idx; 141 141 142 - /* Next journal bucket to be discarded */ 143 - unsigned int discard_idx; 144 - 145 - #define DISCARD_READY 0 146 - #define DISCARD_IN_FLIGHT 1 147 - #define DISCARD_DONE 2 148 - /* 1 - discard in flight, -1 - discard completed */ 149 - atomic_t discard_in_flight; 150 - 151 - struct work_struct discard_work; 152 - struct bio discard_bio; 153 - struct bio_vec discard_bv; 154 - 155 142 /* Bio for journal reads/writes to this device */ 156 143 struct bio bio; 157 144 struct bio_vec bv[8];
+16 -17
drivers/md/bcache/super.c
··· 1388 1388 bch_cache_accounting_destroy(&dc->accounting); 1389 1389 kobject_del(&d->kobj); 1390 1390 1391 - continue_at(cl, cached_dev_free, system_wq); 1391 + continue_at(cl, cached_dev_free, system_percpu_wq); 1392 1392 } 1393 1393 1394 1394 static int cached_dev_init(struct cached_dev *dc, unsigned int block_size) ··· 1400 1400 __module_get(THIS_MODULE); 1401 1401 INIT_LIST_HEAD(&dc->list); 1402 1402 closure_init(&dc->disk.cl, NULL); 1403 - set_closure_fn(&dc->disk.cl, cached_dev_flush, system_wq); 1403 + set_closure_fn(&dc->disk.cl, cached_dev_flush, system_percpu_wq); 1404 1404 kobject_init(&dc->disk.kobj, &bch_cached_dev_ktype); 1405 1405 INIT_WORK(&dc->detach, cached_dev_detach_finish); 1406 1406 sema_init(&dc->sb_write_mutex, 1); ··· 1513 1513 bcache_device_unlink(d); 1514 1514 mutex_unlock(&bch_register_lock); 1515 1515 kobject_del(&d->kobj); 1516 - continue_at(cl, flash_dev_free, system_wq); 1516 + continue_at(cl, flash_dev_free, system_percpu_wq); 1517 1517 } 1518 1518 1519 1519 static int flash_dev_run(struct cache_set *c, struct uuid_entry *u) ··· 1525 1525 goto err_ret; 1526 1526 1527 1527 closure_init(&d->cl, NULL); 1528 - set_closure_fn(&d->cl, flash_dev_flush, system_wq); 1528 + set_closure_fn(&d->cl, flash_dev_flush, system_percpu_wq); 1529 1529 1530 1530 kobject_init(&d->kobj, &bch_flash_dev_ktype); 1531 1531 ··· 1833 1833 1834 1834 mutex_unlock(&bch_register_lock); 1835 1835 1836 - continue_at(cl, cache_set_flush, system_wq); 1836 + continue_at(cl, cache_set_flush, system_percpu_wq); 1837 1837 } 1838 1838 1839 1839 void bch_cache_set_stop(struct cache_set *c) ··· 1863 1863 1864 1864 __module_get(THIS_MODULE); 1865 1865 closure_init(&c->cl, NULL); 1866 - set_closure_fn(&c->cl, cache_set_free, system_wq); 1866 + set_closure_fn(&c->cl, cache_set_free, system_percpu_wq); 1867 1867 1868 1868 closure_init(&c->caching, &c->cl); 1869 - set_closure_fn(&c->caching, __cache_set_unregister, system_wq); 1869 + set_closure_fn(&c->caching, __cache_set_unregister, system_percpu_wq); 1870 1870 1871 1871 /* Maybe create continue_at_noreturn() and use it here? */ 1872 1872 closure_set_stopped(&c->cl); ··· 1939 1939 if (!c->uuids) 1940 1940 goto err; 1941 1941 1942 - c->moving_gc_wq = alloc_workqueue("bcache_gc", WQ_MEM_RECLAIM, 0); 1942 + c->moving_gc_wq = alloc_workqueue("bcache_gc", 1943 + WQ_MEM_RECLAIM | WQ_PERCPU, 0); 1943 1944 if (!c->moving_gc_wq) 1944 1945 goto err; 1945 1946 ··· 2383 2382 ca->bdev = file_bdev(bdev_file); 2384 2383 ca->sb_disk = sb_disk; 2385 2384 2386 - if (bdev_max_discard_sectors(file_bdev(bdev_file))) 2387 - ca->discard = CACHE_DISCARD(&ca->sb); 2388 - 2389 2385 ret = cache_alloc(ca); 2390 2386 if (ret != 0) { 2391 2387 if (ret == -ENOMEM) ··· 2529 2531 INIT_DELAYED_WORK(&args->reg_work, register_cache_worker); 2530 2532 2531 2533 /* 10 jiffies is enough for a delay */ 2532 - queue_delayed_work(system_wq, &args->reg_work, 10); 2534 + queue_delayed_work(system_percpu_wq, &args->reg_work, 10); 2533 2535 } 2534 2536 2535 2537 static void *alloc_holder_object(struct cache_sb *sb) ··· 2903 2905 if (bch_btree_init()) 2904 2906 goto err; 2905 2907 2906 - bcache_wq = alloc_workqueue("bcache", WQ_MEM_RECLAIM, 0); 2908 + bcache_wq = alloc_workqueue("bcache", WQ_MEM_RECLAIM | WQ_PERCPU, 0); 2907 2909 if (!bcache_wq) 2908 2910 goto err; 2909 2911 2910 2912 /* 2911 2913 * Let's not make this `WQ_MEM_RECLAIM` for the following reasons: 2912 2914 * 2913 - * 1. It used `system_wq` before which also does no memory reclaim. 2915 + * 1. It used `system_percpu_wq` before which also does no memory reclaim. 2914 2916 * 2. With `WQ_MEM_RECLAIM` desktop stalls, increased boot times, and 2915 2917 * reduced throughput can be observed. 2916 2918 * 2917 - * We still want to user our own queue to not congest the `system_wq`. 2919 + * We still want to user our own queue to not congest the `system_percpu_wq`. 2918 2920 */ 2919 - bch_flush_wq = alloc_workqueue("bch_flush", 0, 0); 2921 + bch_flush_wq = alloc_workqueue("bch_flush", WQ_PERCPU, 0); 2920 2922 if (!bch_flush_wq) 2921 2923 goto err; 2922 2924 2923 - bch_journal_wq = alloc_workqueue("bch_journal", WQ_MEM_RECLAIM, 0); 2925 + bch_journal_wq = alloc_workqueue("bch_journal", 2926 + WQ_MEM_RECLAIM | WQ_PERCPU, 0); 2924 2927 if (!bch_journal_wq) 2925 2928 goto err; 2926 2929
-15
drivers/md/bcache/sysfs.c
··· 134 134 rw_attribute(synchronous); 135 135 rw_attribute(journal_delay_ms); 136 136 rw_attribute(io_disable); 137 - rw_attribute(discard); 138 137 rw_attribute(running); 139 138 rw_attribute(label); 140 139 rw_attribute(errors); ··· 1035 1036 sysfs_hprint(bucket_size, bucket_bytes(ca)); 1036 1037 sysfs_hprint(block_size, block_bytes(ca)); 1037 1038 sysfs_print(nbuckets, ca->sb.nbuckets); 1038 - sysfs_print(discard, ca->discard); 1039 1039 sysfs_hprint(written, atomic_long_read(&ca->sectors_written) << 9); 1040 1040 sysfs_hprint(btree_written, 1041 1041 atomic_long_read(&ca->btree_sectors_written) << 9); ··· 1140 1142 if (bcache_is_reboot) 1141 1143 return -EBUSY; 1142 1144 1143 - if (attr == &sysfs_discard) { 1144 - bool v = strtoul_or_return(buf); 1145 - 1146 - if (bdev_max_discard_sectors(ca->bdev)) 1147 - ca->discard = v; 1148 - 1149 - if (v != CACHE_DISCARD(&ca->sb)) { 1150 - SET_CACHE_DISCARD(&ca->sb, v); 1151 - bcache_write_super(ca->set); 1152 - } 1153 - } 1154 - 1155 1145 if (attr == &sysfs_cache_replacement_policy) { 1156 1146 v = __sysfs_match_string(cache_replacement_policies, -1, buf); 1157 1147 if (v < 0) ··· 1171 1185 &sysfs_block_size, 1172 1186 &sysfs_nbuckets, 1173 1187 &sysfs_priority_stats, 1174 - &sysfs_discard, 1175 1188 &sysfs_written, 1176 1189 &sysfs_btree_written, 1177 1190 &sysfs_metadata_written,
+2 -3
drivers/md/bcache/writeback.c
··· 805 805 * may set BCH_ENABLE_AUTO_GC via sysfs, then when 806 806 * BCH_DO_AUTO_GC is set, garbage collection thread 807 807 * will be wake up here. After moving gc, the shrunk 808 - * btree and discarded free buckets SSD space may be 809 - * helpful for following write requests. 808 + * btree may be helpful for following write requests. 810 809 */ 811 810 if (c->gc_after_writeback == 812 811 (BCH_ENABLE_AUTO_GC|BCH_DO_AUTO_GC)) { ··· 1075 1076 int bch_cached_dev_writeback_start(struct cached_dev *dc) 1076 1077 { 1077 1078 dc->writeback_write_wq = alloc_workqueue("bcache_writeback_wq", 1078 - WQ_MEM_RECLAIM, 0); 1079 + WQ_MEM_RECLAIM | WQ_PERCPU, 0); 1079 1080 if (!dc->writeback_write_wq) 1080 1081 return -ENOMEM; 1081 1082