Skip to content

Commit ba9c792

Browse files
committed
Merge tag 'for-7.2/block-20260615' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux
Pull block updates from Jens Axboe: - NVMe pull request via Keith: - Per-controller admin and IO timeout sysfs attributes, and letting the block layer set request timeouts (Maurizio, Maximilian) - Multipath passthrough iostats, and PCI P2PDMA enablement for multipath devices (Keith, Kiran) - A new diag sysfs attribute group exporting per-controller counters (retries, multipath failover, error counters, requeue and failure counts, reset and reconnect events) (Nilay) - FDP configuration validation and bounds check fixes (liuxixin) - Various nvmet fixes, including a pre-auth out-of-bounds read in the Discovery Get Log Page handler, auth payload bounds validation, and tcp error-path leak fixes (Bryam, Tianchu, Geliang) - nvme-tcp lockdep and workqueue fixes (Shin'ichiro, Kuniyuki, Eric) - Assorted other fixes and cleanups (John, Yao, Chao, Mateusz, Achkinazi, Wentao) - MD pull request via Yu Kuai: - raid1/raid10 fixes for a deadlock in the read error recovery path, error-path detection and bio accounting with cloned bios, and an nr_pending leak in the REQ_ATOMIC bad-block error path (Abd-Alrhman) - PCI P2PDMA propagation from member devices to the RAID device (Kiran) - dm-raid bio requeue fix, and various smaller fixes and cleanups (Benjamin, Chen, Li, Thorsten) - Enable Clang lock context analysis for the block layer, with the accompanying annotations across queue limits, the blk_holder_ops callbacks, crypto, cgroup, iocost, kyber and mq-deadline (Bart) - Block status code infrastructure work: a tagged status table, a str_to_blk_op() helper, a bio_endio_status() helper, and on top of that a new configurable block-layer error injection facility (Christoph) - DRBD netlink rework, replacing the genl_magic machinery with explicit netlink serialization and moving the DRBD UAPI headers to include/uapi/linux/ (Christoph Böhmwalder) - bvec improvements: a bvec_folio() helper and making the bvec_iter helpers proper inline functions (Willy, Christoph) - ublk cleanups and a canceling-flag fix for the disk-not-allocated case (Caleb, Ming) - Partition handling fixes: bound the AIX pp_count scan, fix an of_node refcount leak, and replace __get_free_page() with kmalloc() (Bryam, Wentao, Mike) - Convert numa_node to int in blk_mq_hw_ctx and ->init_request, and add WQ_PERCPU to the block workqueue users (Mateusz, Marco) - Block statistics and tracing: propagate in-flight to the whole disk on partition IO, export passthrough stats, and a new block_rq_tag_wait tracepoint (Tang, Keith, Aaron) - A round of removals, unexports and cleanups across bio, direct-io and the bvec helpers (Christoph) - Various driver fixes (mtip32xx use-after-free, rbd snap_count validation and strscpy conversion, nbd socket lockdep reclassify, virtio-blk zone report clamp, floppy) and a batch of MAINTAINERS email/list updates (Coly, Li, Yu, Christoph Böhmwalder) - Other little fixes and cleanups all over * tag 'for-7.2/block-20260615' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: (117 commits) MAINTAINERS: Update Coly Li's email address block: check bio split for unaligned bvec nbd: Reclassify sockets to avoid lockdep circular dependency block: add configurable error injection block: add a str_to_blk_op helper block: add a "tag" for block status codes block: add a macro to initialize the status table floppy: Drop unused pnp driver data block: propagate in_flight to whole disk on partition I/O virtio-blk: clamp zone report to the report buffer capacity block: optimize I/O merge hot path with unlikely() hints drivers/block/rbd: Use strscpy() to copy strings into arrays partitions: aix: bound the pp_count scan to the ppe array block: Enable lock context analysis block/mq-deadline: Make the lock context annotations compatible with Clang block/Kyber: Make the lock context annotations compatible with Clang block/blk-mq-debugfs: Improve lock context annotations block/blk-iocost: Inline iocg_lock() and iocg_unlock() block/blk-iocost: Split ioc_rqos_throttle() block/crypto: Annotate the crypto functions ...
2 parents 9b40ba1 + c7c76f9 commit ba9c792

98 files changed

Lines changed: 5781 additions & 2322 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
============================
4+
Configurable Error Injection
5+
============================
6+
7+
Overview
8+
--------
9+
10+
Configurable error injection allows injecting specific block layer status codes
11+
for sector ranges of a block device. Errors can be injected unconditionally, or
12+
with a given probability.
13+
14+
To use configurable error injection, CONFIG_BLK_ERROR_INJECTION must be enabled.
15+
16+
The only interface is the error_injection debugfs file, which is created for
17+
each registered gendisk. Writes to this file are used to create or delete rules
18+
and reads return a list of the current error injection sites.
19+
20+
Options
21+
-------
22+
23+
The following options specify the operations:
24+
25+
=================== =======================================================
26+
add add a new rule
27+
removeall remove all existing rules
28+
=================== =======================================================
29+
30+
The following options specify the details of the rule for the add operation:
31+
32+
=================== =======================================================
33+
op=<string> block layer operation this rule applies to. This uses
34+
the XYZ for each REQ_OP_XYZ operation, e.g. READ, WRITE
35+
or DISCARD. Mandatory.
36+
status=<string> Status to return. This uses XYZ for each BLK_STS_XYZ
37+
code, e.g. IOERR or MEDIUM. Mandatory.
38+
start=<number> First block layer sector the rule applies to.
39+
Optional, defaults to 0.
40+
nr_sectors=<number> Number of sectors this rule applies.
41+
Optional, defaults to the remainder of the device.
42+
chance=<number> Only return a failure with a likelihood of 1/chance.
43+
Optional, defaults to 1 (always).
44+
=================== =======================================================
45+
46+
Example
47+
-------
48+
49+
Return BLK_STS_IOERR for one in 10 reads of sector 0 of /dev/nvme0n1:
50+
51+
$ echo 'add,op=READ,start=0,status=IOERR,chance=10' > /sys/kernel/debug/block/nvme0n1/error_injection
52+
53+
Return BLK_STS_MEDIUM for every write to /dev/nvme0n1:
54+
55+
$ echo 'add,op=WRITE,start=0,status=MEDIUM' > /sys/kernel/debug/block/nvme0n1/error_injection
56+
57+
Remove all rules for /dev/nvme0n1:
58+
59+
$ echo 'removeall' > /sys/kernel/debug/block/nvme0n1/error_injection

Documentation/block/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ Block
2222
switching-sched
2323
writeback_cache_control
2424
ublk
25+
error-injection

Documentation/core-api/kernel-api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ Accounting Framework
307307
Block Devices
308308
=============
309309

310+
.. kernel-doc:: include/linux/bvec.h
310311
.. kernel-doc:: include/linux/bio.h
311312
.. kernel-doc:: block/blk-core.c
312313
:export:

MAINTAINERS

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4462,7 +4462,7 @@ F: include/uapi/linux/batman_adv.h
44624462
F: net/batman-adv/
44634463

44644464
BCACHE (BLOCK LAYER CACHE)
4465-
M: Coly Li <colyli@fnnas.com>
4465+
M: Coly Li <colyli@fygo.io>
44664466
M: Kent Overstreet <kent.overstreet@linux.dev>
44674467
L: linux-bcache@vger.kernel.org
44684468
S: Maintained
@@ -4500,7 +4500,7 @@ F: Documentation/filesystems/befs.rst
45004500
F: fs/befs/
45014501

45024502
BFQ I/O SCHEDULER
4503-
M: Yu Kuai <yukuai@fnnas.com>
4503+
M: Yu Kuai <yukuai@fygo.io>
45044504
L: linux-block@vger.kernel.org
45054505
S: Odd Fixes
45064506
F: Documentation/block/bfq-iosched.rst
@@ -7804,7 +7804,7 @@ DRBD DRIVER
78047804
M: Philipp Reisner <philipp.reisner@linbit.com>
78057805
M: Lars Ellenberg <lars.ellenberg@linbit.com>
78067806
M: Christoph Böhmwalder <christoph.boehmwalder@linbit.com>
7807-
L: drbd-dev@lists.linbit.com
7807+
L: drbd-dev@lists.linux.dev
78087808
S: Supported
78097809
W: http://www.drbd.org
78107810
T: git git://git.linbit.com/linux-drbd.git
@@ -24896,8 +24896,8 @@ F: include/linux/property.h
2489624896

2489724897
SOFTWARE RAID (Multiple Disks) SUPPORT
2489824898
M: Song Liu <song@kernel.org>
24899-
M: Yu Kuai <yukuai@fnnas.com>
24900-
R: Li Nan <linan122@huawei.com>
24899+
M: Yu Kuai <yukuai@fygo.io>
24900+
R: Li Nan <magiclinan@didiglobal.com>
2490124901
R: Xiao Ni <xiao@kernel.org>
2490224902
L: linux-raid@vger.kernel.org
2490324903
S: Supported

block/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,14 @@ config BLOCK_HOLDER_DEPRECATED
221221
config BLK_MQ_STACKING
222222
bool
223223

224+
config BLK_ERROR_INJECTION
225+
bool "Enable block layer error injection"
226+
select JUMP_LABEL if HAVE_ARCH_JUMP_LABEL
227+
help
228+
Enable inserting arbitrary block errors through a debugfs interface.
229+
230+
See Documentation/block/error-injection.rst for details.
231+
224232
source "block/Kconfig.iosched"
225233

226234
endif # BLOCK

block/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
# Makefile for the kernel block layer
44
#
55

6+
CONTEXT_ANALYSIS := y
7+
68
obj-y := bdev.o fops.o bio.o elevator.o blk-core.o blk-sysfs.o \
79
blk-flush.o blk-settings.o blk-ioc.o blk-map.o \
810
blk-merge.o blk-timeout.o blk-lib.o blk-mq.o \
@@ -11,6 +13,7 @@ obj-y := bdev.o fops.o bio.o elevator.o blk-core.o blk-sysfs.o \
1113
genhd.o ioprio.o badblocks.o partitions/ blk-rq-qos.o \
1214
disk-events.o blk-ia-ranges.o early-lookup.o
1315

16+
obj-$(CONFIG_BLK_ERROR_INJECTION) += error-injection.o
1417
obj-$(CONFIG_BLK_DEV_BSG_COMMON) += bsg.o
1518
obj-$(CONFIG_BLK_DEV_BSGLIB) += bsg-lib.o
1619
obj-$(CONFIG_BLK_CGROUP) += blk-cgroup.o

block/bdev.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -446,15 +446,10 @@ EXPORT_SYMBOL_GPL(blockdev_superblock);
446446

447447
void __init bdev_cache_init(void)
448448
{
449-
int err;
450-
451449
bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode),
452450
0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
453451
SLAB_ACCOUNT|SLAB_PANIC),
454452
init_once);
455-
err = register_filesystem(&bd_type);
456-
if (err)
457-
panic("Cannot register bdev pseudo-fs");
458453
blockdev_mnt = kern_mount(&bd_type);
459454
if (IS_ERR(blockdev_mnt))
460455
panic("Cannot create bdev pseudo-fs");
@@ -1250,7 +1245,13 @@ void bdev_mark_dead(struct block_device *bdev, bool surprise)
12501245
bdev->bd_holder_ops->mark_dead(bdev, surprise);
12511246
else {
12521247
mutex_unlock(&bdev->bd_holder_lock);
1253-
sync_blockdev(bdev);
1248+
/*
1249+
* On surprise removal the device is already gone; syncing is
1250+
* futile and can hang forever waiting on I/O that will never
1251+
* complete. Match fs_bdev_mark_dead(), which also skips it.
1252+
*/
1253+
if (!surprise)
1254+
sync_blockdev(bdev);
12541255
}
12551256

12561257
invalidate_bdev(bdev);

block/bfq-cgroup.c

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,25 @@ static struct bfq_group *bfqg_parent(struct bfq_group *bfqg)
300300
return pblkg ? blkg_to_bfqg(pblkg) : NULL;
301301
}
302302

303+
static void bfqg_stats_exit(struct bfqg_stats *stats)
304+
{
305+
blkg_rwstat_exit(&stats->bytes);
306+
blkg_rwstat_exit(&stats->ios);
307+
#ifdef CONFIG_BFQ_CGROUP_DEBUG
308+
blkg_rwstat_exit(&stats->merged);
309+
blkg_rwstat_exit(&stats->service_time);
310+
blkg_rwstat_exit(&stats->wait_time);
311+
blkg_rwstat_exit(&stats->queued);
312+
bfq_stat_exit(&stats->time);
313+
bfq_stat_exit(&stats->avg_queue_size_sum);
314+
bfq_stat_exit(&stats->avg_queue_size_samples);
315+
bfq_stat_exit(&stats->dequeue);
316+
bfq_stat_exit(&stats->group_wait_time);
317+
bfq_stat_exit(&stats->idle_time);
318+
bfq_stat_exit(&stats->empty_time);
319+
#endif
320+
}
321+
303322
struct bfq_group *bfqq_group(struct bfq_queue *bfqq)
304323
{
305324
struct bfq_entity *group_entity = bfqq->entity.parent;
@@ -321,8 +340,10 @@ static void bfqg_get(struct bfq_group *bfqg)
321340

322341
static void bfqg_put(struct bfq_group *bfqg)
323342
{
324-
if (refcount_dec_and_test(&bfqg->ref))
343+
if (refcount_dec_and_test(&bfqg->ref)) {
344+
bfqg_stats_exit(&bfqg->stats);
325345
kfree(bfqg);
346+
}
326347
}
327348

328349
static void bfqg_and_blkg_get(struct bfq_group *bfqg)
@@ -433,25 +454,6 @@ void bfq_init_entity(struct bfq_entity *entity, struct bfq_group *bfqg)
433454
entity->sched_data = &bfqg->sched_data;
434455
}
435456

436-
static void bfqg_stats_exit(struct bfqg_stats *stats)
437-
{
438-
blkg_rwstat_exit(&stats->bytes);
439-
blkg_rwstat_exit(&stats->ios);
440-
#ifdef CONFIG_BFQ_CGROUP_DEBUG
441-
blkg_rwstat_exit(&stats->merged);
442-
blkg_rwstat_exit(&stats->service_time);
443-
blkg_rwstat_exit(&stats->wait_time);
444-
blkg_rwstat_exit(&stats->queued);
445-
bfq_stat_exit(&stats->time);
446-
bfq_stat_exit(&stats->avg_queue_size_sum);
447-
bfq_stat_exit(&stats->avg_queue_size_samples);
448-
bfq_stat_exit(&stats->dequeue);
449-
bfq_stat_exit(&stats->group_wait_time);
450-
bfq_stat_exit(&stats->idle_time);
451-
bfq_stat_exit(&stats->empty_time);
452-
#endif
453-
}
454-
455457
static int bfqg_stats_init(struct bfqg_stats *stats, gfp_t gfp)
456458
{
457459
if (blkg_rwstat_init(&stats->bytes, gfp) ||
@@ -552,7 +554,6 @@ static void bfq_pd_free(struct blkg_policy_data *pd)
552554
{
553555
struct bfq_group *bfqg = pd_to_bfqg(pd);
554556

555-
bfqg_stats_exit(&bfqg->stats);
556557
bfqg_put(bfqg);
557558
}
558559

@@ -1051,9 +1052,13 @@ static ssize_t bfq_io_set_device_weight(struct kernfs_open_file *of,
10511052

10521053
blkg_conf_init(&ctx, buf);
10531054

1055+
ret = blkg_conf_open_bdev(&ctx);
1056+
if (ret)
1057+
return ret;
1058+
10541059
ret = blkg_conf_prep(blkcg, &blkcg_policy_bfq, &ctx);
10551060
if (ret)
1056-
goto out;
1061+
goto close_bdev;
10571062

10581063
if (sscanf(ctx.body, "%llu", &v) == 1) {
10591064
/* require "default" on dfl */
@@ -1074,8 +1079,11 @@ static ssize_t bfq_io_set_device_weight(struct kernfs_open_file *of,
10741079
bfq_group_set_weight(bfqg, bfqg->entity.weight, v);
10751080
ret = 0;
10761081
}
1082+
10771083
out:
1078-
blkg_conf_exit(&ctx);
1084+
blkg_conf_unprep(&ctx);
1085+
close_bdev:
1086+
blkg_conf_close_bdev(&ctx);
10791087
return ret ?: nbytes;
10801088
}
10811089

block/bio.c

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -635,15 +635,15 @@ struct bio *bio_kmalloc(unsigned short nr_vecs, gfp_t gfp_mask)
635635
}
636636
EXPORT_SYMBOL(bio_kmalloc);
637637

638-
void zero_fill_bio_iter(struct bio *bio, struct bvec_iter start)
638+
void zero_fill_bio(struct bio *bio)
639639
{
640640
struct bio_vec bv;
641641
struct bvec_iter iter;
642642

643-
__bio_for_each_segment(bv, bio, iter, start)
643+
bio_for_each_segment(bv, bio, iter)
644644
memzero_bvec(&bv);
645645
}
646-
EXPORT_SYMBOL(zero_fill_bio_iter);
646+
EXPORT_SYMBOL(zero_fill_bio);
647647

648648
/**
649649
* bio_truncate - truncate the bio to small size of @new_size
@@ -1300,7 +1300,7 @@ static void bio_free_folios(struct bio *bio)
13001300
int i;
13011301

13021302
bio_for_each_bvec_all(bv, bio, i) {
1303-
struct folio *folio = page_folio(bv->bv_page);
1303+
struct folio *folio = bvec_folio(bv);
13041304

13051305
if (!is_zero_folio(folio))
13061306
folio_put(folio);
@@ -1409,7 +1409,7 @@ int bio_iov_iter_bounce(struct bio *bio, struct iov_iter *iter, size_t maxlen,
14091409

14101410
static void bvec_unpin(struct bio_vec *bv, bool mark_dirty)
14111411
{
1412-
struct folio *folio = page_folio(bv->bv_page);
1412+
struct folio *folio = bvec_folio(bv);
14131413
size_t nr_pages = (bv->bv_offset + bv->bv_len - 1) / PAGE_SIZE -
14141414
bv->bv_offset / PAGE_SIZE + 1;
14151415

@@ -1443,7 +1443,7 @@ static void bio_iov_iter_unbounce_read(struct bio *bio, bool is_error,
14431443
bvec_unpin(&bio->bi_io_vec[1 + i], mark_dirty);
14441444
}
14451445

1446-
folio_put(page_folio(bio->bi_io_vec[0].bv_page));
1446+
folio_put(bvec_folio(&bio->bi_io_vec[0]));
14471447
}
14481448

14491449
/**
@@ -1578,26 +1578,6 @@ void __bio_advance(struct bio *bio, unsigned bytes)
15781578
}
15791579
EXPORT_SYMBOL(__bio_advance);
15801580

1581-
void bio_copy_data_iter(struct bio *dst, struct bvec_iter *dst_iter,
1582-
struct bio *src, struct bvec_iter *src_iter)
1583-
{
1584-
while (src_iter->bi_size && dst_iter->bi_size) {
1585-
struct bio_vec src_bv = bio_iter_iovec(src, *src_iter);
1586-
struct bio_vec dst_bv = bio_iter_iovec(dst, *dst_iter);
1587-
unsigned int bytes = min(src_bv.bv_len, dst_bv.bv_len);
1588-
void *src_buf = bvec_kmap_local(&src_bv);
1589-
void *dst_buf = bvec_kmap_local(&dst_bv);
1590-
1591-
memcpy(dst_buf, src_buf, bytes);
1592-
1593-
kunmap_local(dst_buf);
1594-
kunmap_local(src_buf);
1595-
1596-
bio_advance_iter_single(src, src_iter, bytes);
1597-
bio_advance_iter_single(dst, dst_iter, bytes);
1598-
}
1599-
}
1600-
EXPORT_SYMBOL(bio_copy_data_iter);
16011581

16021582
/**
16031583
* bio_copy_data - copy contents of data buffers from one bio to another
@@ -1612,7 +1592,21 @@ void bio_copy_data(struct bio *dst, struct bio *src)
16121592
struct bvec_iter src_iter = src->bi_iter;
16131593
struct bvec_iter dst_iter = dst->bi_iter;
16141594

1615-
bio_copy_data_iter(dst, &dst_iter, src, &src_iter);
1595+
while (src_iter.bi_size && dst_iter.bi_size) {
1596+
struct bio_vec src_bv = bio_iter_iovec(src, src_iter);
1597+
struct bio_vec dst_bv = bio_iter_iovec(dst, dst_iter);
1598+
unsigned int bytes = min(src_bv.bv_len, dst_bv.bv_len);
1599+
void *src_buf = bvec_kmap_local(&src_bv);
1600+
void *dst_buf = bvec_kmap_local(&dst_bv);
1601+
1602+
memcpy(dst_buf, src_buf, bytes);
1603+
1604+
kunmap_local(dst_buf);
1605+
kunmap_local(src_buf);
1606+
1607+
bio_advance_iter_single(src, &src_iter, bytes);
1608+
bio_advance_iter_single(dst, &dst_iter, bytes);
1609+
}
16161610
}
16171611
EXPORT_SYMBOL(bio_copy_data);
16181612

@@ -1659,7 +1653,6 @@ void bio_set_pages_dirty(struct bio *bio)
16591653
folio_unlock(fi.folio);
16601654
}
16611655
}
1662-
EXPORT_SYMBOL_GPL(bio_set_pages_dirty);
16631656

16641657
/*
16651658
* bio_check_pages_dirty() will check that all the BIO's pages are still dirty.
@@ -1718,7 +1711,6 @@ void bio_check_pages_dirty(struct bio *bio)
17181711
spin_unlock_irqrestore(&bio_dirty_lock, flags);
17191712
schedule_work(&bio_dirty_work);
17201713
}
1721-
EXPORT_SYMBOL_GPL(bio_check_pages_dirty);
17221714

17231715
static inline bool bio_remaining_done(struct bio *bio)
17241716
{
@@ -1884,7 +1876,7 @@ EXPORT_SYMBOL_GPL(bio_trim);
18841876
* create memory pools for biovec's in a bio_set.
18851877
* use the global biovec slabs created for general use.
18861878
*/
1887-
int biovec_init_pool(mempool_t *pool, int pool_entries)
1879+
static int biovec_init_pool(mempool_t *pool, int pool_entries)
18881880
{
18891881
struct biovec_slab *bp = bvec_slabs + ARRAY_SIZE(bvec_slabs) - 1;
18901882

0 commit comments

Comments
 (0)