From patchwork Sun Feb 26 16:02:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ammar Faizi X-Patchwork-Id: 13152440 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C44C0C6FA8E for ; Sun, 26 Feb 2023 16:03:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229675AbjBZQDm (ORCPT ); Sun, 26 Feb 2023 11:03:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229563AbjBZQDf (ORCPT ); Sun, 26 Feb 2023 11:03:35 -0500 Received: from gnuweeb.org (gnuweeb.org [51.81.211.47]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E3EDBDEB; Sun, 26 Feb 2023 08:03:23 -0800 (PST) Received: from localhost.localdomain (unknown [182.253.183.169]) by gnuweeb.org (Postfix) with ESMTPSA id D189C831AB; Sun, 26 Feb 2023 16:03:18 +0000 (UTC) X-GW-Data: lPqxHiMPbJw1wb7CM9QUryAGzr0yq5atzVDdxTR0iA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=default; t=1677427403; bh=VLdIA0Ryrjg4sqcZ4qs9212xaCVaprtzgyOR34VDtxc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mQ0KI6MLmFZy5fNV0dblCFChQ7CoCIrNnIkAJTvDHbO2K2nCKsvV0ZhdZNpW7+NnQ IOI263lqaJo4TBbDplL4Th3KYfgol/qUGoVYiduQViA5IuOfg1wRxmSHnTibJFBOpm LS7V5ikK1AUlWRPQFKcwJH3mU0r6I+fSGaMS/6VUlW2dUXZAoFzK5901bap+We8Bn4 xIVeyUo0nNBOqBQB3qcENdMYKOpB0exofmUbaiyIZ6V0Yrf5rZejsSziBcg7ityiJQ qz44FB23tC+PMCMhPl5p/JJc9UicgOvVM4IMAZSvQ7nyMccVQXw9/IC3r2qjcmY9FV AzyspPQipjinw== From: Ammar Faizi To: Chris Mason , Josef Bacik , David Sterba , Tejun Heo Cc: Ammar Faizi , Lai Jiangshan , Filipe Manana , Linux Btrfs Mailing List , Linux Kernel Mailing List , Linux Fsdevel Mailing List , GNU/Weeb Mailing List Subject: [RFC PATCH v1 1/6] workqueue: Add set_workqueue_cpumask() helper function Date: Sun, 26 Feb 2023 23:02:54 +0700 Message-Id: <20230226160259.18354-2-ammarfaizi2@gnuweeb.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> References: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Allow users to specify a CPU set for the workqueue. The first use case of this helper function is to set the CPU affinity of Btrfs workqueues. Signed-off-by: Ammar Faizi --- include/linux/workqueue.h | 3 +++ kernel/workqueue.c | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index ac551b8ee7d9f2f4..e3bd6f47e74ecd66 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -710,6 +710,9 @@ int workqueue_online_cpu(unsigned int cpu); int workqueue_offline_cpu(unsigned int cpu); #endif +int set_workqueue_cpumask(struct workqueue_struct *wq, + const cpumask_var_t mask); + void __init workqueue_init_early(void); void __init workqueue_init(void); diff --git a/kernel/workqueue.c b/kernel/workqueue.c index b8b541caed4854a4..adc1478fafb1811c 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -4398,6 +4398,25 @@ static int init_rescuer(struct workqueue_struct *wq) return 0; } +int set_workqueue_cpumask(struct workqueue_struct *wq, const cpumask_var_t mask) +{ + struct workqueue_attrs *tmp_attrs; + int ret; + + tmp_attrs = alloc_workqueue_attrs(); + if (!tmp_attrs) + return -ENOMEM; + + apply_wqattrs_lock(); + copy_workqueue_attrs(tmp_attrs, wq->unbound_attrs); + cpumask_copy(tmp_attrs->cpumask, mask); + ret = apply_workqueue_attrs_locked(wq, tmp_attrs); + apply_wqattrs_unlock(); + free_workqueue_attrs(tmp_attrs); + return ret; +} +EXPORT_SYMBOL_GPL(set_workqueue_cpumask); + __printf(1, 4) struct workqueue_struct *alloc_workqueue(const char *fmt, unsigned int flags, From patchwork Sun Feb 26 16:02:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ammar Faizi X-Patchwork-Id: 13152441 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3F353C64ED6 for ; Sun, 26 Feb 2023 16:03:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229647AbjBZQDp (ORCPT ); Sun, 26 Feb 2023 11:03:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229661AbjBZQDm (ORCPT ); Sun, 26 Feb 2023 11:03:42 -0500 Received: from gnuweeb.org (gnuweeb.org [51.81.211.47]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D53EC1041B; Sun, 26 Feb 2023 08:03:28 -0800 (PST) Received: from localhost.localdomain (unknown [182.253.183.169]) by gnuweeb.org (Postfix) with ESMTPSA id 19DE8831AF; Sun, 26 Feb 2023 16:03:23 +0000 (UTC) X-GW-Data: lPqxHiMPbJw1wb7CM9QUryAGzr0yq5atzVDdxTR0iA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=default; t=1677427408; bh=dk6mSe4MY5NIqRMjCLFlrLyUSKZZEVxaqAfyqXfwVa4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=k6QRoXLqOsMTebWNx0TMa8JLFQVdx/XStS+s7pCIKLmXL1YwM68tMgh+aty7mpfTj CDYcYLrv1aihPsIr4VeASZQMuo8uhqBEvIRqB1L0IyXK4W1nYvvw/9XttO0PlH5It5 BA8KHyfpV6+rCMMDHJ0kcrl0vxyKWnJSpCJv9RVe/nHQTPcAtCG1yYN9Rw8RuTGxUb EzxeckC0J4GDK81Y5bmNNanHEEdEV4e6hiIVZf0sNgZpvCfsDH+UeYHeeZstmnle33 7SPKZLvxBvCMGXDE9A28i5TCvefHYrJ/q2HtSMLQ4dy9pj3k5kizVzFYSEn3V7QTyY SsmHAUF2408Jw== From: Ammar Faizi To: Chris Mason , Josef Bacik , David Sterba , Tejun Heo Cc: Ammar Faizi , Lai Jiangshan , Filipe Manana , Linux Btrfs Mailing List , Linux Kernel Mailing List , Linux Fsdevel Mailing List , GNU/Weeb Mailing List Subject: [RFC PATCH v1 2/6] btrfs: Change `mount_opt` type in `struct btrfs_fs_info` to `u64` Date: Sun, 26 Feb 2023 23:02:55 +0700 Message-Id: <20230226160259.18354-3-ammarfaizi2@gnuweeb.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> References: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org On a 32-bit Linux system, `unsigned long` is 32-bit. In preparation to add more mount options, change the type to `u64` because the enum for this option has reached the max 32-bit capacity. It does not make any difference on a system where `unsigned long` is 64-bit, only needed for the 32-bit system. Signed-off-by: Ammar Faizi --- fs/btrfs/fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h index 4c477eae689148dd..6de61367b6686197 100644 --- a/fs/btrfs/fs.h +++ b/fs/btrfs/fs.h @@ -422,7 +422,7 @@ struct btrfs_fs_info { * required instead of the faster short fsync log commits */ u64 last_trans_log_full_commit; - unsigned long mount_opt; + u64 mount_opt; unsigned long compress_type:4; unsigned int compress_level; From patchwork Sun Feb 26 16:02:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ammar Faizi X-Patchwork-Id: 13152442 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4566C6FA8E for ; Sun, 26 Feb 2023 16:03:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229736AbjBZQDt (ORCPT ); Sun, 26 Feb 2023 11:03:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229653AbjBZQDp (ORCPT ); Sun, 26 Feb 2023 11:03:45 -0500 Received: from gnuweeb.org (gnuweeb.org [51.81.211.47]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 11912A5D6; Sun, 26 Feb 2023 08:03:34 -0800 (PST) Received: from localhost.localdomain (unknown [182.253.183.169]) by gnuweeb.org (Postfix) with ESMTPSA id 4F8AF831A3; Sun, 26 Feb 2023 16:03:28 +0000 (UTC) X-GW-Data: lPqxHiMPbJw1wb7CM9QUryAGzr0yq5atzVDdxTR0iA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=default; t=1677427413; bh=Myw3hByCu9lylJKDc0tVPW8sdVob9FBj4sLqjc1V50w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tr4VLw5aC8ArluOFX0XvTmPqY4tIRGeOer0XOLd/mKyollc+09Q5iH1xYOgfph3Ge XywUJAaYIplTR0M/AhYE1lhc/ldNDpXO5KXGnlLk5iG+/WesuX7n1Jfl6CzkbWXETN /e0xtyi+ypKwPih3XkFwovwB6vJT/BFM2etoV+zGHN2FBHcclQ+nt44kiFF/yxuRc6 b4Bg4JLsVu7ZfR4K1o37ZNxxx3B2WWg6Z5Xja545mbBx/ygCPCc+UK60W+feYbxRy9 emnIJlf/YdeshvtZ7LavzpxQFjlzaaYzUa5zEEEK4ooYIhljce5+YyvvKkglUCsoya c5IT3+9s2k0sQ== From: Ammar Faizi To: Chris Mason , Josef Bacik , David Sterba , Tejun Heo Cc: Ammar Faizi , Lai Jiangshan , Filipe Manana , Linux Btrfs Mailing List , Linux Kernel Mailing List , Linux Fsdevel Mailing List , GNU/Weeb Mailing List Subject: [RFC PATCH v1 3/6] btrfs: Create btrfs CPU set struct and helpers Date: Sun, 26 Feb 2023 23:02:56 +0700 Message-Id: <20230226160259.18354-4-ammarfaizi2@gnuweeb.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> References: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org It's a preparation to add Btrfs CPU affinity support. First, create a new struct named `btrfs_cpu_set` to contain CPU affinity information. Then, create helpers to allocate, parse, and free them. Signed-off-by: Ammar Faizi --- fs/btrfs/fs.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/fs.h | 7 ++++ 2 files changed, 104 insertions(+) diff --git a/fs/btrfs/fs.c b/fs/btrfs/fs.c index 31c1648bc0b46922..283d153d4491289c 100644 --- a/fs/btrfs/fs.c +++ b/fs/btrfs/fs.c @@ -96,3 +96,100 @@ void __btrfs_clear_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag, set_bit(BTRFS_FS_FEATURE_CHANGED, &fs_info->flags); } } + +/* + * The user can't use the taskset pattern because ',' is used as + * the mount option delimiter. They can use the same taskset pattern, + * but replace the ',' with '.' and we will replace it back to + * ',', so the cpulist_parse() can recognize it. + * + * For example, in taskset cmd, they do: + * taskset -c 1,4,7 /bin/ls + * + * The equivalent CPU mask for the btrfs mount option will be: + * wq_cpu_set=1.4.7 + * + * Mark these as __cold to avoid the code bloat from overoptimizing + * the loop. + */ +__cold static void cpulist_dot_to_comma(char *set) +{ + while (*set) { + if (*set == '.') + *set = ','; + set++; + } +} + +__cold static void cpulist_comma_to_dot(char *set) +{ + while (*set) { + if (*set == ',') + *set = '.'; + set++; + } +} + +void btrfs_destroy_cpu_set(struct btrfs_cpu_set *cpu_set) +{ + if (!cpu_set) + return; + + free_cpumask_var(cpu_set->mask); + kfree(cpu_set->mask_str); + kfree(cpu_set); +} + +/* + * Only called from btrfs_parse_cpu_set(). + */ +static struct btrfs_cpu_set *btrfs_alloc_cpu_set(void) +{ + struct btrfs_cpu_set *cpu_set; + + cpu_set = kmalloc(sizeof(*cpu_set), GFP_KERNEL); + if (!cpu_set) + return NULL; + + if (!alloc_cpumask_var(&cpu_set->mask, GFP_KERNEL)) { + kfree(cpu_set); + return NULL; + } + + cpu_set->mask_str = NULL; + return cpu_set; +} + +int btrfs_parse_cpu_set(struct btrfs_cpu_set **cpu_set_p, const char *mask_str) +{ + struct btrfs_cpu_set *cpu_set; + int ret; + + cpu_set = btrfs_alloc_cpu_set(); + if (!cpu_set) + return -ENOMEM; + + cpu_set->mask_str = kstrdup(mask_str, GFP_KERNEL); + if (!cpu_set->mask_str) { + ret = -ENOMEM; + goto out_fail; + } + + cpulist_dot_to_comma(cpu_set->mask_str); + ret = cpulist_parse(cpu_set->mask_str, cpu_set->mask); + if (ret) + goto out_fail; + + if (cpumask_empty(cpu_set->mask)) { + ret = -EINVAL; + goto out_fail; + } + + cpulist_comma_to_dot(cpu_set->mask_str); + *cpu_set_p = cpu_set; + return 0; + +out_fail: + btrfs_destroy_cpu_set(cpu_set); + return ret; +} diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h index 6de61367b6686197..cbad856df197ccfd 100644 --- a/fs/btrfs/fs.h +++ b/fs/btrfs/fs.h @@ -356,6 +356,11 @@ struct btrfs_commit_stats { u64 total_commit_dur; }; +struct btrfs_cpu_set { + cpumask_var_t mask; + char *mask_str; +}; + struct btrfs_fs_info { u8 chunk_tree_uuid[BTRFS_UUID_SIZE]; unsigned long flags; @@ -876,6 +881,8 @@ void btrfs_exclop_start_unlock(struct btrfs_fs_info *fs_info); void btrfs_exclop_finish(struct btrfs_fs_info *fs_info); void btrfs_exclop_balance(struct btrfs_fs_info *fs_info, enum btrfs_exclusive_operation op); +int btrfs_parse_cpu_set(struct btrfs_cpu_set **cpu_set_p, const char *mask_str); +void btrfs_destroy_cpu_set(struct btrfs_cpu_set *cpu_set); /* Compatibility and incompatibility defines */ void __btrfs_set_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag, From patchwork Sun Feb 26 16:02:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ammar Faizi X-Patchwork-Id: 13152443 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C53BEC6FA8E for ; Sun, 26 Feb 2023 16:03:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229789AbjBZQD6 (ORCPT ); Sun, 26 Feb 2023 11:03:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229742AbjBZQDt (ORCPT ); Sun, 26 Feb 2023 11:03:49 -0500 Received: from gnuweeb.org (gnuweeb.org [51.81.211.47]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F19911148; Sun, 26 Feb 2023 08:03:39 -0800 (PST) Received: from localhost.localdomain (unknown [182.253.183.169]) by gnuweeb.org (Postfix) with ESMTPSA id 8BF448319A; Sun, 26 Feb 2023 16:03:34 +0000 (UTC) X-GW-Data: lPqxHiMPbJw1wb7CM9QUryAGzr0yq5atzVDdxTR0iA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=default; t=1677427419; bh=Lh3FXdEhYYeO5gm8fhDvdFLZ3MyGY8XmpI1g+zO/bzM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qS5tQrh8N7LynwYGLCSJ4ErfaCVhz7srFXQRwx5s89dmmINfJUqGPMtqWjaWj7CP9 jiUUntXWfORMAAomVD/DOEkYxkS2ZybyexRCoMUCFjIHc2U9DAV92s5OQM74i2PHhc J7rHtmlHpokZfymAN6KJEQOnF+FCu/XfWh+R7y2frqDfNp+zYDKZPLVuvF4aEo+rn9 lQliMIaVzM7szZp0BsFrQ8c68uVYLsHT36/4ZP12ZAmej4XdjJ45GlWeKiZD8tzlV/ Or/1YuiCwYLX4KBn85DlUIIcjTKkSiCFX+mpPgFeo1eFQPaOpYy1DiLxRQ892Sr7my WfPG7bsFfZs5Q== From: Ammar Faizi To: Chris Mason , Josef Bacik , David Sterba , Tejun Heo Cc: Ammar Faizi , Lai Jiangshan , Filipe Manana , Linux Btrfs Mailing List , Linux Kernel Mailing List , Linux Fsdevel Mailing List , GNU/Weeb Mailing List Subject: [RFC PATCH v1 4/6] btrfs: Add wq_cpu_set=%s mount option Date: Sun, 26 Feb 2023 23:02:57 +0700 Message-Id: <20230226160259.18354-5-ammarfaizi2@gnuweeb.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> References: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Btrfs workqueues can slow sensitive user tasks down because they can use any online CPU to perform heavy workloads on an SMP system. Add a mount option to isolate the Btrfs workqueues to a set of CPUs. It is helpful to avoid sensitive user tasks being preempted by Btrfs heavy workqueues. This option is similar to the taskset bitmask except that the comma separator is replaced with a dot. The reason for this is that the mount option parser uses commas to separate mount options. Signed-off-by: Ammar Faizi --- fs/btrfs/async-thread.c | 51 +++++++++++++++++++++++++++++++++++++++++ fs/btrfs/async-thread.h | 1 + fs/btrfs/disk-io.c | 3 ++- fs/btrfs/fs.h | 3 +++ fs/btrfs/super.c | 44 +++++++++++++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index aac240430efe1316..445c055304574653 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c @@ -11,6 +11,7 @@ #include #include "async-thread.h" #include "ctree.h" +#include "messages.h" enum { WORK_DONE_BIT, @@ -339,3 +340,53 @@ void btrfs_flush_workqueue(struct btrfs_workqueue *wq) { flush_workqueue(wq->normal_wq); } + +static int apply_wq_cpu_set_notice(struct btrfs_fs_info *info, + struct workqueue_struct *wq, + const char *wq_name) +{ + const char *mask_str = info->wq_cpu_set->mask_str; + int ret; + + ret = set_workqueue_cpumask(wq, info->wq_cpu_set->mask); + if (ret) { + btrfs_err(info, "failed to set cpu mask for %s wq: %d", wq_name, + ret); + return ret; + } + + btrfs_info(info, "set cpu mask for %s wq to %s", wq_name, mask_str); + return 0; +} + +#define apply_wq_cpu_set(INFO, WQ) \ + apply_wq_cpu_set_notice(INFO, (INFO)->WQ, # WQ) + +#define btrfs_apply_wq_cpu_set(INFO, WQ) \ + apply_wq_cpu_set_notice(INFO, (INFO)->WQ->normal_wq, # WQ) + + +void btrfs_apply_workqueue_cpu_set(struct btrfs_fs_info *fs_info) +{ + if (!btrfs_test_opt(fs_info, WQ_CPU_SET)) + return; + + btrfs_apply_wq_cpu_set(fs_info, workers); + btrfs_apply_wq_cpu_set(fs_info, hipri_workers); + btrfs_apply_wq_cpu_set(fs_info, delalloc_workers); + btrfs_apply_wq_cpu_set(fs_info, flush_workers); + btrfs_apply_wq_cpu_set(fs_info, caching_workers); + btrfs_apply_wq_cpu_set(fs_info, fixup_workers); + apply_wq_cpu_set(fs_info, endio_workers); + apply_wq_cpu_set(fs_info, endio_meta_workers); + apply_wq_cpu_set(fs_info, rmw_workers); + btrfs_apply_wq_cpu_set(fs_info, endio_write_workers); + apply_wq_cpu_set(fs_info, compressed_write_workers); + btrfs_apply_wq_cpu_set(fs_info, endio_freespace_worker); + btrfs_apply_wq_cpu_set(fs_info, delayed_workers); + btrfs_apply_wq_cpu_set(fs_info, qgroup_rescan_workers); + apply_wq_cpu_set(fs_info, discard_ctl.discard_workers); +} + +#undef apply_wq_cpu_set +#undef btrfs_apply_wq_cpu_set diff --git a/fs/btrfs/async-thread.h b/fs/btrfs/async-thread.h index 6e2596ddae1002ab..2b8a76fa75ef9e69 100644 --- a/fs/btrfs/async-thread.h +++ b/fs/btrfs/async-thread.h @@ -41,5 +41,6 @@ struct btrfs_fs_info * __pure btrfs_work_owner(const struct btrfs_work *work); struct btrfs_fs_info * __pure btrfs_workqueue_owner(const struct btrfs_workqueue *wq); bool btrfs_workqueue_normal_congested(const struct btrfs_workqueue *wq); void btrfs_flush_workqueue(struct btrfs_workqueue *wq); +void btrfs_apply_workqueue_cpu_set(struct btrfs_fs_info *fs_info); #endif diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index b53f0e30ce2b3bbb..1bb1db461a30fa71 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1498,6 +1498,7 @@ static void free_global_roots(struct btrfs_fs_info *fs_info) void btrfs_free_fs_info(struct btrfs_fs_info *fs_info) { + btrfs_destroy_cpu_set(fs_info->wq_cpu_set); percpu_counter_destroy(&fs_info->dirty_metadata_bytes); percpu_counter_destroy(&fs_info->delalloc_bytes); percpu_counter_destroy(&fs_info->ordered_bytes); @@ -2231,7 +2232,7 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info) fs_info->discard_ctl.discard_workers)) { return -ENOMEM; } - + btrfs_apply_workqueue_cpu_set(fs_info); return 0; } diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h index cbad856df197ccfd..a8bd1414b2520ea4 100644 --- a/fs/btrfs/fs.h +++ b/fs/btrfs/fs.h @@ -177,6 +177,7 @@ enum { BTRFS_MOUNT_IGNOREBADROOTS = (1UL << 29), BTRFS_MOUNT_IGNOREDATACSUMS = (1UL << 30), BTRFS_MOUNT_NODISCARD = (1UL << 31), + BTRFS_MOUNT_WQ_CPU_SET = (1ULL << 32), }; /* @@ -807,6 +808,8 @@ struct btrfs_fs_info { spinlock_t eb_leak_lock; struct list_head allocated_ebs; #endif + + struct btrfs_cpu_set *wq_cpu_set; }; static inline void btrfs_set_last_root_drop_gen(struct btrfs_fs_info *fs_info, diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 581845bc206ad28b..3e061ec977b014d1 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -139,6 +139,7 @@ enum { #ifdef CONFIG_BTRFS_FS_REF_VERIFY Opt_ref_verify, #endif + Opt_wq_cpu_set, Opt_err, }; @@ -213,6 +214,7 @@ static const match_table_t tokens = { #ifdef CONFIG_BTRFS_FS_REF_VERIFY {Opt_ref_verify, "ref_verify"}, #endif + {Opt_wq_cpu_set, "wq_cpu_set=%s"}, {Opt_err, NULL}, }; @@ -298,6 +300,23 @@ static int parse_rescue_options(struct btrfs_fs_info *info, const char *options) return ret; } +static int parse_wq_cpu_set(struct btrfs_fs_info *info, const char *mask_str) +{ + struct btrfs_cpu_set *cpu_set; + int ret; + + ret = btrfs_parse_cpu_set(&cpu_set, mask_str); + if (ret) { + btrfs_err(info, "failed to parse wq_cpu_set: %d", ret); + return ret; + } + + info->wq_cpu_set = cpu_set; + btrfs_info(info, "using wq_cpu_set=%s", mask_str); + btrfs_set_opt(info->mount_opt, WQ_CPU_SET); + return 0; +} + /* * Regular mount options parser. Everything that is needed only when * reading in a new superblock is parsed here. @@ -803,6 +822,11 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, btrfs_set_opt(info->mount_opt, REF_VERIFY); break; #endif + case Opt_wq_cpu_set: + ret = parse_wq_cpu_set(info, args[0].from); + if (ret < 0) + goto out; + break; case Opt_err: btrfs_err(info, "unrecognized mount option '%s'", p); ret = -EINVAL; @@ -1319,6 +1343,8 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) #endif if (btrfs_test_opt(info, REF_VERIFY)) seq_puts(seq, ",ref_verify"); + if (btrfs_test_opt(info, WQ_CPU_SET)) + seq_printf(seq, ",wq_cpu_set=%s", info->wq_cpu_set->mask_str); seq_printf(seq, ",subvolid=%llu", BTRFS_I(d_inode(dentry))->root->root_key.objectid); subvol_name = btrfs_get_subvol_name_from_objectid(info, @@ -1686,6 +1712,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) u64 old_max_inline = fs_info->max_inline; u32 old_thread_pool_size = fs_info->thread_pool_size; u32 old_metadata_ratio = fs_info->metadata_ratio; + struct btrfs_cpu_set *old_wq_cpu_set = fs_info->wq_cpu_set; int ret; sync_filesystem(sb); @@ -1838,6 +1865,14 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) set_bit(BTRFS_FS_OPEN, &fs_info->flags); } out: + /* + * The remount operation changes the wq_cpu_set. + */ + if (fs_info->wq_cpu_set != old_wq_cpu_set) { + btrfs_destroy_cpu_set(old_wq_cpu_set); + btrfs_apply_workqueue_cpu_set(fs_info); + } + /* * We need to set SB_I_VERSION here otherwise it'll get cleared by VFS, * since the absence of the flag means it can be toggled off by remount. @@ -1852,6 +1887,15 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) return 0; restore: + /* + * The remount operation changes the wq_cpu_set, but we hit an error, + * destroy the new value and roll it back to the previous value. + */ + if (fs_info->wq_cpu_set != old_wq_cpu_set) { + btrfs_destroy_cpu_set(fs_info->wq_cpu_set); + fs_info->wq_cpu_set = old_wq_cpu_set; + } + /* We've hit an error - don't reset SB_RDONLY */ if (sb_rdonly(sb)) old_flags |= SB_RDONLY; From patchwork Sun Feb 26 16:02:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ammar Faizi X-Patchwork-Id: 13152447 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C2168C6FA8E for ; Sun, 26 Feb 2023 16:04:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229801AbjBZQEK (ORCPT ); Sun, 26 Feb 2023 11:04:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54288 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229805AbjBZQD6 (ORCPT ); Sun, 26 Feb 2023 11:03:58 -0500 Received: from gnuweeb.org (gnuweeb.org [51.81.211.47]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 809E711177; Sun, 26 Feb 2023 08:03:44 -0800 (PST) Received: from localhost.localdomain (unknown [182.253.183.169]) by gnuweeb.org (Postfix) with ESMTPSA id C24538319D; Sun, 26 Feb 2023 16:03:39 +0000 (UTC) X-GW-Data: lPqxHiMPbJw1wb7CM9QUryAGzr0yq5atzVDdxTR0iA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=default; t=1677427424; bh=KGQkSC7uN8P5ShfcF5vnepkW95hzs86cm3yNydWOBj0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R6ld5PCKPWRl5RjCDcp2FJNpbcCCdOpbeexDCsQiRlWg9Dd559yFtlz35Be8FE+y9 Ypk19EReL1hhTwCICrxgwI/tb65rCwZRbbvZ3kpfE4Bs2MzJ/21JvzsHZerdvDHHG0 kdf1UL5KB9keGFhzVmGysuqNYF7VlreryhX6+J9ufrsn3/XlTqx8lf+3xKY8eTAUaN wQqk1nHXxNh3ja8g+EBUQJUsTqsfxpyocDQ/MahtwK1cpRoI54uBkv+NDxOHgXyGHh uOFw+OXISKSQ3HKIJNzciovBljZ3EE3HlrLqzcoDNMn6Py+ao1s71c2awvHBoWKysi aqej08/W5T5Uw== From: Ammar Faizi To: Chris Mason , Josef Bacik , David Sterba , Tejun Heo Cc: Ammar Faizi , Lai Jiangshan , Filipe Manana , Linux Btrfs Mailing List , Linux Kernel Mailing List , Linux Fsdevel Mailing List , GNU/Weeb Mailing List Subject: [RFC PATCH v1 5/6] btrfs: Adjust the default thread pool size when `wq_cpu_set` option is used Date: Sun, 26 Feb 2023 23:02:58 +0700 Message-Id: <20230226160259.18354-6-ammarfaizi2@gnuweeb.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> References: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org If wq_cpu_set is specified, adjust thread_pool_size to the number of CPUs in the set plus 2 to avoid the case where the number of CPUs in the set is less than the default thread_pool_size + 2, which might cause the thread pool to be starved. The thread_pool=%u mount option overrides this adjusting behavior. Signed-off-by: Ammar Faizi --- fs/btrfs/super.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 3e061ec977b014d1..34b7c5810d34d624 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -317,6 +317,32 @@ static int parse_wq_cpu_set(struct btrfs_fs_info *info, const char *mask_str) return 0; } +static void adjust_default_thread_pool_size(struct btrfs_fs_info *info) +{ + unsigned long old_thread_pool_size; + unsigned long new_thread_pool_size; + unsigned long total_usable_cpu = 0; + unsigned long cpu; + + if (!btrfs_test_opt(info, WQ_CPU_SET)) + return; + + for_each_online_cpu(cpu) { + if (cpumask_test_cpu(cpu, info->wq_cpu_set->mask)) + total_usable_cpu++; + } + + old_thread_pool_size = info->thread_pool_size; + new_thread_pool_size = min_t(unsigned long, total_usable_cpu + 2, 8); + + if (old_thread_pool_size == new_thread_pool_size) + return; + + info->thread_pool_size = new_thread_pool_size; + btrfs_info(info, "adjusting thread_pool_size to %lu due to wq_cpu_set (you can override this with thread_pool=%%u option)", + new_thread_pool_size); +} + /* * Regular mount options parser. Everything that is needed only when * reading in a new superblock is parsed here. @@ -336,6 +362,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, bool saved_compress_force; int no_compress = 0; const bool remounting = test_bit(BTRFS_FS_STATE_REMOUNTING, &info->fs_state); + bool has_thread_pool_opt = false; if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE)) btrfs_set_opt(info->mount_opt, FREE_SPACE_TREE); @@ -543,6 +570,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, goto out; } info->thread_pool_size = intarg; + has_thread_pool_opt = true; break; case Opt_max_inline: num = match_strdup(&args[0]); @@ -854,6 +882,16 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, } if (!ret) ret = btrfs_check_mountopts_zoned(info); + + /* + * If wq_cpu_set is specified, adjust thread_pool_size to the number of + * CPUs in the set plus 2 to avoid the case where the number of CPUs in + * the set is less than the default thread_pool_size + 2, which might + * cause the thread pool to be starved. The thread_pool=%u mount option + * overrides this adjusting behavior. + */ + if (!ret && !has_thread_pool_opt) + adjust_default_thread_pool_size(info); if (!ret && !remounting) { if (btrfs_test_opt(info, SPACE_CACHE)) btrfs_info(info, "disk space caching is enabled"); From patchwork Sun Feb 26 16:02:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ammar Faizi X-Patchwork-Id: 13152448 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 67C10C7EE2F for ; Sun, 26 Feb 2023 16:04:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229866AbjBZQEN (ORCPT ); Sun, 26 Feb 2023 11:04:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229813AbjBZQEB (ORCPT ); Sun, 26 Feb 2023 11:04:01 -0500 Received: from gnuweeb.org (gnuweeb.org [51.81.211.47]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C62E2125A7; Sun, 26 Feb 2023 08:03:49 -0800 (PST) Received: from localhost.localdomain (unknown [182.253.183.169]) by gnuweeb.org (Postfix) with ESMTPSA id 08155831B7; Sun, 26 Feb 2023 16:03:44 +0000 (UTC) X-GW-Data: lPqxHiMPbJw1wb7CM9QUryAGzr0yq5atzVDdxTR0iA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=default; t=1677427429; bh=Yo1+jDAmCINsAVjB6QZIr6c2SpALyJNJSdY2CPV6JsI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mgtuJhCTdxodogoH8lRiLcqjlFTtteVvB/jjKwArR69BaLharsOanmHPiZ3ArTXmh QzwuZWzCOGdEo6E+nuEfed+KHxc3/P2CeFWPZ9Ietfu2xSSG2bzOlW5aJ1A5A7XbUw C5mhDR+kI4p9WNy914pLnJL9fwK4rM7HadEa+x/V27VQjYjWcy7m+RDNoz436YZel1 y5r7CMRTvlxLKHjNkHNUCr+vG6eW22W3TLJU54wjg7tCkXWmZoDXVaD4PmT95w/7cD o7xAJ1U2YKYS0CHOCe+JK9uvIAg3zTZtWAxNKTH1e3klc2wNK7faplAATa14fJly8p oGq+GVZUXmNKw== From: Ammar Faizi To: Chris Mason , Josef Bacik , David Sterba , Tejun Heo Cc: Ammar Faizi , Lai Jiangshan , Filipe Manana , Linux Btrfs Mailing List , Linux Kernel Mailing List , Linux Fsdevel Mailing List , GNU/Weeb Mailing List Subject: [RFC PATCH v1 6/6] btrfs: Add `BTRFS_DEFAULT_MAX_THREAD_POOL_SIZE` macro Date: Sun, 26 Feb 2023 23:02:59 +0700 Message-Id: <20230226160259.18354-7-ammarfaizi2@gnuweeb.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> References: <20230226160259.18354-1-ammarfaizi2@gnuweeb.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Currently, the default max thread pool size is hardcoded as 8. This number is not only used in one place. Keep the default max thread pool size in sync by introducing a new macro. Signed-off-by: Ammar Faizi --- fs/btrfs/async-thread.h | 2 ++ fs/btrfs/disk-io.c | 3 ++- fs/btrfs/super.c | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/async-thread.h b/fs/btrfs/async-thread.h index 2b8a76fa75ef9e69..f11c3b36568053be 100644 --- a/fs/btrfs/async-thread.h +++ b/fs/btrfs/async-thread.h @@ -9,6 +9,8 @@ #include +#define BTRFS_DEFAULT_MAX_THREAD_POOL_SIZE 8 + struct btrfs_fs_info; struct btrfs_workqueue; struct btrfs_work; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 1bb1db461a30fa71..4f4ddc8e088b08ec 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2957,7 +2957,8 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info) btrfs_init_ref_verify(fs_info); fs_info->thread_pool_size = min_t(unsigned long, - num_online_cpus() + 2, 8); + num_online_cpus() + 2, + BTRFS_DEFAULT_MAX_THREAD_POOL_SIZE); INIT_LIST_HEAD(&fs_info->ordered_roots); spin_lock_init(&fs_info->ordered_root_lock); diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 34b7c5810d34d624..bf4be383e289ef6c 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -333,7 +333,8 @@ static void adjust_default_thread_pool_size(struct btrfs_fs_info *info) } old_thread_pool_size = info->thread_pool_size; - new_thread_pool_size = min_t(unsigned long, total_usable_cpu + 2, 8); + new_thread_pool_size = min_t(unsigned long, total_usable_cpu + 2, + BTRFS_DEFAULT_MAX_THREAD_POOL_SIZE); if (old_thread_pool_size == new_thread_pool_size) return;