mailweb.openeuler.org
Manage this list

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Kernel

Threads by month
  • ----- 2025 -----
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
kernel@openeuler.org

  • 46 participants
  • 19070 discussions
[PATCH openEuler-22.03-LTS-SP1] Bluetooth: RFCOMM: Fix not validating setsockopt user input
by Jinjiang Tu 14 Jun '24

14 Jun '24
From: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com> mainline inclusion from mainline-v6.9-rc4 commit a97de7bff13b1cc825c1b1344eaed8d6c2d3e695 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9QRFS CVE: CVE-2024-35966 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- syzbot reported rfcomm_sock_setsockopt_old() is copying data without checking user input length. BUG: KASAN: slab-out-of-bounds in copy_from_sockptr_offset include/linux/sockptr.h:49 [inline] BUG: KASAN: slab-out-of-bounds in copy_from_sockptr include/linux/sockptr.h:55 [inline] BUG: KASAN: slab-out-of-bounds in rfcomm_sock_setsockopt_old net/bluetooth/rfcomm/sock.c:632 [inline] BUG: KASAN: slab-out-of-bounds in rfcomm_sock_setsockopt+0x893/0xa70 net/bluetooth/rfcomm/sock.c:673 Read of size 4 at addr ffff8880209a8bc3 by task syz-executor632/5064 Fixes: 9f2c8a03fbb3 ("Bluetooth: Replace RFCOMM link mode with security level") Fixes: bb23c0ab8246 ("Bluetooth: Add support for deferring RFCOMM connection setup") Reported-by: syzbot <syzkaller(a)googlegroups.com> Signed-off-by: Eric Dumazet <edumazet(a)google.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com> Signed-off-by: Jinjiang Tu <tujinjiang(a)huawei.com> --- net/bluetooth/rfcomm/sock.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 4cf1fa9900ca..82f404d3eba2 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -631,7 +631,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, switch (optname) { case RFCOMM_LM: - if (copy_from_sockptr(&opt, optval, sizeof(u32))) { + if (bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen)) { err = -EFAULT; break; } @@ -666,7 +666,6 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, struct sock *sk = sock->sk; struct bt_security sec; int err = 0; - size_t len; u32 opt; BT_DBG("sk %p", sk); @@ -688,11 +687,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, sec.level = BT_SECURITY_LOW; - len = min_t(unsigned int, sizeof(sec), optlen); - if (copy_from_sockptr(&sec, optval, len)) { - err = -EFAULT; + err = bt_copy_from_sockptr(&sec, sizeof(sec), optval, optlen); + if (err) break; - } if (sec.level > BT_SECURITY_HIGH) { err = -EINVAL; @@ -708,10 +705,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, break; } - if (copy_from_sockptr(&opt, optval, sizeof(u32))) { - err = -EFAULT; + err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen); + if (err) break; - } if (opt) set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); -- 2.25.1
2 1
0 0
[PATCH OLK-5.10] Bluetooth: RFCOMM: Fix not validating setsockopt user input
by Jinjiang Tu 14 Jun '24

14 Jun '24
From: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com> mainline inclusion from mainline-v6.9-rc4 commit a97de7bff13b1cc825c1b1344eaed8d6c2d3e695 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9QRFS CVE: CVE-2024-35966 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- syzbot reported rfcomm_sock_setsockopt_old() is copying data without checking user input length. BUG: KASAN: slab-out-of-bounds in copy_from_sockptr_offset include/linux/sockptr.h:49 [inline] BUG: KASAN: slab-out-of-bounds in copy_from_sockptr include/linux/sockptr.h:55 [inline] BUG: KASAN: slab-out-of-bounds in rfcomm_sock_setsockopt_old net/bluetooth/rfcomm/sock.c:632 [inline] BUG: KASAN: slab-out-of-bounds in rfcomm_sock_setsockopt+0x893/0xa70 net/bluetooth/rfcomm/sock.c:673 Read of size 4 at addr ffff8880209a8bc3 by task syz-executor632/5064 Fixes: 9f2c8a03fbb3 ("Bluetooth: Replace RFCOMM link mode with security level") Fixes: bb23c0ab8246 ("Bluetooth: Add support for deferring RFCOMM connection setup") Reported-by: syzbot <syzkaller(a)googlegroups.com> Signed-off-by: Eric Dumazet <edumazet(a)google.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com> Signed-off-by: Jinjiang Tu <tujinjiang(a)huawei.com> --- net/bluetooth/rfcomm/sock.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 4cf1fa9900ca..82f404d3eba2 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -631,7 +631,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, switch (optname) { case RFCOMM_LM: - if (copy_from_sockptr(&opt, optval, sizeof(u32))) { + if (bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen)) { err = -EFAULT; break; } @@ -666,7 +666,6 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, struct sock *sk = sock->sk; struct bt_security sec; int err = 0; - size_t len; u32 opt; BT_DBG("sk %p", sk); @@ -688,11 +687,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, sec.level = BT_SECURITY_LOW; - len = min_t(unsigned int, sizeof(sec), optlen); - if (copy_from_sockptr(&sec, optval, len)) { - err = -EFAULT; + err = bt_copy_from_sockptr(&sec, sizeof(sec), optval, optlen); + if (err) break; - } if (sec.level > BT_SECURITY_HIGH) { err = -EINVAL; @@ -708,10 +705,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, break; } - if (copy_from_sockptr(&opt, optval, sizeof(u32))) { - err = -EFAULT; + err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen); + if (err) break; - } if (opt) set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); -- 2.25.1
2 1
0 0
[PATCH OLK-5.10] config: enable CONFIG_BLK_CGROUP_IOCOST by default
by Li Nan 14 Jun '24

14 Jun '24
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IA582B CVE: NA -------------------------------- It will also enable CONFIG_BLK_RQ_ALLOC_TIME. Signed-off-by: Li Nan <linan122(a)huawei.com> --- arch/arm64/configs/openeuler_defconfig | 3 ++- arch/x86/configs/openeuler_defconfig | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index ffb058ec0b0a..4450315d742e 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -945,6 +945,7 @@ CONFIG_MODULE_SIG_HASH="sha256" # CONFIG_TRIM_UNUSED_KSYMS is not set CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y +CONFIG_BLK_RQ_ALLOC_TIME=y CONFIG_BLK_SCSI_REQUEST=y CONFIG_BLK_CGROUP_RWSTAT=y CONFIG_BLK_DEV_BSG=y @@ -957,7 +958,7 @@ CONFIG_BLK_DEV_THROTTLING=y # CONFIG_BLK_CMDLINE_PARSER is not set CONFIG_BLK_WBT=y # CONFIG_BLK_CGROUP_IOLATENCY is not set -# CONFIG_BLK_CGROUP_IOCOST is not set +CONFIG_BLK_CGROUP_IOCOST=y CONFIG_BLK_WBT_MQ=y CONFIG_BLK_DEBUG_FS=y CONFIG_BLK_DEBUG_FS_ZONED=y diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index dbf869f75111..6d56ba68ff1f 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -923,6 +923,7 @@ CONFIG_MODULE_SIG_HASH="sha256" # CONFIG_TRIM_UNUSED_KSYMS is not set CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y +CONFIG_BLK_RQ_ALLOC_TIME=y CONFIG_BLK_SCSI_REQUEST=y CONFIG_BLK_CGROUP_RWSTAT=y CONFIG_BLK_DEV_BSG=y @@ -935,7 +936,7 @@ CONFIG_BLK_DEV_THROTTLING=y # CONFIG_BLK_CMDLINE_PARSER is not set CONFIG_BLK_WBT=y # CONFIG_BLK_CGROUP_IOLATENCY is not set -# CONFIG_BLK_CGROUP_IOCOST is not set +CONFIG_BLK_CGROUP_IOCOST=y CONFIG_BLK_WBT_MQ=y CONFIG_BLK_DEBUG_FS=y CONFIG_BLK_DEBUG_FS_ZONED=y -- 2.39.2
2 1
0 0
[PATCH] block: support to dispatch bio asynchronously
by Li Nan 14 Jun '24

14 Jun '24
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IA5AEP CVE: NA -------------------------------- In certain environments, specific CPUs handle a large number of tasks and become bottlenecks, affecting overall system performance. This commit introduces a new feature that enables asynchronous I/O dispatch to designated CPUs, thereby relieving the pressure on the busy CPUs. Signed-off-by: Li Nan <linan122(a)huawei.com> --- block/blk.h | 7 + include/linux/blk_types.h | 1 + include/linux/blkdev.h | 8 + block/blk-core.c | 240 ++++++++++++++++++++++++- block/blk-mq-debugfs.c | 1 + block/blk-sysfs.c | 59 ++++++ arch/arm64/configs/openeuler_defconfig | 1 + arch/x86/configs/openeuler_defconfig | 1 + block/Kconfig | 11 ++ 9 files changed, 328 insertions(+), 1 deletion(-) diff --git a/block/blk.h b/block/blk.h index 4bbcc971d4f7..5e7c00356ddc 100644 --- a/block/blk.h +++ b/block/blk.h @@ -450,4 +450,11 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio, struct page *page, unsigned int len, unsigned int offset, unsigned int max_sectors, bool *same_page); +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC +void blk_free_queue_dispatch_async(struct request_queue *q); +#else +static inline void blk_free_queue_dispatch_async(struct request_queue *q) +{ +} +#endif #endif /* BLK_INTERNAL_H */ diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 1853ec569b72..5445d89ae1cf 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -301,6 +301,7 @@ enum { * of this bio. */ BIO_CGROUP_ACCT, /* has been accounted to a cgroup */ BIO_TRACKED, /* set if bio goes through the rq_qos path */ + BIO_ASYNC, /* has been dispatched asynchronously */ BIO_FLAG_LAST }; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 50b4fd0a0687..3a071d12623e 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -603,6 +603,12 @@ struct request_queue { KABI_REPLACE(unsigned long dtag_wait_time, struct blk_mq_tags *shared_sbitmap_tags) + +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC + /* used when QUEUE_FLAG_DISPATCH_ASYNC is set */ + struct cpumask *dispatch_async_cpus; + int __percpu *last_dispatch_cpu; +#endif KABI_RESERVE(1) KABI_RESERVE(2) KABI_RESERVE(3) @@ -643,6 +649,8 @@ struct request_queue { #define QUEUE_FLAG_NOWAIT 29 /* device supports NOWAIT */ /*at least one blk-mq hctx can't get driver tag */ #define QUEUE_FLAG_HCTX_WAIT 30 +/* support to dispatch bio asynchronously */ +#define QUEUE_FLAG_DISPATCH_ASYNC 31 #define QUEUE_FLAG_MQ_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ (1 << QUEUE_FLAG_SAME_COMP) | \ diff --git a/block/blk-core.c b/block/blk-core.c index f91f8e8be482..a1ebbf96d19a 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -87,6 +87,234 @@ struct kmem_cache *blk_requestq_cachep; */ static struct workqueue_struct *kblockd_workqueue; +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC + +#define BIO_DISPATCH_MAX_LOOP 16 + +struct async_bio { + struct bio_list list; + spinlock_t lock; +} ____cacheline_aligned_in_smp; + +struct bio_dispatch_async_ctl { + /* + * Vector size is nr_cpu_ids, list stores bio dispatched from other cpu, + * such bio will be dispatched asynchronously to the cpu this structure + * is serviced. + */ + struct async_bio *bios; + /* kthread to handle bio dispatched from other cpu. */ + struct task_struct *thread; + wait_queue_head_t wait; +}; + +static struct bio_dispatch_async_ctl __percpu *bio_dispatch_async_ctl; + +static int blk_alloc_queue_dispatch_async(struct request_queue *q) +{ + int cpu; + + /* use the same function and parameters as alloc_cpumask_var() */ + q->dispatch_async_cpus = kmalloc_node(cpumask_size(), + GFP_KERNEL, q->node); + if (!q->dispatch_async_cpus) + return -ENOMEM; + + q->last_dispatch_cpu = alloc_percpu(int); + if (!q->last_dispatch_cpu) { + kfree(q->dispatch_async_cpus); + q->dispatch_async_cpus = NULL; + return -ENOMEM; + } + + cpumask_setall(q->dispatch_async_cpus); + for_each_possible_cpu(cpu) + *per_cpu_ptr(q->last_dispatch_cpu, cpu) = cpu; + + return 0; +} + +void blk_free_queue_dispatch_async(struct request_queue *q) +{ + kfree(q->dispatch_async_cpus); + q->dispatch_async_cpus = NULL; + free_percpu(q->last_dispatch_cpu); + q->last_dispatch_cpu = NULL; +} + +static int get_dispatch_cpu(struct request_queue *q) +{ + int cpu = cpumask_next(this_cpu_read(*q->last_dispatch_cpu), + q->dispatch_async_cpus); + + if (cpu >= nr_cpu_ids) + cpu = cpumask_first(q->dispatch_async_cpus); + + return cpu; +} + +static bool __submit_bio_noacct_async(struct bio *bio) +{ + struct request_queue *q = bio->bi_disk->queue; + int current_cpu = smp_processor_id(); + int dispatch_cpu = get_dispatch_cpu(q); + struct bio_dispatch_async_ctl *ctl; + + if (dispatch_cpu >= nr_cpu_ids) + return false; + + this_cpu_write(*q->last_dispatch_cpu, dispatch_cpu); + + ctl = per_cpu_ptr(bio_dispatch_async_ctl, dispatch_cpu); + spin_lock_irq(&ctl->bios[current_cpu].lock); + bio_list_add(&ctl->bios[current_cpu].list, bio); + spin_unlock_irq(&ctl->bios[current_cpu].lock); + + if (wq_has_sleeper(&ctl->wait)) + wake_up(&ctl->wait); + + return true; +} + +static bool submit_bio_noacct_async(struct bio *bio) +{ + struct request_queue *q; + + if (bio_flagged(bio, BIO_ASYNC)) + return false; + + bio_set_flag(bio, BIO_ASYNC); + /* + * Don't dispatch bio asynchronously in following cases: + * + * - QUEUE_FLAG_DISPATCH_ASYNC is not set; + * - current cpu is the target cpu; + * - bio is flagged no wait; + * - io polling is enabled; + */ + q = bio->bi_disk->queue; + if (!test_bit(QUEUE_FLAG_DISPATCH_ASYNC, &q->queue_flags) || + test_bit(QUEUE_FLAG_POLL, &q->queue_flags) || + cpumask_test_cpu(smp_processor_id(), q->dispatch_async_cpus) || + bio->bi_opf & REQ_NOWAIT) + return false; + + return __submit_bio_noacct_async(bio); +} + +static bool collect_bio(struct bio_dispatch_async_ctl *ctl, + struct bio_list *list) +{ + bool has_bio = false; + int cpu; + + for_each_possible_cpu(cpu) { + struct async_bio *abio = &ctl->bios[cpu]; + + if (bio_list_empty(&abio->list)) + continue; + + has_bio = true; + + spin_lock_irq(&abio->lock); + bio_list_merge(list, &abio->list); + bio_list_init(&abio->list); + spin_unlock_irq(&abio->lock); + } + + return has_bio; +} + +static int bio_dispatch_work(void *data) +{ + int loop_count = 0; + struct bio_list bio_list_on_stack; + struct blk_plug plug; + struct bio_dispatch_async_ctl *ctl; + + bio_list_init(&bio_list_on_stack); + ctl = this_cpu_ptr(bio_dispatch_async_ctl); + + for (;; loop_count++) { + struct bio *bio; + bool has_bio = collect_bio(ctl, &bio_list_on_stack); + + if (!has_bio) { + DEFINE_WAIT(wait); + + for (;;) { + prepare_to_wait(&ctl->wait, &wait, + TASK_INTERRUPTIBLE); + has_bio = collect_bio(ctl, &bio_list_on_stack); + if (has_bio) + break; + schedule(); + loop_count = 0; + } + finish_wait(&ctl->wait, &wait); + } + + blk_start_plug(&plug); + while ((bio = bio_list_pop(&bio_list_on_stack))) + submit_bio_noacct(bio); + blk_finish_plug(&plug); + + /* prevent soft lockup. */ + if (loop_count >= BIO_DISPATCH_MAX_LOOP) { + loop_count = 0; + cond_resched(); + } + } + + return 0; +} + +static void init_blk_queue_async_dispatch(void) +{ + int cpu; + + bio_dispatch_async_ctl = alloc_percpu(struct bio_dispatch_async_ctl); + if (!bio_dispatch_async_ctl) + panic("Failed to alloc bio_dispatch_async_ctl\n"); + + for_each_possible_cpu(cpu) { + int i; + struct bio_dispatch_async_ctl *ctl = + per_cpu_ptr(bio_dispatch_async_ctl, cpu); + + init_waitqueue_head(&ctl->wait); + ctl->bios = kmalloc_array(nr_cpu_ids, sizeof(struct async_bio), + GFP_KERNEL | __GFP_NOFAIL); + for (i = 0; i < nr_cpu_ids; ++i) { + bio_list_init(&ctl->bios[i].list); + spin_lock_init(&ctl->bios[i].lock); + } + + ctl->thread = + kthread_create_on_cpu(bio_dispatch_work, NULL, cpu, + "bio_dispatch_work_%u"); + if (IS_ERR_OR_NULL(ctl->thread)) + panic("Failed to create bio dispatch thread\n"); + + wake_up_process(ctl->thread); + } +} +#else +static int blk_alloc_queue_dispatch_async(struct request_queue *q) +{ + return 0; +} + +static bool submit_bio_noacct_async(struct bio *bio) +{ + return false; +} + +static void init_blk_queue_async_dispatch(void) +{ +} +#endif + /** * blk_queue_flag_set - atomically set a queue flag * @flag: flag to be set @@ -539,9 +767,12 @@ struct request_queue *blk_alloc_queue(int node_id) q->last_merge = NULL; + if (blk_alloc_queue_dispatch_async(q)) + goto fail_q; + q->id = ida_simple_get(&blk_queue_ida, 0, 0, GFP_KERNEL); if (q->id < 0) - goto fail_q; + goto fail_dispatch_async; ret = bioset_init(&q->bio_split, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); if (ret) @@ -606,6 +837,8 @@ struct request_queue *blk_alloc_queue(int node_id) bioset_exit(&q->bio_split); fail_id: ida_simple_remove(&blk_queue_ida, q->id); +fail_dispatch_async: + blk_free_queue_dispatch_async(q); fail_q: kmem_cache_free(blk_requestq_cachep, q); return NULL; @@ -1055,6 +1288,9 @@ static blk_qc_t __submit_bio_noacct_mq(struct bio *bio) */ blk_qc_t submit_bio_noacct(struct bio *bio) { + if (submit_bio_noacct_async(bio)) + return BLK_QC_T_NONE; + if (!submit_bio_checks(bio)) return BLK_QC_T_NONE; @@ -1905,5 +2141,7 @@ int __init blk_dev_init(void) blk_debugfs_root = debugfs_create_dir("block", NULL); + init_blk_queue_async_dispatch(); + return 0; } diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index a879f94782e4..b5b17c6ee650 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c @@ -131,6 +131,7 @@ static const char *const blk_queue_flag_name[] = { QUEUE_FLAG_NAME(RQ_ALLOC_TIME), QUEUE_FLAG_NAME(HCTX_ACTIVE), QUEUE_FLAG_NAME(NOWAIT), + QUEUE_FLAG_NAME(DISPATCH_ASYNC), }; #undef QUEUE_FLAG_NAME diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index c95be9626a09..53598eb6affd 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -288,6 +288,9 @@ QUEUE_SYSFS_BIT_FNS(nonrot, NONROT, 1); QUEUE_SYSFS_BIT_FNS(random, ADD_RANDOM, 0); QUEUE_SYSFS_BIT_FNS(iostats, IO_STAT, 0); QUEUE_SYSFS_BIT_FNS(stable_writes, STABLE_WRITES, 0); +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC +QUEUE_SYSFS_BIT_FNS(dispatch_async, DISPATCH_ASYNC, 0); +#endif #undef QUEUE_SYSFS_BIT_FNS static ssize_t queue_zoned_show(struct request_queue *q, char *page) @@ -619,6 +622,57 @@ QUEUE_RW_ENTRY(queue_iostats, "iostats"); QUEUE_RW_ENTRY(queue_random, "add_random"); QUEUE_RW_ENTRY(queue_stable_writes, "stable_writes"); +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC + +static ssize_t queue_dispatch_async_cpus_show(struct request_queue *q, + char *page) +{ + return sprintf(page, "%*pb\n", nr_cpu_ids, + cpumask_bits(q->dispatch_async_cpus)); +} + +static ssize_t queue_dispatch_async_cpus_store(struct request_queue *q, + const char *page, size_t count) +{ + cpumask_var_t cpumask; + ssize_t ret; + + if (!alloc_cpumask_var(&cpumask, GFP_KERNEL)) + return -ENOMEM; + + ret = bitmap_parse(page, count, cpumask_bits(cpumask), + nr_cpumask_bits); + if (ret < 0) + goto out; + + if (cpumask_empty(cpumask) || + !cpumask_subset(cpumask, cpu_online_mask)) { + ret = -EINVAL; + goto out; + } + + blk_mq_freeze_queue(q); + blk_mq_quiesce_queue(q); + + cpumask_copy(q->dispatch_async_cpus, cpumask); + + blk_mq_unquiesce_queue(q); + blk_mq_unfreeze_queue(q); + ret = count; +out: + free_cpumask_var(cpumask); + return ret; +} + +static struct queue_sysfs_entry queue_dispatch_async_cpus_entry = { + .attr = {.name = "dispatch_async_cpus", .mode = 0644 }, + .show = queue_dispatch_async_cpus_show, + .store = queue_dispatch_async_cpus_store, +}; + +QUEUE_RW_ENTRY(queue_dispatch_async, "dispatch_async"); +#endif + static struct attribute *queue_attrs[] = { &queue_requests_entry.attr, &queue_ra_entry.attr, @@ -659,6 +713,10 @@ static struct attribute *queue_attrs[] = { &queue_wb_lat_entry.attr, &queue_poll_delay_entry.attr, &queue_io_timeout_entry.attr, +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC + &queue_dispatch_async_cpus_entry.attr, + &queue_dispatch_async_entry.attr, +#endif #ifdef CONFIG_BLK_DEV_THROTTLING_LOW &blk_throtl_sample_time_entry.attr, #endif @@ -795,6 +853,7 @@ static void blk_release_queue(struct kobject *kobj) blk_stat_remove_callback(q, q->poll_cb); blk_stat_free_callback(q->poll_cb); + blk_free_queue_dispatch_async(q); blk_free_queue_stats(q->stats); blk_exit_queue(q); diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index d2ba9ee9eb81..996a6196cc5a 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -964,6 +964,7 @@ CONFIG_BLK_DEBUG_FS_ZONED=y # CONFIG_BLK_SED_OPAL is not set # CONFIG_BLK_INLINE_ENCRYPTION is not set CONFIG_BLK_DEV_DUMPINFO=y +CONFIG_BLK_BIO_DISPATCH_ASYNC=y # # Partition Types diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index dbf869f75111..6b014668cf4d 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -942,6 +942,7 @@ CONFIG_BLK_DEBUG_FS_ZONED=y # CONFIG_BLK_SED_OPAL is not set # CONFIG_BLK_INLINE_ENCRYPTION is not set CONFIG_BLK_DEV_DUMPINFO=y +CONFIG_BLK_BIO_DISPATCH_ASYNC=y # # Partition Types diff --git a/block/Kconfig b/block/Kconfig index e5c965f1ea25..24c6bb87727d 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -209,6 +209,17 @@ config BLK_DEV_DUMPINFO Dump info when open an write opened block device exclusively or open an exclusive opened device for write +config BLK_BIO_DISPATCH_ASYNC + bool "Dispatch bios asynchronously on specific cpus" + default n + help + In certain environments, specific CPUs handle a large number of + tasks and become bottlenecks, affecting overall system + performance. This commit introduces a new feature that enables + asynchronous I/O dispatch to designated CPUs, thereby relieving + the pressure on the busy CPUs. + If unsure, say N. + menu "Partition Types" source "block/partitions/Kconfig" -- 2.39.2
1 0
0 0
[openeuler:openEuler-1.0-LTS 14221/22914] fs/ext4/.tmp_mballoc.o: warning: objtool: ext4_mb_complex_scan_group()+0xb0f: unreachable instruction
by kernel test robot 14 Jun '24

14 Jun '24
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS head: efdd263f4cc3df5dcccb45402615eb6d2d8f55c5 commit: 41298197ead9e85ee2ec1d52122f03fd1863cff2 [14221/22914] ext4: convert BUG_ON's to WARN_ON's in mballoc.c config: x86_64-buildonly-randconfig-006-20240614 (https://download.01.org/0day-ci/archive/20240614/202406141455.MPvgmjIK-lkp@…) compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240614/202406141455.MPvgmjIK-lkp@…) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp(a)intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202406141455.MPvgmjIK-lkp@intel.com/ All warnings (new ones prefixed by >>): In file included from fs/ext4/mballoc.c:12: In file included from fs/ext4/ext4_jbd2.h:16: In file included from include/linux/jbd2.h:26: In file included from include/linux/buffer_head.h:14: include/linux/pagemap.h:425:21: warning: cast from 'int (*)(struct file *, struct page *)' to 'filler_t *' (aka 'int (*)(void *, struct page *)') converts to incompatible function type [-Wcast-function-type-strict] 425 | filler_t *filler = (filler_t *)mapping->a_ops->readpage; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 warning generated. fs/ext4/mballoc.c:4734: warning: Function parameter or member 'bh' not described in 'ext4_free_blocks' >> fs/ext4/.tmp_mballoc.o: warning: objtool: ext4_mb_complex_scan_group()+0xb0f: unreachable instruction fs/ext4/.tmp_mballoc.o: warning: objtool: missing symbol for section .init.text objdump-func vmlinux.o ext4_mb_complex_scan_group: -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
1 0
0 0
[PATCH] block: support to dispatch bio asynchronously
by Li Nan 14 Jun '24

14 Jun '24
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IA5AEP CVE: NA -------------------------------- In certain environments, specific CPUs handle a large number of tasks and become bottlenecks, affecting overall system performance. This commit introduces a new feature that enables asynchronous I/O dispatch to designated CPUs, thereby relieving the pressure on the busy CPUs. Signed-off-by: Li Nan <linan122(a)huawei.com> --- block/blk.h | 7 + include/linux/blk_types.h | 1 + include/linux/blkdev.h | 8 + block/blk-core.c | 240 ++++++++++++++++++++++++- block/blk-mq-debugfs.c | 1 + block/blk-sysfs.c | 59 ++++++ arch/arm64/configs/openeuler_defconfig | 1 + arch/x86/configs/openeuler_defconfig | 1 + block/Kconfig | 11 ++ 9 files changed, 328 insertions(+), 1 deletion(-) diff --git a/block/blk.h b/block/blk.h index 4bbcc971d4f7..5e7c00356ddc 100644 --- a/block/blk.h +++ b/block/blk.h @@ -450,4 +450,11 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio, struct page *page, unsigned int len, unsigned int offset, unsigned int max_sectors, bool *same_page); +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC +void blk_free_queue_dispatch_async(struct request_queue *q); +#else +static inline void blk_free_queue_dispatch_async(struct request_queue *q) +{ +} +#endif #endif /* BLK_INTERNAL_H */ diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 1853ec569b72..5445d89ae1cf 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -301,6 +301,7 @@ enum { * of this bio. */ BIO_CGROUP_ACCT, /* has been accounted to a cgroup */ BIO_TRACKED, /* set if bio goes through the rq_qos path */ + BIO_ASYNC, /* has been dispatched asynchronously */ BIO_FLAG_LAST }; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 50b4fd0a0687..3a071d12623e 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -603,6 +603,12 @@ struct request_queue { KABI_REPLACE(unsigned long dtag_wait_time, struct blk_mq_tags *shared_sbitmap_tags) + +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC + /* used when QUEUE_FLAG_DISPATCH_ASYNC is set */ + struct cpumask *dispatch_async_cpus; + int __percpu *last_dispatch_cpu; +#endif KABI_RESERVE(1) KABI_RESERVE(2) KABI_RESERVE(3) @@ -643,6 +649,8 @@ struct request_queue { #define QUEUE_FLAG_NOWAIT 29 /* device supports NOWAIT */ /*at least one blk-mq hctx can't get driver tag */ #define QUEUE_FLAG_HCTX_WAIT 30 +/* support to dispatch bio asynchronously */ +#define QUEUE_FLAG_DISPATCH_ASYNC 31 #define QUEUE_FLAG_MQ_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ (1 << QUEUE_FLAG_SAME_COMP) | \ diff --git a/block/blk-core.c b/block/blk-core.c index f91f8e8be482..a1ebbf96d19a 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -87,6 +87,234 @@ struct kmem_cache *blk_requestq_cachep; */ static struct workqueue_struct *kblockd_workqueue; +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC + +#define BIO_DISPATCH_MAX_LOOP 16 + +struct async_bio { + struct bio_list list; + spinlock_t lock; +} ____cacheline_aligned_in_smp; + +struct bio_dispatch_async_ctl { + /* + * Vector size is nr_cpu_ids, list stores bio dispatched from other cpu, + * such bio will be dispatched asynchronously to the cpu this structure + * is serviced. + */ + struct async_bio *bios; + /* kthread to handle bio dispatched from other cpu. */ + struct task_struct *thread; + wait_queue_head_t wait; +}; + +static struct bio_dispatch_async_ctl __percpu *bio_dispatch_async_ctl; + +static int blk_alloc_queue_dispatch_async(struct request_queue *q) +{ + int cpu; + + /* use the same function and parameters as alloc_cpumask_var() */ + q->dispatch_async_cpus = kmalloc_node(cpumask_size(), + GFP_KERNEL, q->node); + if (!q->dispatch_async_cpus) + return -ENOMEM; + + q->last_dispatch_cpu = alloc_percpu(int); + if (!q->last_dispatch_cpu) { + kfree(q->dispatch_async_cpus); + q->dispatch_async_cpus = NULL; + return -ENOMEM; + } + + cpumask_setall(q->dispatch_async_cpus); + for_each_possible_cpu(cpu) + *per_cpu_ptr(q->last_dispatch_cpu, cpu) = cpu; + + return 0; +} + +void blk_free_queue_dispatch_async(struct request_queue *q) +{ + kfree(q->dispatch_async_cpus); + q->dispatch_async_cpus = NULL; + free_percpu(q->last_dispatch_cpu); + q->last_dispatch_cpu = NULL; +} + +static int get_dispatch_cpu(struct request_queue *q) +{ + int cpu = cpumask_next(this_cpu_read(*q->last_dispatch_cpu), + q->dispatch_async_cpus); + + if (cpu >= nr_cpu_ids) + cpu = cpumask_first(q->dispatch_async_cpus); + + return cpu; +} + +static bool __submit_bio_noacct_async(struct bio *bio) +{ + struct request_queue *q = bio->bi_disk->queue; + int current_cpu = smp_processor_id(); + int dispatch_cpu = get_dispatch_cpu(q); + struct bio_dispatch_async_ctl *ctl; + + if (dispatch_cpu >= nr_cpu_ids) + return false; + + this_cpu_write(*q->last_dispatch_cpu, dispatch_cpu); + + ctl = per_cpu_ptr(bio_dispatch_async_ctl, dispatch_cpu); + spin_lock_irq(&ctl->bios[current_cpu].lock); + bio_list_add(&ctl->bios[current_cpu].list, bio); + spin_unlock_irq(&ctl->bios[current_cpu].lock); + + if (wq_has_sleeper(&ctl->wait)) + wake_up(&ctl->wait); + + return true; +} + +static bool submit_bio_noacct_async(struct bio *bio) +{ + struct request_queue *q; + + if (bio_flagged(bio, BIO_ASYNC)) + return false; + + bio_set_flag(bio, BIO_ASYNC); + /* + * Don't dispatch bio asynchronously in following cases: + * + * - QUEUE_FLAG_DISPATCH_ASYNC is not set; + * - current cpu is the target cpu; + * - bio is flagged no wait; + * - io polling is enabled; + */ + q = bio->bi_disk->queue; + if (!test_bit(QUEUE_FLAG_DISPATCH_ASYNC, &q->queue_flags) || + test_bit(QUEUE_FLAG_POLL, &q->queue_flags) || + cpumask_test_cpu(smp_processor_id(), q->dispatch_async_cpus) || + bio->bi_opf & REQ_NOWAIT) + return false; + + return __submit_bio_noacct_async(bio); +} + +static bool collect_bio(struct bio_dispatch_async_ctl *ctl, + struct bio_list *list) +{ + bool has_bio = false; + int cpu; + + for_each_possible_cpu(cpu) { + struct async_bio *abio = &ctl->bios[cpu]; + + if (bio_list_empty(&abio->list)) + continue; + + has_bio = true; + + spin_lock_irq(&abio->lock); + bio_list_merge(list, &abio->list); + bio_list_init(&abio->list); + spin_unlock_irq(&abio->lock); + } + + return has_bio; +} + +static int bio_dispatch_work(void *data) +{ + int loop_count = 0; + struct bio_list bio_list_on_stack; + struct blk_plug plug; + struct bio_dispatch_async_ctl *ctl; + + bio_list_init(&bio_list_on_stack); + ctl = this_cpu_ptr(bio_dispatch_async_ctl); + + for (;; loop_count++) { + struct bio *bio; + bool has_bio = collect_bio(ctl, &bio_list_on_stack); + + if (!has_bio) { + DEFINE_WAIT(wait); + + for (;;) { + prepare_to_wait(&ctl->wait, &wait, + TASK_INTERRUPTIBLE); + has_bio = collect_bio(ctl, &bio_list_on_stack); + if (has_bio) + break; + schedule(); + loop_count = 0; + } + finish_wait(&ctl->wait, &wait); + } + + blk_start_plug(&plug); + while ((bio = bio_list_pop(&bio_list_on_stack))) + submit_bio_noacct(bio); + blk_finish_plug(&plug); + + /* prevent soft lockup. */ + if (loop_count >= BIO_DISPATCH_MAX_LOOP) { + loop_count = 0; + cond_resched(); + } + } + + return 0; +} + +static void init_blk_queue_async_dispatch(void) +{ + int cpu; + + bio_dispatch_async_ctl = alloc_percpu(struct bio_dispatch_async_ctl); + if (!bio_dispatch_async_ctl) + panic("Failed to alloc bio_dispatch_async_ctl\n"); + + for_each_possible_cpu(cpu) { + int i; + struct bio_dispatch_async_ctl *ctl = + per_cpu_ptr(bio_dispatch_async_ctl, cpu); + + init_waitqueue_head(&ctl->wait); + ctl->bios = kmalloc_array(nr_cpu_ids, sizeof(struct async_bio), + GFP_KERNEL | __GFP_NOFAIL); + for (i = 0; i < nr_cpu_ids; ++i) { + bio_list_init(&ctl->bios[i].list); + spin_lock_init(&ctl->bios[i].lock); + } + + ctl->thread = + kthread_create_on_cpu(bio_dispatch_work, NULL, cpu, + "bio_dispatch_work_%u"); + if (IS_ERR_OR_NULL(ctl->thread)) + panic("Failed to create bio dispatch thread\n"); + + wake_up_process(ctl->thread); + } +} +#else +static int blk_alloc_queue_dispatch_async(struct request_queue *q) +{ + return 0; +} + +static bool submit_bio_noacct_async(struct bio *bio) +{ + return false; +} + +static void init_blk_queue_async_dispatch(void) +{ +} +#endif + /** * blk_queue_flag_set - atomically set a queue flag * @flag: flag to be set @@ -539,9 +767,12 @@ struct request_queue *blk_alloc_queue(int node_id) q->last_merge = NULL; + if (blk_alloc_queue_dispatch_async(q)) + goto fail_q; + q->id = ida_simple_get(&blk_queue_ida, 0, 0, GFP_KERNEL); if (q->id < 0) - goto fail_q; + goto fail_dispatch_async; ret = bioset_init(&q->bio_split, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); if (ret) @@ -606,6 +837,8 @@ struct request_queue *blk_alloc_queue(int node_id) bioset_exit(&q->bio_split); fail_id: ida_simple_remove(&blk_queue_ida, q->id); +fail_dispatch_async: + blk_free_queue_dispatch_async(q); fail_q: kmem_cache_free(blk_requestq_cachep, q); return NULL; @@ -1055,6 +1288,9 @@ static blk_qc_t __submit_bio_noacct_mq(struct bio *bio) */ blk_qc_t submit_bio_noacct(struct bio *bio) { + if (submit_bio_noacct_async(bio)) + return BLK_QC_T_NONE; + if (!submit_bio_checks(bio)) return BLK_QC_T_NONE; @@ -1905,5 +2141,7 @@ int __init blk_dev_init(void) blk_debugfs_root = debugfs_create_dir("block", NULL); + init_blk_queue_async_dispatch(); + return 0; } diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index a879f94782e4..b5b17c6ee650 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c @@ -131,6 +131,7 @@ static const char *const blk_queue_flag_name[] = { QUEUE_FLAG_NAME(RQ_ALLOC_TIME), QUEUE_FLAG_NAME(HCTX_ACTIVE), QUEUE_FLAG_NAME(NOWAIT), + QUEUE_FLAG_NAME(DISPATCH_ASYNC), }; #undef QUEUE_FLAG_NAME diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index c95be9626a09..53598eb6affd 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -288,6 +288,9 @@ QUEUE_SYSFS_BIT_FNS(nonrot, NONROT, 1); QUEUE_SYSFS_BIT_FNS(random, ADD_RANDOM, 0); QUEUE_SYSFS_BIT_FNS(iostats, IO_STAT, 0); QUEUE_SYSFS_BIT_FNS(stable_writes, STABLE_WRITES, 0); +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC +QUEUE_SYSFS_BIT_FNS(dispatch_async, DISPATCH_ASYNC, 0); +#endif #undef QUEUE_SYSFS_BIT_FNS static ssize_t queue_zoned_show(struct request_queue *q, char *page) @@ -619,6 +622,57 @@ QUEUE_RW_ENTRY(queue_iostats, "iostats"); QUEUE_RW_ENTRY(queue_random, "add_random"); QUEUE_RW_ENTRY(queue_stable_writes, "stable_writes"); +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC + +static ssize_t queue_dispatch_async_cpus_show(struct request_queue *q, + char *page) +{ + return sprintf(page, "%*pb\n", nr_cpu_ids, + cpumask_bits(q->dispatch_async_cpus)); +} + +static ssize_t queue_dispatch_async_cpus_store(struct request_queue *q, + const char *page, size_t count) +{ + cpumask_var_t cpumask; + ssize_t ret; + + if (!alloc_cpumask_var(&cpumask, GFP_KERNEL)) + return -ENOMEM; + + ret = bitmap_parse(page, count, cpumask_bits(cpumask), + nr_cpumask_bits); + if (ret < 0) + goto out; + + if (cpumask_empty(cpumask) || + !cpumask_subset(cpumask, cpu_online_mask)) { + ret = -EINVAL; + goto out; + } + + blk_mq_freeze_queue(q); + blk_mq_quiesce_queue(q); + + cpumask_copy(q->dispatch_async_cpus, cpumask); + + blk_mq_unquiesce_queue(q); + blk_mq_unfreeze_queue(q); + ret = count; +out: + free_cpumask_var(cpumask); + return ret; +} + +static struct queue_sysfs_entry queue_dispatch_async_cpus_entry = { + .attr = {.name = "dispatch_async_cpus", .mode = 0644 }, + .show = queue_dispatch_async_cpus_show, + .store = queue_dispatch_async_cpus_store, +}; + +QUEUE_RW_ENTRY(queue_dispatch_async, "dispatch_async"); +#endif + static struct attribute *queue_attrs[] = { &queue_requests_entry.attr, &queue_ra_entry.attr, @@ -659,6 +713,10 @@ static struct attribute *queue_attrs[] = { &queue_wb_lat_entry.attr, &queue_poll_delay_entry.attr, &queue_io_timeout_entry.attr, +#ifdef CONFIG_BLK_BIO_DISPATCH_ASYNC + &queue_dispatch_async_cpus_entry.attr, + &queue_dispatch_async_entry.attr, +#endif #ifdef CONFIG_BLK_DEV_THROTTLING_LOW &blk_throtl_sample_time_entry.attr, #endif @@ -795,6 +853,7 @@ static void blk_release_queue(struct kobject *kobj) blk_stat_remove_callback(q, q->poll_cb); blk_stat_free_callback(q->poll_cb); + blk_free_queue_dispatch_async(q); blk_free_queue_stats(q->stats); blk_exit_queue(q); diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index d2ba9ee9eb81..996a6196cc5a 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -964,6 +964,7 @@ CONFIG_BLK_DEBUG_FS_ZONED=y # CONFIG_BLK_SED_OPAL is not set # CONFIG_BLK_INLINE_ENCRYPTION is not set CONFIG_BLK_DEV_DUMPINFO=y +CONFIG_BLK_BIO_DISPATCH_ASYNC=y # # Partition Types diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index dbf869f75111..6b014668cf4d 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -942,6 +942,7 @@ CONFIG_BLK_DEBUG_FS_ZONED=y # CONFIG_BLK_SED_OPAL is not set # CONFIG_BLK_INLINE_ENCRYPTION is not set CONFIG_BLK_DEV_DUMPINFO=y +CONFIG_BLK_BIO_DISPATCH_ASYNC=y # # Partition Types diff --git a/block/Kconfig b/block/Kconfig index e5c965f1ea25..24c6bb87727d 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -209,6 +209,17 @@ config BLK_DEV_DUMPINFO Dump info when open an write opened block device exclusively or open an exclusive opened device for write +config BLK_BIO_DISPATCH_ASYNC + bool "Dispatch bios asynchronously on specific cpus" + default n + help + In certain environments, specific CPUs handle a large number of + tasks and become bottlenecks, affecting overall system + performance. This commit introduces a new feature that enables + asynchronous I/O dispatch to designated CPUs, thereby relieving + the pressure on the busy CPUs. + If unsure, say N. + menu "Partition Types" source "block/partitions/Kconfig" -- 2.39.2
1 0
0 0
[PATCH openEuler-22.03-LTS-SP1] afs: Fix corruption in reads at fpos 2G-4G from an OpenAFS server
by Zizhi Wo 14 Jun '24

14 Jun '24
From: David Howells <dhowells(a)redhat.com> stable inclusion from stable-v5.14.9 commit e66fc460d6dcf85cf12288e133a081205aebcd97 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9R4M4 CVE: CVE-2021-47366 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- [ Upstream commit b537a3c21775075395af475dcc6ef212fcf29db8 ] AFS-3 has two data fetch RPC variants, FS.FetchData and FS.FetchData64, and Linux's afs client switches between them when talking to a non-YFS server if the read size, the file position or the sum of the two have the upper 32 bits set of the 64-bit value. This is a problem, however, since the file position and length fields of FS.FetchData are *signed* 32-bit values. Fix this by capturing the capability bits obtained from the fileserver when it's sent an FS.GetCapabilities RPC, rather than just discarding them, and then picking out the VICED_CAPABILITY_64BITFILES flag. This can then be used to decide whether to use FS.FetchData or FS.FetchData64 - and also FS.StoreData or FS.StoreData64 - rather than using upper_32_bits() to switch on the parameter values. This capabilities flag could also be used to limit the maximum size of the file, but all servers must be checked for that. Note that the issue does not exist with FS.StoreData - that uses *unsigned* 32-bit values. It's also not a problem with Auristor servers as its YFS.FetchData64 op uses unsigned 64-bit values. This can be tested by cloning a git repo through an OpenAFS client to an OpenAFS server and then doing "git status" on it from a Linux afs client[1]. Provided the clone has a pack file that's in the 2G-4G range, the git status will show errors like: error: packfile .git/objects/pack/pack-5e813c51d12b6847bbc0fcd97c2bca66da50079c.pack does not match index error: packfile .git/objects/pack/pack-5e813c51d12b6847bbc0fcd97c2bca66da50079c.pack does not match index This can be observed in the server's FileLog with something like the following appearing: Sun Aug 29 19:31:39 2021 SRXAFS_FetchData, Fid = 2303380852.491776.3263114, Host 192.168.11.201:7001, Id 1001 Sun Aug 29 19:31:39 2021 CheckRights: len=0, for host=192.168.11.201:7001 Sun Aug 29 19:31:39 2021 FetchData_RXStyle: Pos 18446744071815340032, Len 3154 Sun Aug 29 19:31:39 2021 FetchData_RXStyle: file size 2400758866 ... Sun Aug 29 19:31:40 2021 SRXAFS_FetchData returns 5 Note the file position of 18446744071815340032. This is the requested file position sign-extended. Fixes: b9b1f8d5930a ("AFS: write support fixes") Reported-by: Markus Suvanto <markus.suvanto(a)gmail.com> Signed-off-by: David Howells <dhowells(a)redhat.com> Reviewed-by: Marc Dionne <marc.dionne(a)auristor.com> Tested-by: Markus Suvanto <markus.suvanto(a)gmail.com> cc: linux-afs(a)lists.infradead.org cc: openafs-devel(a)openafs.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=214217#c9 [1] Link: https://lore.kernel.org/r/951332.1631308745@warthog.procyon.org.uk/ Signed-off-by: Sasha Levin <sashal(a)kernel.org> Conflicts: fs/afs/fs_probe.c fs/afs/fsclient.c [Simple context conflict adaptation.] Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com> --- fs/afs/fs_probe.c | 8 +++++++- fs/afs/fsclient.c | 30 ++++++++++++++++++++---------- fs/afs/internal.h | 1 + fs/afs/protocol_afs.h | 15 +++++++++++++++ fs/afs/protocol_yfs.h | 6 ++++++ 5 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 fs/afs/protocol_afs.h diff --git a/fs/afs/fs_probe.c b/fs/afs/fs_probe.c index e7e98ad63a91..c0031a3ab42f 100644 --- a/fs/afs/fs_probe.c +++ b/fs/afs/fs_probe.c @@ -9,6 +9,7 @@ #include <linux/slab.h> #include "afs_fs.h" #include "internal.h" +#include "protocol_afs.h" #include "protocol_yfs.h" static unsigned int afs_fs_probe_fast_poll_interval = 30 * HZ; @@ -102,7 +103,7 @@ void afs_fileserver_probe_result(struct afs_call *call) struct afs_addr_list *alist = call->alist; struct afs_server *server = call->server; unsigned int index = call->addr_ix; - unsigned int rtt_us = 0; + unsigned int rtt_us = 0, cap0; int ret = call->error; _enter("%pU,%u", &server->uuid, index); @@ -159,6 +160,11 @@ void afs_fileserver_probe_result(struct afs_call *call) clear_bit(AFS_SERVER_FL_IS_YFS, &server->flags); alist->addrs[index].srx_service = call->service_id; } + cap0 = ntohl(call->tmp); + if (cap0 & AFS3_VICED_CAPABILITY_64BITFILES) + set_bit(AFS_SERVER_FL_HAS_FS64, &server->flags); + else + clear_bit(AFS_SERVER_FL_HAS_FS64, &server->flags); } if (rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us) && diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index 0048a32cb040..bf1fd9d187dc 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c @@ -483,9 +483,7 @@ void afs_fs_fetch_data(struct afs_operation *op) struct afs_read *req = op->fetch.req; __be32 *bp; - if (upper_32_bits(req->pos) || - upper_32_bits(req->len) || - upper_32_bits(req->pos + req->len)) + if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags)) return afs_fs_fetch_data64(op); _enter(""); @@ -1149,8 +1147,7 @@ void afs_fs_store_data(struct afs_operation *op) (unsigned long long) size, (unsigned long long) pos, (unsigned long long) i_size); - if (upper_32_bits(pos) || upper_32_bits(i_size) || upper_32_bits(size) || - upper_32_bits(pos + size)) + if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags)) return afs_fs_store_data64(op, pos, size, i_size); call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData, @@ -1264,7 +1261,7 @@ static void afs_fs_setattr_size(struct afs_operation *op) key_serial(op->key), vp->fid.vid, vp->fid.vnode); ASSERT(attr->ia_valid & ATTR_SIZE); - if (upper_32_bits(attr->ia_size)) + if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags)) return afs_fs_setattr_size64(op); call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData_as_Status, @@ -1691,20 +1688,33 @@ static int afs_deliver_fs_get_capabilities(struct afs_call *call) return ret; count = ntohl(call->tmp); - call->count = count; call->count2 = count; - afs_extract_discard(call, count * sizeof(__be32)); + if (count == 0) { + call->unmarshall = 4; + call->tmp = 0; + break; + } + + /* Extract the first word of the capabilities to call->tmp */ + afs_extract_to_tmp(call); call->unmarshall++; fallthrough; - /* Extract capabilities words */ case 2: ret = afs_extract_data(call, false); if (ret < 0) return ret; - /* TODO: Examine capabilities */ + afs_extract_discard(call, (count - 1) * sizeof(__be32)); + call->unmarshall++; + fallthrough; + + /* Extract remaining capabilities words */ + case 3: + ret = afs_extract_data(call, false); + if (ret < 0) + return ret; call->unmarshall++; break; diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 637cbe549397..8ce13fe4dd78 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -510,6 +510,7 @@ struct afs_server { #define AFS_SERVER_FL_IS_YFS 16 /* Server is YFS not AFS */ #define AFS_SERVER_FL_NO_IBULK 17 /* Fileserver doesn't support FS.InlineBulkStatus */ #define AFS_SERVER_FL_NO_RM2 18 /* Fileserver doesn't support YFS.RemoveFile2 */ +#define AFS_SERVER_FL_HAS_FS64 19 /* Fileserver supports FS.{Fetch,Store}Data64 */ atomic_t ref; /* Object refcount */ atomic_t active; /* Active user count */ u32 addr_version; /* Address list version */ diff --git a/fs/afs/protocol_afs.h b/fs/afs/protocol_afs.h new file mode 100644 index 000000000000..0c39358c8b70 --- /dev/null +++ b/fs/afs/protocol_afs.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* AFS protocol bits + * + * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells(a)redhat.com) + */ + + +#define AFSCAPABILITIESMAX 196 /* Maximum number of words in a capability set */ + +/* AFS3 Fileserver capabilities word 0 */ +#define AFS3_VICED_CAPABILITY_ERRORTRANS 0x0001 /* Uses UAE errors */ +#define AFS3_VICED_CAPABILITY_64BITFILES 0x0002 /* FetchData64 & StoreData64 supported */ +#define AFS3_VICED_CAPABILITY_WRITELOCKACL 0x0004 /* Can lock a file even without lock perm */ +#define AFS3_VICED_CAPABILITY_SANEACLS 0x0008 /* ACLs reviewed for sanity - don't use */ diff --git a/fs/afs/protocol_yfs.h b/fs/afs/protocol_yfs.h index b5bd03b1d3c7..e4cd89c44c46 100644 --- a/fs/afs/protocol_yfs.h +++ b/fs/afs/protocol_yfs.h @@ -168,3 +168,9 @@ enum yfs_lock_type { yfs_LockMandatoryWrite = 0x101, yfs_LockMandatoryExtend = 0x102, }; + +/* RXYFS Viced Capability Flags */ +#define YFS_VICED_CAPABILITY_ERRORTRANS 0x0001 /* Deprecated v0.195 */ +#define YFS_VICED_CAPABILITY_64BITFILES 0x0002 /* Deprecated v0.195 */ +#define YFS_VICED_CAPABILITY_WRITELOCKACL 0x0004 /* Can lock a file even without lock perm */ +#define YFS_VICED_CAPABILITY_SANEACLS 0x0008 /* Deprecated v0.195 */ -- 2.39.2
2 1
0 0
[PATCH OLK-5.10 v3 0/2] block: support to dispatch bio asynchronously
by Li Nan 14 Jun '24

14 Jun '24
v3: code optimization. Li Nan (2): block: support to dispatch bio asynchronously block: fix kabi broken in struct request_queue about CONFIG_BLK_BIO_DISPATCH_ASYNC block/blk.h | 7 + include/linux/blk_types.h | 1 + include/linux/blkdev.h | 9 + block/blk-core.c | 240 ++++++++++++++++++++++++- block/blk-mq-debugfs.c | 1 + block/blk-sysfs.c | 59 ++++++ arch/arm64/configs/openeuler_defconfig | 1 + arch/x86/configs/openeuler_defconfig | 1 + block/Kconfig | 11 ++ 9 files changed, 329 insertions(+), 1 deletion(-) -- 2.39.2
2 3
0 0
[PATCH openEuler-1.0-LTS v3 0/2] block: support to dispatch bio asynchronously
by Li Nan 14 Jun '24

14 Jun '24
v3: code optimization. Li Nan (2): block: support to dispatch bio asynchronously block: fix kabi broken in struct request_queue about CONFIG_BLK_BIO_DISPATCH_ASYNC block/blk.h | 7 + include/linux/blk_types.h | 1 + include/linux/blkdev.h | 9 + block/blk-core.c | 240 ++++++++++++++++++++++++- block/blk-mq-debugfs.c | 1 + block/blk-sysfs.c | 59 ++++++ arch/arm64/configs/openeuler_defconfig | 1 + arch/x86/configs/openeuler_defconfig | 1 + block/Kconfig | 11 ++ 9 files changed, 329 insertions(+), 1 deletion(-) -- 2.39.2
2 3
0 0
[PATCH OLK-5.10 v2 0/2] block: support to dispatch bio asynchronously
by Li Nan 14 Jun '24

14 Jun '24
v2: bugfix and code optimization. Li Nan (2): block: support to dispatch bio asynchronously block: fix kabi broken in struct request_queue about CONFIG_BLK_BIO_DISPATCH_ASYNC block/blk.h | 7 + include/linux/blk_types.h | 1 + include/linux/blkdev.h | 9 + block/blk-core.c | 238 ++++++++++++++++++++++++- block/blk-mq-debugfs.c | 1 + block/blk-sysfs.c | 60 +++++++ arch/arm64/configs/openeuler_defconfig | 1 + arch/x86/configs/openeuler_defconfig | 1 + block/Kconfig | 11 ++ 9 files changed, 328 insertions(+), 1 deletion(-) -- 2.39.2
2 3
0 0
  • ← Newer
  • 1
  • ...
  • 923
  • 924
  • 925
  • 926
  • 927
  • 928
  • 929
  • ...
  • 1907
  • Older →

HyperKitty Powered by HyperKitty