* Re: [PATCH v25 0/7] firmware: imx: driver for NXP secure-enclave
From: Frieder Schrempf @ 2026-04-21 7:52 UTC (permalink / raw)
To: Pankaj Gupta, Jonathan Corbet, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam
Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org, Frank Li
In-Reply-To: <6543cf20-01e3-4dc2-b4b0-08935527f440@kontron.de>
On 24.02.26 12:18, Frieder Schrempf wrote:
> On 29.01.26 17:58, Pankaj Gupta wrote:
>> Hi Shawn,
>>
>> This is a gentle follow‑up regarding the patch-set.
>>
>> In v25, I addressed all automated feedback from kernel CI (warning fixes and checkpatch‑strict resolution), with no further changes requested by reviewers.
>> Patch 5/7 has also received a Reviewed-by tag from Frank Li (NXP).
>>
>> I have not seen additional feedback.
>> I would appreciate any update on the review/merge status, or guidance on further changes needed to move the series forward.
>>
>> Thanks for your time and continued support.
>
> How close are we to getting this patchset merged? Work on this has been
> ongoing for almost three years now and it would be really helpful to
> have this in the kernel.
>
> Thanks!
Gentle ping! Can someone please provide information on what needs to be
done to get this merged?
Thanks!
^ permalink raw reply
* Re: [PATCH] docs/mm: clarify that we are not looking for LLM generated content
From: Lorenzo Stoakes @ 2026-04-21 7:38 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: linux-doc, Andrew Morton, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Jonathan Corbet,
Shuah Khan, Matthew Wilcox, Harry Yoo, linux-mm, linux-kernel
In-Reply-To: <20260420-llmdoc-v1-1-47d2091177c4@kernel.org>
On Mon, Apr 20, 2026 at 11:03:16PM +0200, David Hildenbrand (Arm) wrote:
> Let's make it clear that we are not looking for LLM generated content
> from contributors not familiar with the details of MM, as it shifts the
> real work onto reviewers.
>
> Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
LGTM to me, I think it's important we clear this up. So:
Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
> ---
> Documentation/mm/index.rst | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/Documentation/mm/index.rst b/Documentation/mm/index.rst
> index 7aa2a8886908..13a79f5d092c 100644
> --- a/Documentation/mm/index.rst
> +++ b/Documentation/mm/index.rst
> @@ -7,6 +7,19 @@ of Linux. If you are looking for advice on simply allocating memory,
> see the :ref:`memory_allocation`. For controlling and tuning guides,
> see the :doc:`admin guide <../admin-guide/mm/index>`.
>
> +.. note::
> +
> + Unfortunately, parts of this guide are still incomplete or missing.
> + While we appreciate contributions, documentation in this area is hard
> + to get right and requires a lot of attention to detail. New contributors
> + should reach out to the relevant maintainers early.
> +
> + This guide is expected to reflect reality, which requires contributors
> + to have a detailed understanding. Documentation generated with LLMs
> + by contributors unfamiliar with these details shifts the real work onto
> + reviewers, which is why such contributions will be rejected without
> + further comment.
> +
> .. toctree::
> :maxdepth: 1
>
>
> ---
> base-commit: da6b5aae84beb0917ecb0c9fbc71169d145397ff
> change-id: 20260420-llmdoc-21bf5fadbd6f
>
> Best regards,
> --
> David Hildenbrand (Arm) <david@kernel.org>
>
^ permalink raw reply
* Re: [PATCH V10 00/10] famfs: port into fuse
From: Christian Brauner @ 2026-04-21 6:59 UTC (permalink / raw)
To: Joanne Koong
Cc: Christoph Hellwig, Miklos Szeredi, John Groves, Bernd Schubert,
John Groves, Dan Williams, Bernd Schubert, Alison Schofield,
John Groves, Jonathan Corbet, Shuah Khan, Vishal Verma,
Dave Jiang, Matthew Wilcox, Jan Kara, Alexander Viro,
David Hildenbrand, Darrick J . Wong, Randy Dunlap, Jeff Layton,
Amir Goldstein, Jonathan Cameron, Stefan Hajnoczi, Josef Bacik,
Bagas Sanjaya, Chen Linxuan, James Morse, Fuad Tabba,
Sean Christopherson, Shivank Garg, Ackerley Tng, Gregory Price,
Aravind Ramesh, Ajay Joshi, venkataravis@micron.com,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
nvdimm@lists.linux.dev, linux-cxl@vger.kernel.org,
linux-fsdevel@vger.kernel.org, djbw
In-Reply-To: <CAJnrk1a7idWN4UNpW0P-X4xeBKOkhnR+Mvfo3QW38OfShiwpKw@mail.gmail.com>
On Fri, Apr 17, 2026 at 12:35:13PM -0700, Joanne Koong wrote:
> On Fri, Apr 17, 2026 at 1:04 AM Christoph Hellwig <hch@infradead.org> wrote:
> >
> > This is the first mail without annoying and pointless full quotes,
> > so chiming in here. Sorry if I missed something important in all the
> > noise.
> >
> > On Tue, Apr 14, 2026 at 03:19:36PM +0200, Miklos Szeredi wrote:
> > > On Fri, 10 Apr 2026 at 21:44, Joanne Koong <joannelkoong@gmail.com> wrote:
> > >
> > > > Overall, my intention with bringing this up is just to make sure we're
> > > > at least aware of this alternative before anything is merged and
> > > > permanent. If Miklos and you think we should land this series, then
> > > > I'm on board with that.
> > >
> > > TBH, I'd prefer not to add the famfs specific mapping interface if not
> > > absolutely necessary.
> >
> > Yes, fuse needing support for a specific file systems sounds like a
> > design mistake.
> >
> > >This was the main sticking point originally,
> > > but there seemed to be no better alternative.
> > >
> > > However with the bpf approach this would be gone, which is great.
> >
> > So what is this bpf magic actually trying to solve?
>
> It is trying to avoid having famfs-specific implementation details
> hardcoded permanently into fuse's uapi and kernel code. I really like
> your suggestion of adding generic stride/offset multi-device support
> to fs/iomap. That is a much better solution than bpf.
If you go down the bpf route you will just have to use bpf hashmaps to
associate the blobs that you need with the relevant data structure and
then activate it from whatever hook you need. There's now very flexible
hashmap storage that you can autoresize - or you can use bpf arenas.
There's a ton of options that don't require modifying core structures.
IOW, I don't want dedicated bpf storage in struct inode. Not just
because bpf people consider dedicated blob storage in kernel structures
obsolete and recommend to use hashmaps - which is e.g., what I use for
another project of mine where I associate metadata with block devices -
but also because I very much disagree with bloating generic infra.
^ permalink raw reply
* Re: [PATCH] docs/mm: clarify that we are not looking for LLM generated content
From: Mike Rapoport @ 2026-04-21 6:45 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: linux-doc, Andrew Morton, Lorenzo Stoakes, Liam R. Howlett,
Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
Jonathan Corbet, Shuah Khan, Matthew Wilcox, Harry Yoo, linux-mm,
linux-kernel
In-Reply-To: <20260420-llmdoc-v1-1-47d2091177c4@kernel.org>
On Mon, Apr 20, 2026 at 11:03:16PM +0200, David Hildenbrand (Arm) wrote:
> Let's make it clear that we are not looking for LLM generated content
> from contributors not familiar with the details of MM, as it shifts the
> real work onto reviewers.
>
> Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
> ---
> Documentation/mm/index.rst | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/Documentation/mm/index.rst b/Documentation/mm/index.rst
> index 7aa2a8886908..13a79f5d092c 100644
> --- a/Documentation/mm/index.rst
> +++ b/Documentation/mm/index.rst
> @@ -7,6 +7,19 @@ of Linux. If you are looking for advice on simply allocating memory,
> see the :ref:`memory_allocation`. For controlling and tuning guides,
> see the :doc:`admin guide <../admin-guide/mm/index>`.
>
> +.. note::
> +
> + Unfortunately, parts of this guide are still incomplete or missing.
> + While we appreciate contributions, documentation in this area is hard
> + to get right and requires a lot of attention to detail. New contributors
> + should reach out to the relevant maintainers early.
> +
> + This guide is expected to reflect reality, which requires contributors
> + to have a detailed understanding. Documentation generated with LLMs
> + by contributors unfamiliar with these details shifts the real work onto
> + reviewers, which is why such contributions will be rejected without
> + further comment.
> +
> .. toctree::
> :maxdepth: 1
>
>
> ---
> base-commit: da6b5aae84beb0917ecb0c9fbc71169d145397ff
> change-id: 20260420-llmdoc-21bf5fadbd6f
>
> Best regards,
> --
> David Hildenbrand (Arm) <david@kernel.org>
>
--
Sincerely yours,
Mike.
^ permalink raw reply
* Re: [PATCH v2 1/2] kernel: param: handle NULL module_kset in lookup_or_create_module_kobject()
From: Greg Kroah-Hartman @ 2026-04-21 6:27 UTC (permalink / raw)
To: Shashank Balaji
Cc: Kay Sievers, Rafael J. Wysocki, Danilo Krummrich,
Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Maxime Coquelin, Alexandre Torgue, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Richard Cochran, Jonathan Corbet,
Shuah Khan, Rahul Bukte, Daniel Palmer, Tim Bird, linux-kernel,
driver-core, coresight, linux-arm-kernel, rust-for-linux,
linux-doc
In-Reply-To: <20260421-acpi_mod_name-v2-1-e73f9310dad3@sony.com>
On Tue, Apr 21, 2026 at 03:02:34PM +0900, Shashank Balaji wrote:
> module_kset is initialized in a subsys_initcall. If a built-in driver tries to
> register before subsys_initcall with its struct device_driver's mod_name set,
> then a null module_kset is dereferenced via this call trace:
>
> [ 0.095865] Call trace:
> [ 0.095999] _raw_spin_lock+0x4c/0x6c (P)
> [ 0.096150] kset_find_obj+0x24/0x104
> [ 0.096209] lookup_or_create_module_kobject+0x2c/0xd8
> [ 0.096274] module_add_driver+0xd4/0x138
> [ 0.096328] bus_add_driver+0x16c/0x268
> [ 0.096380] driver_register+0x68/0x100
> [ 0.096428] __platform_driver_register+0x24/0x30
> [ 0.096486] tegra194_cbb_init+0x24/0x30
> [ 0.096540] do_one_initcall+0xdc/0x250
> [ 0.096608] do_initcall_level+0x9c/0xd0
> [ 0.096660] do_initcalls+0x54/0x94
> [ 0.096706] do_basic_setup+0x20/0x2c
> [ 0.096753] kernel_init_freeable+0xc8/0x154
> [ 0.096807] kernel_init+0x20/0x1a0
> [ 0.096851] ret_from_fork+0x10/0x20
>
> So, return null in lookup_or_create_module_kobject() if module_kset is null.
> Existing callers handle null already.
>
> Fixes: f30c53a873d0 ("MODULES: add the module name for built in kernel drivers")
This isn't a bugfix.
> Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
> ---
> This bug is triggered by the next patch on arm64 defconfig: tegra194-cbb tries
> to register from a pure_initcall, and with the next patch adding mod_name, this
> null deref is hit.
So this isn't a bug, it's a "don't do that" type of thing :)
> ---
> kernel/params.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/kernel/params.c b/kernel/params.c
> index 74d620bc2521..881c7328c059 100644
> --- a/kernel/params.c
> +++ b/kernel/params.c
> @@ -752,6 +752,9 @@ lookup_or_create_module_kobject(const char *name)
> struct kobject *kobj;
> int err;
>
> + if (!module_kset)
> + return NULL;
Are you sure that making this change is going to be ok?
mod_sysfs_init() should have been called first as the module has to be
created before it can be looked up.
As you are wanting "built in" drivers to show up here, you are going to
beat the call to param_sysfs_init(), so don't do that. Make sure that
the drivers are NOT called before then.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v2 2/2] driver core: platform: set mod_name in driver registration
From: Greg Kroah-Hartman @ 2026-04-21 6:24 UTC (permalink / raw)
To: Shashank Balaji
Cc: Kay Sievers, Rafael J. Wysocki, Danilo Krummrich,
Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Maxime Coquelin, Alexandre Torgue, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Richard Cochran, Jonathan Corbet,
Shuah Khan, Rahul Bukte, Daniel Palmer, Tim Bird, linux-kernel,
driver-core, coresight, linux-arm-kernel, rust-for-linux,
linux-doc
In-Reply-To: <20260421-acpi_mod_name-v2-2-e73f9310dad3@sony.com>
On Tue, Apr 21, 2026 at 03:02:35PM +0900, Shashank Balaji wrote:
> Pass KBUILD_MODNAME through the driver registration macro so that
> the driver core can create the module symlink in sysfs for built-in
> drivers, and fixup all callers.
>
> The Rust platform adapter is updated to pass the module name through to the new
> parameter.
>
> Tested on qemu with:
> - x86 defconfig + CONFIG_RUST
> - arm64 defconfig + CONFIG_RUST + CONFIG_CORESIGHT
>
> Examples after this patch:
>
> /sys/bus/platform/drivers/...
> coresight-itnoc/module -> coresight_tnoc
> coresight-static-tpdm/module -> coresight_tpdm
> coresight-catu-platform/module -> coresight_catu
> serial8250/module -> 8250
> acpi-ged/module -> acpi
> vmclock/module -> ptp_vmclock
>
> Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
> ---
> Depends on the previous patch, without which the kernel fails to boot on arm64
> defconfig.
> ---
> Documentation/driver-api/driver-model/platform.rst | 3 ++-
> drivers/base/platform.c | 21 ++++++++++++++-------
> drivers/hwtracing/coresight/coresight-catu.c | 3 ++-
> drivers/hwtracing/coresight/coresight-core.c | 5 +++--
> drivers/hwtracing/coresight/coresight-cpu-debug.c | 2 +-
> drivers/hwtracing/coresight/coresight-funnel.c | 2 +-
> drivers/hwtracing/coresight/coresight-replicator.c | 2 +-
> drivers/hwtracing/coresight/coresight-stm.c | 3 ++-
> drivers/hwtracing/coresight/coresight-tmc-core.c | 3 ++-
> drivers/hwtracing/coresight/coresight-tnoc.c | 3 ++-
> drivers/hwtracing/coresight/coresight-tpdm.c | 2 +-
> drivers/hwtracing/coresight/coresight-tpiu.c | 3 ++-
> include/linux/coresight.h | 3 ++-
> include/linux/platform_device.h | 17 +++++++++--------
> rust/kernel/platform.rs | 4 +++-
> 15 files changed, 47 insertions(+), 29 deletions(-)
That's a lot of different things all in one change, please break this up
into smaller bits, this is not going to work.
Especially as the coresight changes are incorrect, no individual module
should EVER have to list THIS_MODULE or KBUILD_MODNAME in a function, it
should happen automatically by the compiler using a helper #define, like
is done for other busses.
Please fix that up first, then you can worry about the other ones.
thanks,
greg k-h
^ permalink raw reply
* [PATCH v2 2/2] driver core: platform: set mod_name in driver registration
From: Shashank Balaji @ 2026-04-21 6:02 UTC (permalink / raw)
To: Kay Sievers, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Richard Cochran, Jonathan Corbet, Shuah Khan
Cc: Shashank Balaji, Rahul Bukte, Daniel Palmer, Tim Bird,
linux-kernel, driver-core, coresight, linux-arm-kernel,
rust-for-linux, linux-doc
In-Reply-To: <20260421-acpi_mod_name-v2-0-e73f9310dad3@sony.com>
Pass KBUILD_MODNAME through the driver registration macro so that
the driver core can create the module symlink in sysfs for built-in
drivers, and fixup all callers.
The Rust platform adapter is updated to pass the module name through to the new
parameter.
Tested on qemu with:
- x86 defconfig + CONFIG_RUST
- arm64 defconfig + CONFIG_RUST + CONFIG_CORESIGHT
Examples after this patch:
/sys/bus/platform/drivers/...
coresight-itnoc/module -> coresight_tnoc
coresight-static-tpdm/module -> coresight_tpdm
coresight-catu-platform/module -> coresight_catu
serial8250/module -> 8250
acpi-ged/module -> acpi
vmclock/module -> ptp_vmclock
Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
---
Depends on the previous patch, without which the kernel fails to boot on arm64
defconfig.
---
Documentation/driver-api/driver-model/platform.rst | 3 ++-
drivers/base/platform.c | 21 ++++++++++++++-------
drivers/hwtracing/coresight/coresight-catu.c | 3 ++-
drivers/hwtracing/coresight/coresight-core.c | 5 +++--
drivers/hwtracing/coresight/coresight-cpu-debug.c | 2 +-
drivers/hwtracing/coresight/coresight-funnel.c | 2 +-
drivers/hwtracing/coresight/coresight-replicator.c | 2 +-
drivers/hwtracing/coresight/coresight-stm.c | 3 ++-
drivers/hwtracing/coresight/coresight-tmc-core.c | 3 ++-
drivers/hwtracing/coresight/coresight-tnoc.c | 3 ++-
drivers/hwtracing/coresight/coresight-tpdm.c | 2 +-
drivers/hwtracing/coresight/coresight-tpiu.c | 3 ++-
include/linux/coresight.h | 3 ++-
include/linux/platform_device.h | 17 +++++++++--------
rust/kernel/platform.rs | 4 +++-
15 files changed, 47 insertions(+), 29 deletions(-)
diff --git a/Documentation/driver-api/driver-model/platform.rst b/Documentation/driver-api/driver-model/platform.rst
index cf5ff48d3115..9673470bded2 100644
--- a/Documentation/driver-api/driver-model/platform.rst
+++ b/Documentation/driver-api/driver-model/platform.rst
@@ -70,7 +70,8 @@ Kernel modules can be composed of several platform drivers. The platform core
provides helpers to register and unregister an array of drivers::
int __platform_register_drivers(struct platform_driver * const *drivers,
- unsigned int count, struct module *owner);
+ unsigned int count, struct module *owner,
+ const char *mod_name);
void platform_unregister_drivers(struct platform_driver * const *drivers,
unsigned int count);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 75b4698d0e58..2b0cc0889386 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -901,11 +901,14 @@ EXPORT_SYMBOL_GPL(platform_device_register_full);
* __platform_driver_register - register a driver for platform-level devices
* @drv: platform driver structure
* @owner: owning module/driver
+ * @mod_name: module name string
*/
-int __platform_driver_register(struct platform_driver *drv, struct module *owner)
+int __platform_driver_register(struct platform_driver *drv, struct module *owner,
+ const char *mod_name)
{
drv->driver.owner = owner;
drv->driver.bus = &platform_bus_type;
+ drv->driver.mod_name = mod_name;
return driver_register(&drv->driver);
}
@@ -938,6 +941,7 @@ static int is_bound_to_driver(struct device *dev, void *driver)
* @drv: platform driver structure
* @probe: the driver probe routine, probably from an __init section
* @module: module which will be the owner of the driver
+ * @mod_name: module name string
*
* Use this instead of platform_driver_register() when you know the device
* is not hotpluggable and has already been registered, and you want to
@@ -955,7 +959,8 @@ static int is_bound_to_driver(struct device *dev, void *driver)
*/
int __init_or_module __platform_driver_probe(struct platform_driver *drv,
int (*probe)(struct platform_device *),
- struct module *module)
+ struct module *module,
+ const char *mod_name)
{
int retval;
@@ -983,7 +988,7 @@ int __init_or_module __platform_driver_probe(struct platform_driver *drv,
/* temporary section violation during probe() */
drv->probe = probe;
- retval = __platform_driver_register(drv, module);
+ retval = __platform_driver_register(drv, module, mod_name);
if (retval)
return retval;
@@ -1011,6 +1016,7 @@ EXPORT_SYMBOL_GPL(__platform_driver_probe);
* @data: platform specific data for this platform device
* @size: size of platform specific data
* @module: module which will be the owner of the driver
+ * @mod_name: module name string
*
* Use this in legacy-style modules that probe hardware directly and
* register a single platform device and corresponding platform driver.
@@ -1021,7 +1027,7 @@ struct platform_device * __init_or_module
__platform_create_bundle(struct platform_driver *driver,
int (*probe)(struct platform_device *),
struct resource *res, unsigned int n_res,
- const void *data, size_t size, struct module *module)
+ const void *data, size_t size, struct module *module, const char *mod_name)
{
struct platform_device *pdev;
int error;
@@ -1044,7 +1050,7 @@ __platform_create_bundle(struct platform_driver *driver,
if (error)
goto err_pdev_put;
- error = __platform_driver_probe(driver, probe, module);
+ error = __platform_driver_probe(driver, probe, module, mod_name);
if (error)
goto err_pdev_del;
@@ -1064,6 +1070,7 @@ EXPORT_SYMBOL_GPL(__platform_create_bundle);
* @drivers: an array of drivers to register
* @count: the number of drivers to register
* @owner: module owning the drivers
+ * @mod_name: module name string
*
* Registers platform drivers specified by an array. On failure to register a
* driver, all previously registered drivers will be unregistered. Callers of
@@ -1073,7 +1080,7 @@ EXPORT_SYMBOL_GPL(__platform_create_bundle);
* Returns: 0 on success or a negative error code on failure.
*/
int __platform_register_drivers(struct platform_driver * const *drivers,
- unsigned int count, struct module *owner)
+ unsigned int count, struct module *owner, const char *mod_name)
{
unsigned int i;
int err;
@@ -1081,7 +1088,7 @@ int __platform_register_drivers(struct platform_driver * const *drivers,
for (i = 0; i < count; i++) {
pr_debug("registering platform driver %ps\n", drivers[i]);
- err = __platform_driver_register(drivers[i], owner);
+ err = __platform_driver_register(drivers[i], owner, mod_name);
if (err < 0) {
pr_err("failed to register platform driver %ps: %d\n",
drivers[i], err);
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index dfd035852b12..3e4df832f02a 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -708,7 +708,8 @@ static int __init catu_init(void)
{
int ret;
- ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver, THIS_MODULE);
+ ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver,
+ THIS_MODULE, KBUILD_MODNAME);
tmc_etr_set_catu_ops(&etr_catu_buf_ops);
return ret;
}
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 80e26396ad0a..b88bc053ab58 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1645,7 +1645,8 @@ module_init(coresight_init);
module_exit(coresight_exit);
int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
- struct platform_driver *pdev_drv, struct module *owner)
+ struct platform_driver *pdev_drv, struct module *owner,
+ const char *mod_name)
{
int ret;
@@ -1655,7 +1656,7 @@ int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
return ret;
}
- ret = __platform_driver_register(pdev_drv, owner);
+ ret = __platform_driver_register(pdev_drv, owner, mod_name);
if (!ret)
return 0;
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 629614278e46..00b7c52d3ab9 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -758,7 +758,7 @@ static struct platform_driver debug_platform_driver = {
static int __init debug_init(void)
{
return coresight_init_driver("debug", &debug_driver, &debug_platform_driver,
- THIS_MODULE);
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit debug_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 3b248e54471a..8ee5b42bb475 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -415,7 +415,7 @@ static struct amba_driver dynamic_funnel_driver = {
static int __init funnel_init(void)
{
return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver,
- THIS_MODULE);
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit funnel_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index e6472658235d..9af67100f1fd 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -421,7 +421,7 @@ static struct amba_driver dynamic_replicator_driver = {
static int __init replicator_init(void)
{
return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver,
- THIS_MODULE);
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit replicator_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index e68529bf89c9..b140069e07b5 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -1052,7 +1052,8 @@ static struct platform_driver stm_platform_driver = {
static int __init stm_init(void)
{
- return coresight_init_driver("stm", &stm_driver, &stm_platform_driver, THIS_MODULE);
+ return coresight_init_driver("stm", &stm_driver, &stm_platform_driver,
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit stm_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 36599c431be6..bef0a9d1fa1b 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -1051,7 +1051,8 @@ static struct platform_driver tmc_platform_driver = {
static int __init tmc_init(void)
{
- return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver, THIS_MODULE);
+ return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver,
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit tmc_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tnoc.c b/drivers/hwtracing/coresight/coresight-tnoc.c
index 1128612e70a7..1c7c7a062600 100644
--- a/drivers/hwtracing/coresight/coresight-tnoc.c
+++ b/drivers/hwtracing/coresight/coresight-tnoc.c
@@ -346,7 +346,8 @@ static struct platform_driver itnoc_driver = {
static int __init tnoc_init(void)
{
- return coresight_init_driver("tnoc", &trace_noc_driver, &itnoc_driver, THIS_MODULE);
+ return coresight_init_driver("tnoc", &trace_noc_driver, &itnoc_driver,
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit tnoc_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 06e0a905a67d..2a735f797c8e 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -1534,7 +1534,7 @@ static struct platform_driver static_tpdm_driver = {
static int __init tpdm_init(void)
{
return coresight_init_driver("tpdm", &dynamic_tpdm_driver, &static_tpdm_driver,
- THIS_MODULE);
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit tpdm_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index aaa44bc521c3..3ddabb81b946 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -312,7 +312,8 @@ static struct platform_driver tpiu_platform_driver = {
static int __init tpiu_init(void)
{
- return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver, THIS_MODULE);
+ return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver,
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit tpiu_exit(void)
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 2b48be97fcd0..382341f587d0 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -698,7 +698,8 @@ coresight_find_output_type(struct coresight_platform_data *pdata,
union coresight_dev_subtype subtype);
int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
- struct platform_driver *pdev_drv, struct module *owner);
+ struct platform_driver *pdev_drv, struct module *owner,
+ const char *mod_name);
void coresight_remove_driver(struct amba_driver *amba_drv,
struct platform_driver *pdev_drv);
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 975400a472e3..26e6a43358e2 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -293,18 +293,19 @@ struct platform_driver {
* use a macro to avoid include chaining to get THIS_MODULE
*/
#define platform_driver_register(drv) \
- __platform_driver_register(drv, THIS_MODULE)
+ __platform_driver_register(drv, THIS_MODULE, KBUILD_MODNAME)
extern int __platform_driver_register(struct platform_driver *,
- struct module *);
+ struct module *, const char *mod_name);
extern void platform_driver_unregister(struct platform_driver *);
/* non-hotpluggable platform devices may use this so that probe() and
* its support may live in __init sections, conserving runtime memory.
*/
#define platform_driver_probe(drv, probe) \
- __platform_driver_probe(drv, probe, THIS_MODULE)
+ __platform_driver_probe(drv, probe, THIS_MODULE, KBUILD_MODNAME)
extern int __platform_driver_probe(struct platform_driver *driver,
- int (*probe)(struct platform_device *), struct module *module);
+ int (*probe)(struct platform_device *), struct module *module,
+ const char *mod_name);
static inline void *platform_get_drvdata(const struct platform_device *pdev)
{
@@ -368,19 +369,19 @@ static int __init __platform_driver##_init(void) \
device_initcall(__platform_driver##_init); \
#define platform_create_bundle(driver, probe, res, n_res, data, size) \
- __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE)
+ __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE, KBUILD_MODNAME)
extern struct platform_device *__platform_create_bundle(
struct platform_driver *driver, int (*probe)(struct platform_device *),
struct resource *res, unsigned int n_res,
- const void *data, size_t size, struct module *module);
+ const void *data, size_t size, struct module *module, const char *mod_name);
int __platform_register_drivers(struct platform_driver * const *drivers,
- unsigned int count, struct module *owner);
+ unsigned int count, struct module *owner, const char *mod_name);
void platform_unregister_drivers(struct platform_driver * const *drivers,
unsigned int count);
#define platform_register_drivers(drivers, count) \
- __platform_register_drivers(drivers, count, THIS_MODULE)
+ __platform_register_drivers(drivers, count, THIS_MODULE, KBUILD_MODNAME)
#ifdef CONFIG_SUSPEND
extern int platform_pm_suspend(struct device *dev);
diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
index 8917d4ee499f..2d626eecc450 100644
--- a/rust/kernel/platform.rs
+++ b/rust/kernel/platform.rs
@@ -82,7 +82,9 @@ unsafe fn register(
}
// SAFETY: `pdrv` is guaranteed to be a valid `DriverType`.
- to_result(unsafe { bindings::__platform_driver_register(pdrv.get(), module.0) })
+ to_result(unsafe {
+ bindings::__platform_driver_register(pdrv.get(), module.0, name.as_char_ptr())
+ })
}
unsafe fn unregister(pdrv: &Opaque<Self::DriverType>) {
--
2.43.0
^ permalink raw reply related
* [PATCH v2 1/2] kernel: param: handle NULL module_kset in lookup_or_create_module_kobject()
From: Shashank Balaji @ 2026-04-21 6:02 UTC (permalink / raw)
To: Kay Sievers, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Richard Cochran, Jonathan Corbet, Shuah Khan
Cc: Shashank Balaji, Rahul Bukte, Daniel Palmer, Tim Bird,
linux-kernel, driver-core, coresight, linux-arm-kernel,
rust-for-linux, linux-doc
In-Reply-To: <20260421-acpi_mod_name-v2-0-e73f9310dad3@sony.com>
module_kset is initialized in a subsys_initcall. If a built-in driver tries to
register before subsys_initcall with its struct device_driver's mod_name set,
then a null module_kset is dereferenced via this call trace:
[ 0.095865] Call trace:
[ 0.095999] _raw_spin_lock+0x4c/0x6c (P)
[ 0.096150] kset_find_obj+0x24/0x104
[ 0.096209] lookup_or_create_module_kobject+0x2c/0xd8
[ 0.096274] module_add_driver+0xd4/0x138
[ 0.096328] bus_add_driver+0x16c/0x268
[ 0.096380] driver_register+0x68/0x100
[ 0.096428] __platform_driver_register+0x24/0x30
[ 0.096486] tegra194_cbb_init+0x24/0x30
[ 0.096540] do_one_initcall+0xdc/0x250
[ 0.096608] do_initcall_level+0x9c/0xd0
[ 0.096660] do_initcalls+0x54/0x94
[ 0.096706] do_basic_setup+0x20/0x2c
[ 0.096753] kernel_init_freeable+0xc8/0x154
[ 0.096807] kernel_init+0x20/0x1a0
[ 0.096851] ret_from_fork+0x10/0x20
So, return null in lookup_or_create_module_kobject() if module_kset is null.
Existing callers handle null already.
Fixes: f30c53a873d0 ("MODULES: add the module name for built in kernel drivers")
Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
---
This bug is triggered by the next patch on arm64 defconfig: tegra194-cbb tries
to register from a pure_initcall, and with the next patch adding mod_name, this
null deref is hit.
---
kernel/params.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/params.c b/kernel/params.c
index 74d620bc2521..881c7328c059 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -752,6 +752,9 @@ lookup_or_create_module_kobject(const char *name)
struct kobject *kobj;
int err;
+ if (!module_kset)
+ return NULL;
+
kobj = kset_find_obj(module_kset, name);
if (kobj)
return to_module_kobject(kobj);
--
2.43.0
^ permalink raw reply related
* [PATCH v2 0/2] Enable sysfs module symlink for more built-in drivers
From: Shashank Balaji @ 2026-04-21 6:02 UTC (permalink / raw)
To: Kay Sievers, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Richard Cochran, Jonathan Corbet, Shuah Khan
Cc: Shashank Balaji, Rahul Bukte, Daniel Palmer, Tim Bird,
linux-kernel, driver-core, coresight, linux-arm-kernel,
rust-for-linux, linux-doc
struct device_driver's mod_name is not set by a number of bus' driver registration
functions. Without that, built-in drivers don't have the module symlink in sysfs.
We want this to go from unbound driver name -> module name -> kernel config name.
This is useful on embedded platforms to minimize kernel config, reduce kernel size,
and reduce boot time.
In order to achieve this, mod_name has to be set to KBUILD_MODNAME, and this has
to be done for all buses which don't yet do this.
Here are some treewide stats:
- 110 registration functions across all bus types
- 20 of them set mod_name
- Remaining 90 do not set mod_name:
1. 36 functions under pattern 1:
They have a __register function + register macro. KBUILD_MODNAME needs to
be passed and the function needs to take mod_name as input.
2. 42 functions under pattern 2:
These have no macro wrapper. They need a double-underscore rename + macro
wrapper to make them similar to pattern 1.
3. Remaining 12 do not have such a clean registration interface. More analysis
is required.
We plan to start with pattern 1, since it's the easiest category of changes.
Within that, for now we're only sending the platform patch. If we get the go-ahead
on that, we'll send the remaining ones.
Patch 2 depends on patch 1, without which arm64 defconfig fails to boot with
patch 2.
Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
---
Changes in v2:
- Drop acpi patch, send platform instead (Rafael)
- Link to v1: https://patch.msgid.link/20260416-acpi_mod_name-v1-0-1a4d96fd86c9@sony.com
To: Kay Sievers <kay.sievers@vrfy.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: "Rafael J. Wysocki" <rafael@kernel.org>
To: Danilo Krummrich <dakr@kernel.org>
To: Suzuki K Poulose <suzuki.poulose@arm.com>
To: Mike Leach <mike.leach@linaro.org>
To: James Clark <james.clark@linaro.org>
To: Alexander Shishkin <alexander.shishkin@linux.intel.com>
To: Maxime Coquelin <mcoquelin.stm32@gmail.com>
To: Alexandre Torgue <alexandre.torgue@foss.st.com>
To: Miguel Ojeda <ojeda@kernel.org>
To: Boqun Feng <boqun@kernel.org>
To: Gary Guo <gary@garyguo.net>
To: Björn Roy Baron <bjorn3_gh@protonmail.com>
To: Benno Lossin <lossin@kernel.org>
To: Andreas Hindborg <a.hindborg@kernel.org>
To: Alice Ryhl <aliceryhl@google.com>
To: Trevor Gross <tmgross@umich.edu>
To: Richard Cochran <richardcochran@gmail.com>
To: Jonathan Corbet <corbet@lwn.net>
To: Shuah Khan <skhan@linuxfoundation.org>
Cc: linux-kernel@vger.kernel.org
Cc: driver-core@lists.linux.dev
Cc: coresight@lists.linaro.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: rust-for-linux@vger.kernel.org
Cc: linux-doc@vger.kernel.org
---
Shashank Balaji (2):
kernel: param: handle NULL module_kset in lookup_or_create_module_kobject()
driver core: platform: set mod_name in driver registration
Documentation/driver-api/driver-model/platform.rst | 3 ++-
drivers/base/platform.c | 21 ++++++++++++++-------
drivers/hwtracing/coresight/coresight-catu.c | 3 ++-
drivers/hwtracing/coresight/coresight-core.c | 5 +++--
drivers/hwtracing/coresight/coresight-cpu-debug.c | 2 +-
drivers/hwtracing/coresight/coresight-funnel.c | 2 +-
drivers/hwtracing/coresight/coresight-replicator.c | 2 +-
drivers/hwtracing/coresight/coresight-stm.c | 3 ++-
drivers/hwtracing/coresight/coresight-tmc-core.c | 3 ++-
drivers/hwtracing/coresight/coresight-tnoc.c | 3 ++-
drivers/hwtracing/coresight/coresight-tpdm.c | 2 +-
drivers/hwtracing/coresight/coresight-tpiu.c | 3 ++-
include/linux/coresight.h | 3 ++-
include/linux/platform_device.h | 17 +++++++++--------
kernel/params.c | 3 +++
rust/kernel/platform.rs | 4 +++-
16 files changed, 50 insertions(+), 29 deletions(-)
---
base-commit: b4e07588e743c989499ca24d49e752c074924a9a
change-id: 20260416-acpi_mod_name-f645a76e337b
Best regards,
--
Shashank Balaji <shashank.mahadasyam@sony.com>
^ permalink raw reply
* Re: [PATCH net-deletions] net: remove ax25 and amateur radio (hamradio) subsystem
From: Greg KH @ 2026-04-21 6:04 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
skhan, federico.vaga, carlos.bilbao, avadhut.naik, alexs,
si.yanteng, dzm91, 2023002089, tsbogend, dsahern, jani.nikula,
mchehab+huawei, jirislaby, tytso, herbert, ebiggers,
johannes.berg, geert, pablo, tglx, mashiro.chen, mingo, dqfext,
jreuter, sdf, pkshih, enelsonmoore, mkl, toke, kees, crossd,
jlayton, wangliang74, aha310510, takamitz, kuniyu, linux-doc,
linux-mips
In-Reply-To: <20260421021824.1293976-1-kuba@kernel.org>
On Mon, Apr 20, 2026 at 07:18:23PM -0700, Jakub Kicinski wrote:
> Remove the amateur radio (AX.25, NET/ROM, ROSE) protocol implementation
> and all associated hamradio device drivers from the kernel tree.
> This set of protocols has long been a huge bug/syzbot magnet,
> and since nobody stepped up to help us deal with the influx
> of the AI-generated bug reports we need to move it out of tree
> to protect our sanity.
>
> The code is moved to an out-of-tree repo:
> https://github.com/linux-netdev/mod-orphan
> if it's cleaned up and reworked there we can accept it back.
>
> Minimal stub headers are kept for include/net/ax25.h (AX25_P_IP,
> AX25_ADDR_LEN, ax25_address) and include/net/rose.h (ROSE_ADDR_LEN)
> so that the conditional integration code in arp.c and tun.c continues
> to compile and work when the out-of-tree modules are loaded.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply
* Re: [PATCH net-deletions] net: remove ISDN subsystem and Bluetooth CMTP
From: Greg KH @ 2026-04-21 6:03 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
skhan, marcel, luiz.dentz, mchehab+huawei, jani.nikula, demarchi,
rdunlap, justonli, ivecera, jonathan.cameron, kees,
marco.crivellari, ferr.lambarginio, nihaal, mingo, tglx, linmq006,
linux-doc, linux-bluetooth
In-Reply-To: <20260421022108.1299678-1-kuba@kernel.org>
On Mon, Apr 20, 2026 at 07:21:07PM -0700, Jakub Kicinski wrote:
> Remove the ISDN (mISDN, CAPI) subsystem and Bluetooth CMTP protocol
> from the kernel tree.
>
> ISDN is a pretty old technology and it's unclear whether anyone still
> uses it. I went over the last few years of git history and all the
> commits are either tree-wide conversions or syzbot/static analyzer
> fixes.
>
> When we discussed removal in the past IIRC there were some concerns
> about ISDN still being used in parts of Germany. Unfortunately, the
> code base is quite old, none of the current maintainers are familiar
> with it and AI tools will have a field day finding bugs here.
>
> Delete this code and preserve it in an out-of-tree repository
> for any remaining users:
> https://github.com/linux-netdev/mod-orphan
>
> UAPI constants AF_ISDN/PF_ISDN and the SELinux isdn_socket class
> are preserved for ABI stability, but the rest of uAPI is removed.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply
* Re: [PATCH] docs: fix typos in Documentation/PCI/
From: Randy Dunlap @ 2026-04-21 4:58 UTC (permalink / raw)
To: josh ziegler, bhelgaas, corbet; +Cc: skhan, linux-pci, linux-doc, linux-kernel
In-Reply-To: <20260421012059.251492-1-joshziegler76@gmail.com>
On 4/20/26 6:20 PM, josh ziegler wrote:
> Fix "chose" -> "choose" in pci.rst
> Fix "result an" -> "result in an" in pciebus-howto.rst
>
> Signed-off-by: josh ziegler <joshziegler76@gmail.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org>
> ---
> Documentation/PCI/pci.rst | 2 +-
> Documentation/PCI/pciebus-howto.rst | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/PCI/pci.rst b/Documentation/PCI/pci.rst
> index f4d2662871ab..be35e9a1ee75 100644
> --- a/Documentation/PCI/pci.rst
> +++ b/Documentation/PCI/pci.rst
> @@ -338,7 +338,7 @@ the PCI_IRQ_MSI and PCI_IRQ_MSIX flags will fail, so try to always
> specify PCI_IRQ_INTX as well.
>
> Drivers that have different interrupt handlers for MSI/MSI-X and
> -legacy INTx should chose the right one based on the msi_enabled
> +legacy INTx should choose the right one based on the msi_enabled
> and msix_enabled flags in the pci_dev structure after calling
> pci_alloc_irq_vectors.
>
> diff --git a/Documentation/PCI/pciebus-howto.rst b/Documentation/PCI/pciebus-howto.rst
> index 375d9ce171f6..9cc133ccdeec 100644
> --- a/Documentation/PCI/pciebus-howto.rst
> +++ b/Documentation/PCI/pciebus-howto.rst
> @@ -97,7 +97,7 @@ register its service with the PCI Express Port Bus driver (see
> section 5.2.1 & 5.2.2). It is important that a service driver
> initializes the pcie_port_service_driver data structure, included in
> header file /include/linux/pcieport_if.h, before calling these APIs.
> -Failure to do so will result an identity mismatch, which prevents
> +Failure to do so will result in an identity mismatch, which prevents
> the PCI Express Port Bus driver from loading a service driver.
>
> pcie_port_service_register
--
~Randy
^ permalink raw reply
* [RFC PATCH 1/2] Docs/admin-guide/mm/damon/usage: mark scheme filters sysfs dir as deprecated
From: SeongJae Park @ 2026-04-21 4:49 UTC (permalink / raw)
Cc: SeongJae Park, Liam R. Howlett, Andrew Morton, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
linux-kernel, linux-mm
In-Reply-To: <20260421044928.141388-1-sj@kernel.org>
The alternatives of 'filters/' directory, namely 'core_filters/' and
'ops_filters/', can fully support all the features 'filters/' directory
can do, and provide better user experience. Having 'filters/'
directory is only confusing to users. Announce it as deprecated on the
usage document.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
Documentation/admin-guide/mm/damon/usage.rst | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/Documentation/admin-guide/mm/damon/usage.rst b/Documentation/admin-guide/mm/damon/usage.rst
index d5548e460857c..918c14a8e852b 100644
--- a/Documentation/admin-guide/mm/damon/usage.rst
+++ b/Documentation/admin-guide/mm/damon/usage.rst
@@ -486,9 +486,10 @@ layers. Filters that requested by ``core_filters`` and ``ops_filters`` will be
installed before those of ``filters``. All three directories have same files.
Use of ``filters`` directory can make expecting evaluation orders of given
-filters with the files under directory bit confusing. Users are hence
-recommended to use ``core_filters`` and ``ops_filters`` directories. The
-``filters`` directory could be deprecated in future.
+filters with the files under directory bit confusing. For the reason,
+``filters`` directory is deprecated. It is still functioning, but it will be
+broken and eventually removed in near future. Users should use
+``core_filters`` and ``ops_filters`` directories instead.
In the beginning, the directory has only one file, ``nr_filters``. Writing a
number (``N``) to the file creates the number of child directories named ``0``
--
2.47.3
^ permalink raw reply related
* [RFC PATCH 0/2] mm/damon/sysfs: document filters/ directory as deprecated
From: SeongJae Park @ 2026-04-21 4:49 UTC (permalink / raw)
Cc: SeongJae Park, Liam R. Howlett, Andrew Morton, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
linux-kernel, linux-mm
Commit ab71d2d30121 ("mm/damon/sysfs-schemes: let
damon_sysfs_scheme_set_filters() be used for different named
directories") introduced alternatives of 'filters' directory, namely
core_filters/ and 'ops_filters/ directories. Now the alternatives are
well stabilized and ready for all users. All filters/ directory use
cases are expected to be able to be migrated to the alternatives. An
LTS kernel having the alternatives, namely 6.18.y, is also released.
Existence of filters/ directory is only confusing.
It would be better not immediately removing the directory, though.
There could be users that need time before migrating to the
alternatives. There might be unexpected use cases that the alternatives
cannot support. Doing the deprecation step by step across multiple
years like DAMON debugfs deprecation would be safer. Start the
deprecation changes by announcing the deprecation on the documents.
Every year, one more action for completely removing the directory will
be followed, like DAMON debugfs deprecation did. Following yearly
actions are currently expected. In 2027, deprecation warning kernel
messages will be printed once, for use of filters/ directory. In 2028,
filters/ directory will be renamed to filters_DEPRECATED/. In 2029,
filters_DEPRECATED/ directory will be removed.
SeongJae Park (2):
Docs/admin-guide/mm/damon/usage: mark scheme filters sysfs dir as
deprecated
Docs/ABI/damon: mark schemes/<S>/filters/ deprecated
.../ABI/testing/sysfs-kernel-mm-damon | 62 ++++++++++---------
Documentation/admin-guide/mm/damon/usage.rst | 7 ++-
2 files changed, 38 insertions(+), 31 deletions(-)
base-commit: 68f9cad2eca9a05a70ec47a90f2ae97aa2363a9c
--
2.47.3
^ permalink raw reply
* Re: [PATCH v2 00/16] fs,x86/resctrl: Add kernel-mode (e.g., PLZA) support to the resctrl subsystem
From: Reinette Chatre @ 2026-04-21 3:17 UTC (permalink / raw)
To: Moger, Babu, Babu Moger, corbet@lwn.net, tony.luck@intel.com,
Dave.Martin@arm.com, james.morse@arm.com, tglx@kernel.org,
mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com
Cc: skhan@linuxfoundation.org, x86@kernel.org, hpa@zytor.com,
peterz@infradead.org, juri.lelli@redhat.com,
vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
vschneid@redhat.com, kas@kernel.org, rick.p.edgecombe@intel.com,
akpm@linux-foundation.org, pmladek@suse.com,
rdunlap@infradead.org, dapeng1.mi@linux.intel.com,
kees@kernel.org, elver@google.com, paulmck@kernel.org,
lirongqing@baidu.com, safinaskar@gmail.com, fvdl@google.com,
seanjc@google.com, pawan.kumar.gupta@linux.intel.com,
xin@zytor.com, tiala@microsoft.com, chang.seok.bae@intel.com,
Lendacky, Thomas, elena.reshetova@intel.com,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-coco@lists.linux.dev, kvm@vger.kernel.org,
eranian@google.com, peternewman@google.com
In-Reply-To: <e8530c71-fde2-4522-8b46-a24efb13b681@amd.com>
Hi Babu,
On 4/20/26 5:40 PM, Moger, Babu wrote:
>
> We already discussed moving back to the default group on every mode
> switch. Doing so here would once again cause extra MSR writes on
> each mode transition, which is undesirable.
>
Needing to avoid extra MSR writes in resctrl is not so absolute. Consider, for
example, how resctrl initializes default allocations when a new resource group is
created. resctrl aims to initialize with sane defaults and the user is expected to
follow with desired allocations.
I am not against optimizing, I just want to be careful with such general statements.
Considering your proposal in https://lore.kernel.org/lkml/39e0c786-cc35-4555-bfb9-ff7cd758c423@amd.com/:
I do not think we should make info/kernel_mode read-only. If I understand correctly
doing so would accommodate AMD PLZA but it ignores the discussions on how resctrl could
support MPAM ... or do you perhaps have proposal on how MPAM can be supported when considering
your proposal? Even if you do not want to consider MPAM - what if the PLZA_PQR register's
scope becomes per-CPU in the next version of AMD PLZA?
The idea behind info/kernel_mode is that the active mode it identifies indicates which
configuration files exist to configure the active mode. Since the mode may not always
depend on global configuration, for which info/kernel_mode_assignment was created, but instead
rely on per-resource group files, I do not see how resctrl can build on a read-only
info/kernel_mode backed by a mode and group change via info/kernel_mode_assignment.
Specifically, MPAM support may not use info/kernel_mode_assignment at all.
Instead, MPAM may use something like described in https://lore.kernel.org/lkml/aYyxAPdTFejzsE42@e134344.arm.com/
Could we perhaps consider dropping info/kernel_mode_assignment entirely for
AMD PLZA's global allocations? Similar to what you suggest, the mode and
group assignment could be done via the info/kernel_mode file instead?
Thinking about this more since the CPUs allocation is global, these could *theoretically*
be included also (but see later).
This could mean that "kernel_mode_cpus" and "kernel_mode_cpus_list" could be dropped?
Although, this may complicate the interface since user space may want a convenient way
to modify just CPUs independently from needing to repeat the mode and group every time.
Consider, for example:
# echo "global_assign_ctrl_assign_mon_per_cpu:group=ctrl1/mon1/;cpus_list=5-8" > info/kernel_mode
Having named fields (a) makes this extensible, (b) output does not need to be split among files,
and (c) "inherit_ctrl_and_mon" can continue to be supported.
The named fields could be made optional, if group is omitted then it will become the
default resource group, and if cpus/cpus_list is omitted then it will default to all CPUs.
This may not be intuitive since a user may expect that not mentioning a field means
that the field is left untouched. Have you considered this scenario in your proposal?
As an alternative the group could be made a required field and "kernel_mode_cpus"/"kernel_mode_cpuslist"
can stay? This may be the simplest approach.
Output could still use [] to indicate the active mode that includes its properties.
I find to be more intuitive interface where output more closely matches input.
Reinette
^ permalink raw reply
* Re: [PATCH V10 00/10] famfs: port into fuse
From: Joanne Koong @ 2026-04-21 3:12 UTC (permalink / raw)
To: Gregory Price
Cc: John Groves, David Hildenbrand (Arm), Darrick J. Wong,
Miklos Szeredi, Bernd Schubert, John Groves, Dan Williams,
Bernd Schubert, Alison Schofield, John Groves, Jonathan Corbet,
Shuah Khan, Vishal Verma, Dave Jiang, Matthew Wilcox, Jan Kara,
Alexander Viro, Christian Brauner, Randy Dunlap, Jeff Layton,
Amir Goldstein, Jonathan Cameron, Stefan Hajnoczi, Josef Bacik,
Bagas Sanjaya, Chen Linxuan, James Morse, Fuad Tabba,
Sean Christopherson, Shivank Garg, Ackerley Tng, Aravind Ramesh,
Ajay Joshi, venkataravis@micron.com, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, nvdimm@lists.linux.dev,
linux-cxl@vger.kernel.org, linux-fsdevel@vger.kernel.org, djbw
In-Reply-To: <aeVy2MzucnrLlOQx@gourry-fedora-PF4VCD3F>
On Sun, Apr 19, 2026 at 5:27 PM Gregory Price <gourry@gourry.net> wrote:
>
> On Sun, Apr 19, 2026 at 03:36:30PM -0500, John Groves wrote:
> > On 26/04/15 10:16AM, David Hildenbrand (Arm) wrote:
> > > On 4/15/26 00:20, Gregory Price wrote:
> > > > On Tue, Apr 14, 2026 at 11:57:40AM -0700, Darrick J. Wong wrote:
> >
> > Gregory's code, in the current form, still uses two new fuse messages,
> > GET_FMAP and GET_DAXDEV, but it makes the fmap message format opaque by
> > removing fmap format structs from the uapi. It also uses two BPF programs.
> > One BPF program parses and validates the GET_FMAP payload for every file,
> > and hangs it from a 'void *' in each fuse_inode (just like the current famfs
> > code). The other BPF program is called during vma faults and reads the
> > fuse_inode->'void *' in order to handle faults the same way famfs-fuse does
> > today, but via BPF instead.
> >
>
Thanks John for running the benchmarks on your hardware. And thanks
Gregory for your work on this too.
> I'll just lay out what i've done and why.
>
> For John's sanity, if there are NACKs, knowing sooner rather than later
> would be a kindness.
>
> === Problem: Any lookup() in iomap_begin() is too much overhead.
>
> No dax-backed server will want to eat the cost of a lookup() that
> could be multiple microseconds on what should be a 1-5us soft-fault.
>
> Joanne's prototype had this:
>
> meta = bpf_map_lookup_elem(&inode_map, &nodeid);
>
> But it was offsetting a single pointer dereference:
>
> struct fuse_inode *fi = get_fuse_inode(inode);
> struct famfs_file_meta *meta = fi->famfs_meta;
>
> Not all O(1) are created equal here.
>
> A single L3 LLC miss plus page table walk can cost you ~100ns.
> If that pointer was cache-hot, it's almost free.
>
> A pointer chase through any structure is N x ~100ns.
> This is unlikely to ever be sufficiently cache hot by comparison.
>
> So, lets just avoid this problem altogether.
>
>
> === Requirements
>
> 1) No hard-coded OMF structures in the FUSE API.
>
> While RAID0 style interleaving isn't exactly fancy or novel,
> folks think this should not be in the kernel headers.
>
> (I'm not going to argue, I think the argument is pointless)
>
>
> 2) imap_begin() needs metadata accessible on the order of a single
> pointer dereference - which is what John has implemented.
>
>
> 3) open() needs to validate the metadata and identify DAX devices
>
> a) it needs to validate the DAX devices are available and
> acquire them / set them up / etc. This is a kernel-side op.
>
> b) it needs to validate the addressing information is valid for
> the relevant dax devices
>
> Both GET_FMAP and GET_DAXDEV are avoided if the metadata is
> already cached or the DAXDEV is already setup. So keeping these
> separate is actually important.
>
>
> Joanne's code deals with #1 - but it doesn't handle #2 or #3.
> (It also doesn't handle GET_DAXDEV at all).
It handles #3 by removing GET_DAXDEV as a fuse op and having the
daxdev initialization / setup routed through FUSE_IOMAP_CONFIG at
iomap initialization time instead, which integrates with the generic
iomap infrastruture/uapi additions Darrick added in his fuse-iomap
series [1].
In this series the GET_DAXDEV op gets sent lazily on file opens but
it's still not clear to me why this is necessary. imo device setup
should happen logically as part of iomap configuration and it seems
more efficient to have devices validated/acquired before any files are
opened. I thihnk that makes things a lot simpler on the kernel side in
other ways (eg we can get rid of famfs_dax_devlist / famfs_daxdev /
famfs_devlist_sem / famfs_update_daxdev_table() /
famfs_fuse_get_daxdev() altogether). It also saves the famfs server
the roundtrip context switching cost if we get rid of GET_DAXDEV and
move it to iomap initialization time, which will improve FUSE_OPEN
performance for famfs. Maybe there's something I'm missing here as to
why the daxdev initialization has to be done lazily on open?
I think Darrick had also mentioned something earlier about how he
thinks GET_DAXDEV should be another application of backing files [2] -
I like this idea too, as it gets rid of the GET_DAXDEV op and reuses
fuse's existing infrastructure.
[1] https://lore.kernel.org/linux-fsdevel/177188734695.3935739.8198854011004837207.stgit@frogsfrogsfrogs/
[2] https://lore.kernel.org/linux-fsdevel/20260416224331.GD114184@frogsfrogsfrogs/
>
> John's code mananges #2 and #3 by having the fuse-server pass meta data
> on open() via GET_FMAP and GET_DAXDEV.
>
> GET_FMAP acquires the meta data on how dax devices are used
>
> GET_DAXDEV just translates an ID to specific dax device.
> iomap_being() then uses the OMF to do the mapping.
>
> But it does this by hard-coding the format into kernel headers.
>
>
> === Observation: Add a BPF dax_fmap_parse() on open()
>
> Pair Joanne's suggestion with John's GET_FMAP/GET_DAXDEV operations.
>
> struct fuse_dax_fmap_ops {
> char name[FUSE_DAX_FMAP_OPS_NAME_LEN]; // 16 bytes
> int (*dax_fmap_parse)(struct fuse_dax_fmap_parse_ctx *ctx);
Just a note for later, if the bpf approach gets pursued further:
instead of making this a dax specific ops, I think this needs to be
integrated interface-wise with Darrick's fuse-iomap work since he does
the same thing. I think dax_fmap_parse() could be renamed to something
like iomap_setup(), where userspace can use this to do any sort of
generic setup, whether that's mapping related or dax related or not.
In my mind, the dax vs non dax distinction is handled by the fuse
iomap plumbing that chooses which iomap entry points to call, but
beyond that, the callbacks and struct ops themselves should be
generic enough to be shared between the two.
> int (*iomap_begin)(struct fuse_dax_fmap_resolve_ctx *ctx,
> struct fuse_iomap_io *io);
> };
>
> This parse function is used to do filesystem specific setup the (such as
> populate the dax bitmap) based on filesystem-specific per-file metadata.
>
> In John's case, essentially all it does is populate the dax bitmap and
> toss the data onto fi->dax_fmap.meta.
>
> Pseudo code:
>
> fuse_dax_fmap_open(inode):
> fmap_size = send_GET_FMAP(inode, fmap_buf)
>
> /* Make space to store the metadata */
> meta_buf = kzalloc(meta_size)
> ctx = { ... }
> kern = { .ctx, .blob = blob, .meta_buf = meta_buf }
>
> /* Parse the metadata: i.e. fill out the daxdev bitmap */
> fc->dax_fmap_ops->dax_fmap_parse(&ctx)
>
> /* Call GET_DAXDEV for any new dax devices */
> resolve_dev_bitmap(ctx.dev_bitmap)
>
> /* cache the meta data on the inode */
> inode_lock()
> fi->dax_fmap.meta = meta_buf
> ... etc etc ...
> inode_unlock()
>
> And otherwise, imap_begin() works exactly as Joanne proposed, but with
> in-kernel cached data instead of the bpfmap.
>
> const struct dax_simple_meta *meta = (const struct dax_simple_meta *)
> bpf_fuse_dax_resolve_get_meta(ctx, 0, sizeof(*meta));
another note for later, if the benchmarks prove promising and after
the LSF discussions we decide to go with this approach: imo we
could/should repurpose this into a generic
bpf_fuse_iomap_get_inode_meta() that returns a bounded pointer into
whatever opaque blob was cached on the inode during iomap_setup(),
where it'd be a generic kfunc serving both the dax and non-dax case
for any kind of mapping layout
>
> And since both parse() and iomap_begin() are bpf programs - and they're
> the only consumers of the metadata - FUSE itself no longer needs to know
> anything about the server's particular strategy to use the dax devices.
>
> struct fuse_inode {
> ...
> #if IS_ENABLED(CONFIG_FUSE_DAX_FMAP)
> struct {
> void *meta;
> u32 meta_size;
> u64 file_size;
I don't think file_size is needed here? seems like we could just
derive this from i_size_read(inode)?
> } dax_fmap;
/s/dax_fmap/iomap
> #endif
> };
>
> Just a big ol' honkin' void* that otherwise gets ignored.
>
> (Note: while i'm not a BPF wizard, this pattern seems well established in
> existing BPF code, i found code in the network stack that caches
> data on kernel objects this way as well)
>
> ==== Caveats
>
> 1) We don't know the overhead BPF introduces in the fault path.
>
> My napkin math (and best understanding of BPF) suggests:
>
> 1) trampoline / vtable for bpf ops (iomap_begin func)
> 2) retpoline cost of BPF (assuming this is on, safe assumption)
> 3) bpf_fuse_dax_resolve_get_meta() overhead (extra pointer deref)
>
> This *should* (i think) amount to an extra pointer dereference, a longjump,
> and a retpoline, which hopefully is <100ns since any extra pointer
> derefs here SHOULD be cache-hot (hard to know).
>
> It's not 0 overhead, and if the average fault time is 1us then every
> additional 10ns not an insignificant cost.
>
> But this is napkin math. John will collect data.
>
>
> 2) FUSE needs to be ok with the BPF-driven changes:
>
> https://github.com/joannekoong/linux/commits/prototype_generic_iomap_dax/
>
>
> 3) FUSE needs to be ok with GET_FMAP/GET_DAXDEV as opaque meta-data
> handlers for DAX devices.
I think we could kill GET_DAXDEV and for GET_FMAP, we could make this
a generic FUSE_IOMAP_GETMAP where the server can set a flag on open to
indicate whether the mapping blob should be fetched or not.
>
> That means there is no default parser or format. If you don't
> register ops, these functions are functionally dead.
>
> (probably fine to enforce during init, which is what i did)
>
>
> 4) As John said: MM needs to be good with it.
>
> Any server using DAX like this already essentially has CAP_SYS_RAWIO
> for DAX, and most likely some form of CAP_SYS_ADMIN.
>
> Additionally, as folks have pointed out, the resolution to PTE is
> bounded by dax device extents, so it's not entirely arbitrary.
>
> ===
>
> As mentioned at the start - you'd be doing John a kindness if there are
> clear and obvious NACK's to be had here.
I don't have a NACK on what you wrote above, thank you for your work
on this and bridging it into John's famfs server.
As I understand it, Amir also scheduled a cross-track FS+MM+IO session
at LSF to discuss famfs and dax iomap. Christoph had posted a
suggestion in another message about solving this problem with adding
generic stride/offset multi-device support to fs/iomap, and I'm hoping
the LSF session will shed more light on this, as that to me seems the
cleanest solution and would pretty much give everyone what they want
(including getting famfs unblocked, as I think with this approach we
would just need to figure out the generic stride/offset format for the
fuse iomap uapi, and could have the interleaving logic living in fuse
initially with fs/iomap migrations done post-merge). In the meantime,
I think it's really helpful getting the data points on how bpf
performs, thank you for running the benchmarks on your setup, John.
Thanks,
Joanne
>
> ~Gregory
^ permalink raw reply
* [PATCH 23/23] cgroup/cpuset: Documentation and kselftest updates
From: Waiman Long @ 2026-04-21 3:03 UTC (permalink / raw)
To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>
As CPU hotplug is now being used to enable runtime update to the list
of nohz_full and managed_irq CPUs, we should avoid using CPU 0 in the
formation of isolated partition as CPU 0 may not be able to be brought
offline like in the case of x86-64 architecture. So a number of the
test cases in test_cpuset_prs.sh will have to be updated accordingly.
A new test will also be run in offline isn't allowed in CPU 0 to verify
that using CPU 0 as part of an isolated partition will fail.
The cgroup-v2.rst is also updated to reflect the new capability of using
CPU hotplug to enable run time change to the nohz_full and managed_irq
CPU lists.
Since there is a slight performance overhead to enable runtime changes
to nohz_full CPU list, users have to explicitly opt in by adding a
"nohz_ful" kernel command line parameter with or without a CPU list.
Signed-off-by: Waiman Long <longman@redhat.com>
---
Documentation/admin-guide/cgroup-v2.rst | 35 +++++++---
.../selftests/cgroup/test_cpuset_prs.sh | 70 +++++++++++++++++--
2 files changed, 92 insertions(+), 13 deletions(-)
diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
index 8ad0b2781317..e97fc031eb86 100644
--- a/Documentation/admin-guide/cgroup-v2.rst
+++ b/Documentation/admin-guide/cgroup-v2.rst
@@ -2604,11 +2604,12 @@ Cpuset Interface Files
It accepts only the following input values when written to.
- ========== =====================================
+ ========== ===============================================
"member" Non-root member of a partition
"root" Partition root
- "isolated" Partition root without load balancing
- ========== =====================================
+ "isolated" Partition root without load balancing and other
+ OS noises
+ ========== ===============================================
A cpuset partition is a collection of cpuset-enabled cgroups with
a partition root at the top of the hierarchy and its descendants
@@ -2652,11 +2653,29 @@ Cpuset Interface Files
partition or scheduling domain. The set of exclusive CPUs is
determined by the value of its "cpuset.cpus.exclusive.effective".
- When set to "isolated", the CPUs in that partition will be in
- an isolated state without any load balancing from the scheduler
- and excluded from the unbound workqueues. Tasks placed in such
- a partition with multiple CPUs should be carefully distributed
- and bound to each of the individual CPUs for optimal performance.
+ When set to "isolated", the CPUs in that partition will be in an
+ isolated state without any load balancing from the scheduler and
+ excluded from the unbound workqueues as well as other OS noises.
+ Tasks placed in such a partition with multiple CPUs should be
+ carefully distributed and bound to each of the individual CPUs
+ for optimal performance.
+
+ As CPU hotplug, if supported, is used to improve the degree of
+ CPU isolation close to the "nohz_full" kernel boot parameter.
+ In some architectures, like x86-64, the boot CPU (typically CPU
+ 0) cannot be brought offline, so the boot CPU should not be used
+ for forming isolated partitions. The "nohz_full" kernel boot
+ parameter needs to be present to enable full dynticks support
+ and RCU no-callback CPU mode for CPUs in isolated partitions
+ even if the optional cpu list isn't provided.
+
+ Using CPU hotplug for creating or destroying an isolated
+ partition can cause latency spike in applications running
+ in other isolated partitions. A reserved list of CPUs can
+ optionally be put in the "nohz_full" kernel boot parameter to
+ alleviate this problem. When these reserved CPUs are used for
+ isolated partitions, CPU hotplug won't need to be invoked and
+ so there won't be latency spike in other isolated partitions.
A partition root ("root" or "isolated") can be in one of the
two possible states - valid or invalid. An invalid partition
diff --git a/tools/testing/selftests/cgroup/test_cpuset_prs.sh b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
index a56f4153c64d..eebb4122b581 100755
--- a/tools/testing/selftests/cgroup/test_cpuset_prs.sh
+++ b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
@@ -67,6 +67,12 @@ then
echo Y > /sys/kernel/debug/sched/verbose
fi
+# Enable dynamic debug message if available
+DYN_DEBUG=/proc/dynamic_debug/control
+[[ -f $DYN_DEBUG ]] && {
+ echo "file kernel/cpu.c +p" > $DYN_DEBUG
+}
+
cd $CGROUP2
echo +cpuset > cgroup.subtree_control
@@ -84,6 +90,15 @@ echo member > test/cpuset.cpus.partition
echo "" > test/cpuset.cpus
[[ $RESULT -eq 0 ]] && skip_test "Child cgroups are using cpuset!"
+#
+# If nohz_full parameter is specified and nohz_full file exists, CPU hotplug
+# will be used to modify nohz_full cpumask to include all the isolated CPUs
+# in cpuset isolated partitions.
+#
+NOHZ_FULL=/sys/devices/system/cpu/nohz_full
+BOOT_NOHZ_FULL=$(fmt -1 /proc/cmdline | grep "^nohz_full")
+[[ "$BOOT_NOHZ_FULL" = nohz_full ]] && CHK_NOHZ_FULL=1
+
#
# If isolated CPUs have been reserved at boot time (as shown in
# cpuset.cpus.isolated), these isolated CPUs should be outside of CPUs 0-8
@@ -318,8 +333,8 @@ TEST_MATRIX=(
# Invalid to valid local partition direct transition tests
" C1-3:P2 X4:P2 . . . . . . 0 A1:1-3|XA1:1-3|A2:1-3:XA2: A1:P2|A2:P-2 1-3"
" C1-3:P2 X4:P2 . . . X3:P2 . . 0 A1:1-2|XA1:1-3|A2:3:XA2:3 A1:P2|A2:P2 1-3"
- " C0-3:P2 . . C4-6 C0-4 . . . 0 A1:0-4|B1:5-6 A1:P2|B1:P0"
- " C0-3:P2 . . C4-6 C0-4:C0-3 . . . 0 A1:0-3|B1:4-6 A1:P2|B1:P0 0-3"
+ " C1-3:P2 . . C4-6 C1-4 . . . 0 A1:1-4|B1:5-6 A1:P2|B1:P0"
+ " C1-3:P2 . . C4-6 C1-4:C1-3 . . . 0 A1:1-3|B1:4-6 A1:P2|B1:P0 1-3"
# Local partition invalidation tests
" C0-3:X1-3:P2 C1-3:X2-3:P2 C2-3:X3:P2 \
@@ -329,8 +344,8 @@ TEST_MATRIX=(
" C0-3:X1-3:P2 C1-3:X2-3:P2 C2-3:X3:P2 \
. . C4:X . . 0 A1:1-3|A2:1-3|A3:2-3|XA2:|XA3: A1:P2|A2:P-2|A3:P-2 1-3"
# Local partition CPU change tests
- " C0-5:P2 C4-5:P1 . . . C3-5 . . 0 A1:0-2|A2:3-5 A1:P2|A2:P1 0-2"
- " C0-5:P2 C4-5:P1 . . C1-5 . . . 0 A1:1-3|A2:4-5 A1:P2|A2:P1 1-3"
+ " C1-5:P2 C4-5:P1 . . . C3-5 . . 0 A1:1-2|A2:3-5 A1:P2|A2:P1 1-2"
+ " C1-5:P2 C4-5:P1 . . C2-5 . . . 0 A1:2-3|A2:4-5 A1:P2|A2:P1 2-3"
# cpus_allowed/exclusive_cpus update tests
" C0-3:X2-3 C1-3:X2-3 C2-3:X2-3 \
@@ -442,6 +457,21 @@ TEST_MATRIX=(
" C0-3 . . C4-5 X3-5 . . . 1 A1:0-3|B1:4-5"
)
+#
+# Test matrix to verify that using CPU 0 in isolated (local or remote) partition
+# will fail when offline isn't allowed for CPU 0.
+#
+CPU0_ISOLCPUS_MATRIX=(
+ # old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
+ # ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
+ " C0-3 . . C4-5 P2 . . . 0 A1:0-3|B1:4-5 A1:P-2"
+ " C1-3 . . . P2 . . . 0 A1:1-3 A1:P2"
+ " C1-3 . . . P2:C0-3 . . . 0 A1:0-3 A1:P-2"
+ " CX0-3 C0-3 . . . P2 . . 0 A1:0-3|A2:0-3 A2:P-2"
+ " CX0-3 C0-3:X1-3 . . . P2 . . 0 A1:0|A2:1-3 A2:P2"
+ " CX0-3 C0-3:X1-3 . . . P2:X0-3 . . 0 A1:0-3|A2:0-3 A2:P-2"
+)
+
#
# Cpuset controller remote partition test matrix.
#
@@ -513,7 +543,7 @@ write_cpu_online()
}
fi
echo $VAL > $CPUFILE
- pause 0.05
+ pause 0.10
}
#
@@ -654,6 +684,8 @@ dump_states()
[[ -e $PCPUS ]] && echo "$PCPUS: $(cat $PCPUS)"
[[ -e $ISCPUS ]] && echo "$ISCPUS: $(cat $ISCPUS)"
done
+ # Dump nohz_full
+ [[ -f $NOHZ_FULL ]] && echo "nohz_full: $(cat $NOHZ_FULL)"
}
#
@@ -789,6 +821,18 @@ check_isolcpus()
EXPECTED_SDOMAIN=$EXPECTED_ISOLCPUS
fi
+ #
+ # Check if nohz_full match cpuset.cpus.isolated if nohz_boot parameter
+ # specified with no parameter.
+ #
+ [[ -f $NOHZ_FULL && "$BOOT_NOHZ_FULL" = nohz_full ]] && {
+ NOHZ_FULL_CPUS=$(cat $NOHZ_FULL)
+ [[ "$ISOLCPUS" != "$NOHZ_FULL_CPUS" ]] && {
+ echo "nohz_full ($NOHZ_FULL_CPUS) does not match cpuset.cpus.isolated ($ISOLCPUS)"
+ return 1
+ }
+ }
+
#
# Appending pre-isolated CPUs
# Even though CPU #8 isn't used for testing, it can't be pre-isolated
@@ -1070,6 +1114,21 @@ run_remote_state_test()
echo "All $I tests of $TEST PASSED."
}
+#
+# Testing CPU 0 isolated partition test when offline is disabled
+#
+run_cpu0_isol_test()
+{
+ # Skip the test if CPU0 offline is allowed or if nohz_full kernel
+ # boot parameter is missing.
+ CPU0_ONLINE=/sys/devices/system/cpu/cpu0/online
+ [[ -f $CPU0_ONLINE ]] && return
+ grep -q -w nohz_full /proc/cmdline
+ [[ $? -ne 0 ]] && return
+
+ run_state_test CPU0_ISOLCPUS_MATRIX
+}
+
#
# Testing the new "isolated" partition root type
#
@@ -1207,6 +1266,7 @@ test_inotify()
trap cleanup 0 2 3 6
run_state_test TEST_MATRIX
run_remote_state_test REMOTE_TEST_MATRIX
+run_cpu0_isol_test
test_isolated
test_inotify
echo "All tests PASSED."
--
2.53.0
^ permalink raw reply related
* [PATCH 22/23] cgroup/cpuset: Prevent offline_disabled CPUs from being used in isolated partition
From: Waiman Long @ 2026-04-21 3:03 UTC (permalink / raw)
To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>
If tick_nohz_full_enabled() is true, we are going to use CPU
hotplug to enable runtime changes to the HK_TYPE_KERNEL_NOISE and
HK_TYPE_MANAGED_IRQ cpumasks. However, for some architectures, one
or maybe more CPUs will have the offline_disabled flag set in their
cpu devices. For instance, x64-64 will set this flag for its boot CPU
(typically CPU 0) to disable it from going offline. Those CPUs can't
be used in cpuset isolated partition, or we are going to have problem
in the CPU offline process.
Find out the set of CPUs with offline_disabled set in a
new cpuset_init_late() helper, set the corresponding bits in
offline_disabled_cpus cpumask and check it when isolated partitions are
being created or modified to ensure that we will not use any of those
offline disabled CPUs in an isolated partition.
An error message mentioning those offline disabled CPUs will be
constructed in cpuset_init_late() and shown in "cpuset.cpus.partition"
when isolated creation or modification fails.
Signed-off-by: Waiman Long <longman@redhat.com>
---
kernel/cgroup/cpuset-internal.h | 1 +
kernel/cgroup/cpuset.c | 89 ++++++++++++++++++++++++++++++++-
2 files changed, 88 insertions(+), 2 deletions(-)
diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
index fd7d19842ded..87b7411540ff 100644
--- a/kernel/cgroup/cpuset-internal.h
+++ b/kernel/cgroup/cpuset-internal.h
@@ -35,6 +35,7 @@ enum prs_errcode {
PERR_HKEEPING,
PERR_ACCESS,
PERR_REMOTE,
+ PERR_OL_DISABLED,
};
/* bits in struct cpuset flags field */
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 5f6b4e67748f..f3af8ef6c64e 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -20,6 +20,8 @@
*/
#include "cpuset-internal.h"
+#include <linux/cpu.h>
+#include <linux/device.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
@@ -48,7 +50,7 @@ DEFINE_STATIC_KEY_FALSE(cpusets_enabled_key);
*/
DEFINE_STATIC_KEY_FALSE(cpusets_insane_config_key);
-static const char * const perr_strings[] = {
+static const char *perr_strings[] __ro_after_init = {
[PERR_INVCPUS] = "Invalid cpu list in cpuset.cpus.exclusive",
[PERR_INVPARENT] = "Parent is an invalid partition root",
[PERR_NOTPART] = "Parent is not a partition root",
@@ -59,6 +61,7 @@ static const char * const perr_strings[] = {
[PERR_HKEEPING] = "partition config conflicts with housekeeping setup",
[PERR_ACCESS] = "Enable partition not permitted",
[PERR_REMOTE] = "Have remote partition underneath",
+ [PERR_OL_DISABLED] = "", /* To be set up later */
};
/*
@@ -164,6 +167,12 @@ static cpumask_var_t isolated_mirq_cpus; /* T */
static bool boot_nohz_le_domain __ro_after_init;
static bool boot_mirq_le_domain __ro_after_init;
+/*
+ * Cpumask of CPUs with offline_disabled set
+ * The cpumask is effectively __ro_after_init.
+ */
+static cpumask_var_t offline_disabled_cpus;
+
/*
* A flag to force sched domain rebuild at the end of an operation.
* It can be set in
@@ -1649,6 +1658,8 @@ static int remote_partition_enable(struct cpuset *cs, int new_prs,
* The effective_xcpus mask can contain offline CPUs, but there must
* be at least one or more online CPUs present before it can be enabled.
*
+ * An isolated partition cannot contain CPUs with offline disabled.
+ *
* Note that creating a remote partition with any local partition root
* above it or remote partition root underneath it is not allowed.
*/
@@ -1661,6 +1672,9 @@ static int remote_partition_enable(struct cpuset *cs, int new_prs,
!isolated_cpus_can_update(tmp->new_cpus, NULL)) ||
prstate_housekeeping_conflict(new_prs, tmp->new_cpus))
return PERR_HKEEPING;
+ if (tick_nohz_full_enabled() && (new_prs == PRS_ISOLATED) &&
+ cpumask_intersects(tmp->new_cpus, offline_disabled_cpus))
+ return PERR_OL_DISABLED;
spin_lock_irq(&callback_lock);
partition_xcpus_add(new_prs, NULL, tmp->new_cpus);
@@ -1746,6 +1760,16 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *xcpus,
goto invalidate;
}
+ /*
+ * Isolated partition cannot contains CPUs with offline_disabled
+ * bit set.
+ */
+ if (tick_nohz_full_enabled() && (prs == PRS_ISOLATED) &&
+ cpumask_intersects(excpus, offline_disabled_cpus)) {
+ cs->prs_err = PERR_OL_DISABLED;
+ goto invalidate;
+ }
+
adding = cpumask_andnot(tmp->addmask, excpus, cs->effective_xcpus);
deleting = cpumask_andnot(tmp->delmask, cs->effective_xcpus, excpus);
@@ -1913,6 +1937,11 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
if (tasks_nocpu_error(parent, cs, xcpus))
return PERR_NOCPUS;
+ if (tick_nohz_full_enabled() &&
+ (new_prs == PRS_ISOLATED) &&
+ cpumask_intersects(xcpus, offline_disabled_cpus))
+ return PERR_OL_DISABLED;
+
/*
* This function will only be called when all the preliminary
* checks have passed. At this point, the following condition
@@ -1979,12 +2008,21 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
parent->effective_xcpus);
}
+ /*
+ * Isolated partition cannot contain CPUs with offline_disabled
+ * bit set.
+ */
+ if (tick_nohz_full_enabled() &&
+ ((old_prs == PRS_ISOLATED) ||
+ (old_prs == PRS_INVALID_ISOLATED)) &&
+ cpumask_intersects(newmask, offline_disabled_cpus)) {
+ part_error = PERR_OL_DISABLED;
/*
* TBD: Invalidate a currently valid child root partition may
* still break isolated_cpus_can_update() rule if parent is an
* isolated partition.
*/
- if (is_partition_valid(cs) && (old_prs != parent_prs)) {
+ } else if (is_partition_valid(cs) && (old_prs != parent_prs)) {
if ((parent_prs == PRS_ROOT) &&
/* Adding to parent means removing isolated CPUs */
!isolated_cpus_can_update(tmp->delmask, tmp->addmask))
@@ -1995,6 +2033,19 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
part_error = PERR_HKEEPING;
}
+ if (part_error) {
+ deleting = false;
+ /*
+ * For a previously valid partition, we need to move
+ * the exclusive CPUs back to its parent.
+ */
+ if (is_partition_valid(cs) &&
+ !cpumask_empty(cs->effective_xcpus)) {
+ cpumask_copy(tmp->addmask, cs->effective_xcpus);
+ adding = true;
+ }
+ }
+
/*
* The new CPUs to be removed from parent's effective CPUs
* must be present.
@@ -3829,6 +3880,7 @@ int __init cpuset_init(void)
BUG_ON(!zalloc_cpumask_var(&subpartitions_cpus, GFP_KERNEL));
BUG_ON(!zalloc_cpumask_var(&isolated_cpus, GFP_KERNEL));
BUG_ON(!zalloc_cpumask_var(&isolated_hk_cpus, GFP_KERNEL));
+ BUG_ON(!zalloc_cpumask_var(&offline_disabled_cpus, GFP_KERNEL));
cpumask_setall(top_cpuset.cpus_allowed);
nodes_setall(top_cpuset.mems_allowed);
@@ -4188,6 +4240,39 @@ void __init cpuset_init_smp(void)
BUG_ON(!cpuset_migrate_mm_wq);
}
+/**
+ * cpuset_init_late - initialize the list of CPUs with offline_disabled set
+ *
+ * Description: Initialize a cpumask with CPUs that have the offline_disabled
+ * bit set. It is done in a separate initcall as cpuset_init_smp()
+ * is called before driver_init() where the CPU devices will be
+ * set up.
+ */
+static int __init cpuset_init_late(void)
+{
+ int cpu;
+
+ if (!tick_nohz_full_enabled())
+ return 0;
+ /*
+ * Iterate all the possible CPUs to see which one has offline disabled.
+ */
+ for_each_possible_cpu(cpu) {
+ if (get_cpu_device(cpu)->offline_disabled)
+ __cpumask_set_cpu(cpu, offline_disabled_cpus);
+ }
+ if (!cpumask_empty(offline_disabled_cpus)) {
+ char buf[128];
+
+ snprintf(buf, sizeof(buf),
+ "CPU %*pbl with offline disabled not allowed in isolated partition",
+ cpumask_pr_args(offline_disabled_cpus));
+ perr_strings[PERR_OL_DISABLED] = kstrdup(buf, GFP_KERNEL);
+ }
+ return 0;
+}
+pure_initcall(cpuset_init_late);
+
/*
* Return cpus_allowed mask from a task's cpuset.
*/
--
2.53.0
^ permalink raw reply related
* [PATCH 21/23] cgroup/cpuset: Limit the side effect of using CPU hotplug on isolated partition
From: Waiman Long @ 2026-04-21 3:03 UTC (permalink / raw)
To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>
CPU hotplug is used to facilitate the modification of the
HK_TYPE_KERNEL_NOISE and HK_TYPE_MANAGED_IRQ cpumasks. However, tearing
down and bringing up CPUs can impact the cpuset partition states
as well. For instance, tearing down the last CPU of a partition can
invalidate the partition with active tasks which will not happen if
CPU hotplug isn't used.
A workaround of this issue is disable the invalidation by pretending that
the partition has no task, and making the tasks within the partition
to the effective CPUs of its parent for a short while during the short
transition process where the CPUs will be teared down and the brought
up again.
Signed-off-by: Waiman Long <longman@redhat.com>
---
kernel/cgroup/cpuset.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index a927b9cd4f71..5f6b4e67748f 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -434,6 +434,13 @@ static inline bool partition_is_populated(struct cpuset *cs,
struct cpuset *cp;
struct cgroup_subsys_state *pos_css;
+ /*
+ * Hack: In cpuhp_offline_cb_mode, pretend all partitions are empty
+ * to prevent unnecessary partition invalidation.
+ */
+ if (cpuhp_offline_cb_mode)
+ return false;
+
/*
* We cannot call cs_is_populated(cs) directly, as
* nr_populated_domain_children may include populated
@@ -3881,6 +3888,17 @@ hotplug_update_tasks(struct cpuset *cs,
cs->effective_mems = *new_mems;
spin_unlock_irq(&callback_lock);
+ /*
+ * When cpuhp_offline_cb_mode is active, valid isolated partition
+ * with tasks may have no online CPUs available for a short while.
+ * In that case, we fall back to parent's effective CPUs temporarily
+ * which will be reset back to their rightful value once the affected
+ * CPUs are online again.
+ */
+ if (cpuhp_offline_cb_mode && cpumask_empty(new_cpus) &&
+ (cs->partition_root_state == PRS_ISOLATED))
+ cpumask_copy(new_cpus, parent_cs(cs)->effective_cpus);
+
if (cpus_updated)
cpuset_update_tasks_cpumask(cs, new_cpus);
if (mems_updated)
--
2.53.0
^ permalink raw reply related
* [PATCH 20/23] cgroup/cpuset: Enable runtime update of HK_TYPE_{KERNEL_NOISE,MANAGED_IRQ} cpumasks
From: Waiman Long @ 2026-04-21 3:03 UTC (permalink / raw)
To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>
One simple way to enable runtime update of HK_TYPE_KERNEL_NOISE
(nohz_full) and HK_TYPE_MANAGED_IRQ cpumasks is to make use of the CPU
hotplug to facilitate the transition of those CPUs that are changing
states as long as CONFIG_HOTPLUG_CPU is enabled and a nohz_full boot
parameter is provided. Otherwise, only HK_TYPE_DOMAIN cpumask will be
updated at run time.
For changes in HK_TYPE_DOMAIN cpumask, it can be done without using CPU
hotplug. For changes in HK_TYPE_MANAGED_IRQ cpumask, we have to update
the cpumask first and then tear down and bring up the newly isolated
CPUs to migrate the managed irqs in those CPUs to other housekeeping
CPUs.
For changes in HK_TYPE_KERNEL_NOISE, we have to tear down all the newly
isolated and de-isolated CPUs, change the cpumask and then bring all the
offline CPUs back online.
As it is possible that the various boot versions of the housekeeping
cpumasks are different resulting in the use of different set of isolated
cpumasks for calling housekeeping_update(), we may need to pre-allocate
these cpumasks if necessary.
Note that the use of CPU hotplug to facilitate the changing of
HK_TYPE_KERNEL_NOISE and HK_TYPE_MANAGED_IRQ housekeeping cpumasks has
the drawback that during the tear down of a CPU from CPUHP_TEARDOWN_CPU
state to CPUHP_AP_OFFLINE, the stop_machine code will be invoked to stop
all the other CPUs including all the pre-existing isolated CPUs. That
will cause latency spikes on those isolated CPUs. That latency spike
should only happen when the cpuset isolated partition setting is changed
resulting in changes in those housekeeping cpumasks.
One possible workaround that is being used right now is to pre-allocate
a set of nohz_full and managed_irq CPUs at boot time. The semi-isolated
CPUs are then used to create cpuset isolated partitions when needed
to enable full isolation. This will likely continue even if we made
the nohz_full and managed_irq CPUs runtime changeable if they can't
tolerate these latency spikes.
This is a problem we need to address in a future patch series.
Signed-off-by: Waiman Long <longman@redhat.com>
---
kernel/cgroup/cpuset.c | 199 +++++++++++++++++++++++++++++++++++++----
1 file changed, 182 insertions(+), 17 deletions(-)
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 1b0c50b46a49..a927b9cd4f71 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -152,9 +152,17 @@ static cpumask_var_t isolated_cpus; /* CSCB */
static bool update_housekeeping; /* RWCS */
/*
- * Copy of isolated_cpus to be passed to housekeeping_update()
+ * Cpumasks to be passed to housekeeping_update()
+ * isolated_hk_cpus - copy of isolated_cpus for HK_TYPE_DOMAIN
+ * isolated_nohz_cpus - for HK_TYPE_KERNEL_NOISE
+ * isolated_mirq_cpus - for HK_TYPE_MANAGED_IRQ
*/
static cpumask_var_t isolated_hk_cpus; /* T */
+static cpumask_var_t isolated_nohz_cpus; /* T */
+static cpumask_var_t isolated_mirq_cpus; /* T */
+
+static bool boot_nohz_le_domain __ro_after_init;
+static bool boot_mirq_le_domain __ro_after_init;
/*
* A flag to force sched domain rebuild at the end of an operation.
@@ -1328,29 +1336,67 @@ static bool prstate_housekeeping_conflict(int prstate, struct cpumask *new_cpus)
return false;
}
+static int cpuset_nohz_update_cbfunc(void *arg)
+{
+ struct cpumask *isol_cpus = (struct cpumask *)arg;
+
+ if (isol_cpus)
+ housekeeping_update(isol_cpus, BIT(HK_TYPE_KERNEL_NOISE));
+ return 0;
+}
+
/*
- * cpuset_update_sd_hk_unlock - Rebuild sched domains, update HK & unlock
- *
- * Update housekeeping cpumasks and rebuild sched domains if necessary and
- * then do a cpuset_full_unlock().
- * This should be called at the end of cpuset operation.
*/
-static void cpuset_update_sd_hk_unlock(void)
- __releases(&cpuset_mutex)
- __releases(&cpuset_top_mutex)
+static void cpuset_update_housekeeping_unlock(void)
{
- update_housekeeping = false;
+ bool update_nohz, update_mirq;
+ cpumask_var_t cpus;
+ int ret;
- /* force_sd_rebuild will be cleared in rebuild_sched_domains_locked() */
- if (force_sd_rebuild)
- rebuild_sched_domains_locked();
+ if (!tick_nohz_full_enabled())
+ return;
- if (cpumask_equal(isolated_hk_cpus, isolated_cpus)) {
- /* No housekeeping cpumask update needed */
+ update_nohz = boot_nohz_le_domain;
+ update_mirq = boot_mirq_le_domain;
+
+ if (WARN_ON_ONCE(!alloc_cpumask_var(&cpus, GFP_KERNEL))) {
cpuset_full_unlock();
return;
}
+ /*
+ * Update isolated_nohz_cpus/isolated_mirq_cpus if necessary
+ */
+ if (!boot_nohz_le_domain) {
+ cpumask_andnot(cpus, cpu_possible_mask,
+ housekeeping_cpumask(HK_TYPE_KERNEL_NOISE));
+ cpumask_or(cpus, cpus, isolated_cpus);
+ update_nohz = !cpumask_equal(isolated_nohz_cpus, cpus);
+ if (update_nohz)
+ cpumask_copy(isolated_nohz_cpus, cpus);
+ }
+ if (!boot_mirq_le_domain) {
+ cpumask_andnot(cpus, cpu_possible_mask,
+ housekeeping_cpumask(HK_TYPE_MANAGED_IRQ));
+ cpumask_or(cpus, cpus, isolated_cpus);
+ update_mirq = !cpumask_equal(isolated_mirq_cpus, cpus);
+ if (update_mirq)
+ cpumask_copy(isolated_mirq_cpus, cpus);
+ }
+
+ /*
+ * Compute list of CPUs to be brought offline into "cpus"
+ * isolated_hk_cpus - old cpumask
+ * isolated_cpus - new cpumask
+ *
+ * With update_nohz, we need to offline both the newly isolated
+ * and de-isolated CPUs. With only update_mirq, we only need to
+ * offline the new isolated CPUs.
+ */
+ if (update_nohz)
+ cpumask_xor(cpus, isolated_hk_cpus, isolated_cpus);
+ else if (update_mirq)
+ cpumask_andnot(cpus, isolated_cpus, isolated_hk_cpus);
cpumask_copy(isolated_hk_cpus, isolated_cpus);
/*
@@ -1360,10 +1406,103 @@ static void cpuset_update_sd_hk_unlock(void)
*/
mutex_unlock(&cpuset_mutex);
cpus_read_unlock();
- WARN_ON_ONCE(housekeeping_update(isolated_hk_cpus, BIT(HK_TYPE_DOMAIN)));
+
+ if (!update_mirq) {
+ ret = housekeeping_update(isolated_hk_cpus, BIT(HK_TYPE_DOMAIN));
+ } else if (boot_mirq_le_domain) {
+ ret = housekeeping_update(isolated_hk_cpus,
+ BIT(HK_TYPE_DOMAIN)|BIT(HK_TYPE_MANAGED_IRQ));
+ } else {
+ ret = housekeeping_update(isolated_hk_cpus, BIT(HK_TYPE_DOMAIN));
+ if (!ret)
+ ret = housekeeping_update(isolated_mirq_cpus,
+ BIT(HK_TYPE_MANAGED_IRQ));
+ }
+
+ if (WARN_ON_ONCE(ret))
+ goto out_free;
+
+ /*
+ * Calling cpuhp_offline_cb() is only needed if either
+ * HK_TYPE_KERNEL_NOISE and/or HK_TYPE_MANAGED_IRQ cpumasks
+ * needed to be updated.
+ *
+ * TODO: When tearing down a CPU from CPUHP_TEARDOWN_CPU state
+ * downward to CPUHP_AP_OFFLINE, the stop_machine code will be
+ * invoked to stop all the other CPUs in the system. This will
+ * cause latency spikes on existing isolated CPUs. We will need
+ * some new mechanism to enable us to not stop the existing
+ * isolated CPUs whenever possible. A possible workaround is
+ * to pre-allocate a set of nohz_full and manged_irq CPUs at
+ * boot time and use them to create isolated cpuset partitions
+ * so that CPU hotplug won't need to be used.
+ */
+ if (update_mirq || update_nohz) {
+ struct cpumask *nohz_cpus;
+
+ /*
+ * Calling housekeeping_update() is only needed if
+ * update_nohz is set.
+ */
+ nohz_cpus = !update_nohz ? NULL : boot_nohz_le_domain
+ ? isolated_hk_cpus
+ : isolated_nohz_cpus;
+ /*
+ * Mask out offline CPUs in cpus
+ * If there is no online CPUs, we can call
+ * housekeeping_update() directly if needed.
+ */
+ cpumask_and(cpus, cpus, cpu_online_mask);
+ if (!cpumask_empty(cpus))
+ ret = cpuhp_offline_cb(cpus, cpuset_nohz_update_cbfunc,
+ nohz_cpus);
+ else if (nohz_cpus)
+ ret = housekeeping_update(nohz_cpus, BIT(HK_TYPE_KERNEL_NOISE));
+ }
+ WARN_ON_ONCE(ret);
+out_free:
+ free_cpumask_var(cpus);
mutex_unlock(&cpuset_top_mutex);
}
+/*
+ * cpuset_update_sd_hk_unlock - Rebuild sched domains, update HK & unlock
+ *
+ * Update housekeeping cpumasks and rebuild sched domains if necessary and
+ * then do a cpuset_full_unlock().
+ * This should be called at the end of cpuset operation.
+ */
+static void cpuset_update_sd_hk_unlock(void)
+ __releases(&cpuset_mutex)
+ __releases(&cpuset_top_mutex)
+{
+ /* force_sd_rebuild will be cleared in rebuild_sched_domains_locked() */
+ if (force_sd_rebuild)
+ rebuild_sched_domains_locked();
+
+ update_housekeeping = false;
+
+ if (cpumask_equal(isolated_cpus, isolated_hk_cpus)) {
+ cpuset_full_unlock();
+ return;
+ }
+
+ if (!tick_nohz_full_enabled()) {
+ /*
+ * housekeeping_update() is now called without holding
+ * cpus_read_lock and cpuset_mutex. Only cpuset_top_mutex
+ * is still being held for mutual exclusion.
+ */
+ mutex_unlock(&cpuset_mutex);
+ cpus_read_unlock();
+ WARN_ON_ONCE(housekeeping_update(isolated_hk_cpus,
+ BIT(HK_TYPE_DOMAIN)));
+ mutex_unlock(&cpuset_top_mutex);
+ } else {
+ cpuset_update_housekeeping_unlock();
+ }
+}
+
/*
* Work function to invoke cpuset_update_sd_hk_unlock()
*/
@@ -3700,6 +3839,29 @@ int __init cpuset_init(void)
housekeeping_cpumask(HK_TYPE_DOMAIN_BOOT));
cpumask_copy(isolated_hk_cpus, isolated_cpus);
}
+
+ /*
+ * If nohz_full and/or managed_irq cpu list, if present, is a subset
+ * of the domain cpu list, i.e. HK_TYPE_DOMAIN_BOOT cpumask is a subset
+ * of HK_TYPE_KERNEL_NOISE_BOOT/HK_TYPE_MANAGED_IRQ_BOOT cpumask, the
+ * corresponding non-boot housekeeping cpumasks will follow changes
+ * in the HK_TYPE_DOMAIN cpumask. So we don't need to use separate
+ * cpumasks to isolate them.
+ */
+ boot_nohz_le_domain = cpumask_subset(housekeeping_cpumask(HK_TYPE_DOMAIN_BOOT),
+ housekeeping_cpumask(HK_TYPE_KERNEL_NOISE_BOOT));
+ boot_mirq_le_domain = cpumask_subset(housekeeping_cpumask(HK_TYPE_DOMAIN_BOOT),
+ housekeeping_cpumask(HK_TYPE_MANAGED_IRQ_BOOT));
+ if (!boot_nohz_le_domain) {
+ BUG_ON(!alloc_cpumask_var(&isolated_nohz_cpus, GFP_KERNEL));
+ cpumask_andnot(isolated_nohz_cpus, cpu_possible_mask,
+ housekeeping_cpumask(HK_TYPE_KERNEL_NOISE));
+ }
+ if (!boot_mirq_le_domain) {
+ BUG_ON(!alloc_cpumask_var(&isolated_mirq_cpus, GFP_KERNEL));
+ cpumask_andnot(isolated_mirq_cpus, cpu_possible_mask,
+ housekeeping_cpumask(HK_TYPE_MANAGED_IRQ));
+ }
return 0;
}
@@ -3954,7 +4116,10 @@ static void cpuset_handle_hotplug(void)
*/
if (force_sd_rebuild)
rebuild_sched_domains_cpuslocked();
- if (update_housekeeping)
+ /*
+ * Don't need to update housekeeping cpumasks in cpuhp_offline_cb mode.
+ */
+ if (update_housekeeping && !cpuhp_offline_cb_mode)
queue_work(system_dfl_wq, &hk_sd_work);
free_tmpmasks(ptmp);
--
2.53.0
^ permalink raw reply related
* [PATCH 19/23] cgroup/cpuset: Improve check for calling housekeeping_update()
From: Waiman Long @ 2026-04-21 3:03 UTC (permalink / raw)
To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>
By making sure that isolated_hk_cpus matches isolated_cpus at boot time,
we can more accurately determine if calling housekeeping_update()
is needed by comparing if the two cpumasks are equal. The
update_housekeeping flag still have a use in cpuset_handle_hotplug()
to determine if a work function should be queued to invoke
cpuset_update_sd_hk_unlock() as it is not supposed to look at
isolated_hk_cpus without holding cpuset_top_mutex.
Signed-off-by: Waiman Long <longman@redhat.com>
---
kernel/cgroup/cpuset.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index a4eccb0ec0d1..1b0c50b46a49 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1339,26 +1339,29 @@ static void cpuset_update_sd_hk_unlock(void)
__releases(&cpuset_mutex)
__releases(&cpuset_top_mutex)
{
+ update_housekeeping = false;
+
/* force_sd_rebuild will be cleared in rebuild_sched_domains_locked() */
if (force_sd_rebuild)
rebuild_sched_domains_locked();
- if (update_housekeeping) {
- update_housekeeping = false;
- cpumask_copy(isolated_hk_cpus, isolated_cpus);
-
- /*
- * housekeeping_update() is now called without holding
- * cpus_read_lock and cpuset_mutex. Only cpuset_top_mutex
- * is still being held for mutual exclusion.
- */
- mutex_unlock(&cpuset_mutex);
- cpus_read_unlock();
- WARN_ON_ONCE(housekeeping_update(isolated_hk_cpus, BIT(HK_TYPE_DOMAIN)));
- mutex_unlock(&cpuset_top_mutex);
- } else {
+ if (cpumask_equal(isolated_hk_cpus, isolated_cpus)) {
+ /* No housekeeping cpumask update needed */
cpuset_full_unlock();
+ return;
}
+
+ cpumask_copy(isolated_hk_cpus, isolated_cpus);
+
+ /*
+ * housekeeping_update() is now called without holding
+ * cpus_read_lock and cpuset_mutex. Only cpuset_top_mutex
+ * is still being held for mutual exclusion.
+ */
+ mutex_unlock(&cpuset_mutex);
+ cpus_read_unlock();
+ WARN_ON_ONCE(housekeeping_update(isolated_hk_cpus, BIT(HK_TYPE_DOMAIN)));
+ mutex_unlock(&cpuset_top_mutex);
}
/*
@@ -3692,10 +3695,11 @@ int __init cpuset_init(void)
BUG_ON(!alloc_cpumask_var(&cpus_attach, GFP_KERNEL));
- if (housekeeping_enabled(HK_TYPE_DOMAIN_BOOT))
+ if (housekeeping_enabled(HK_TYPE_DOMAIN_BOOT)) {
cpumask_andnot(isolated_cpus, cpu_possible_mask,
housekeeping_cpumask(HK_TYPE_DOMAIN_BOOT));
-
+ cpumask_copy(isolated_hk_cpus, isolated_cpus);
+ }
return 0;
}
--
2.53.0
^ permalink raw reply related
* [PATCH 18/23] cpu/hotplug: Add a new cpuhp_offline_cb() API
From: Waiman Long @ 2026-04-21 3:03 UTC (permalink / raw)
To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>
Add a new cpuhp_offline_cb() API that allows us to offline a set of
CPUs one-by-one, run the given callback function and then bring those
CPUs back online again while inhibiting any concurrent CPU hotplug
operations from happening.
This new API can be used to enable runtime adjustment of nohz_full and
isolcpus boot command line options. A new cpuhp_offline_cb_mode flag
is also added to signal that the system is in this offline callback
transient state so that some hotplug operations can be optimized out
if we choose to.
Signed-off-by: Waiman Long <longman@redhat.com>
---
include/linux/cpuhplock.h | 9 +++++
kernel/cpu.c | 70 +++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
diff --git a/include/linux/cpuhplock.h b/include/linux/cpuhplock.h
index 286b3ab92e15..37637baa32eb 100644
--- a/include/linux/cpuhplock.h
+++ b/include/linux/cpuhplock.h
@@ -9,7 +9,9 @@
#include <linux/cleanup.h>
#include <linux/errno.h>
+#include <linux/cpumask_types.h>
+typedef int (*cpuhp_cb_t)(void *arg);
struct device;
extern int lockdep_is_cpus_held(void);
@@ -29,6 +31,8 @@ void clear_tasks_mm_cpumask(int cpu);
int remove_cpu(unsigned int cpu);
int cpu_device_down(struct device *dev);
void smp_shutdown_nonboot_cpus(unsigned int primary_cpu);
+int cpuhp_offline_cb(struct cpumask *mask, cpuhp_cb_t func, void *arg);
+extern bool cpuhp_offline_cb_mode;
#else /* CONFIG_HOTPLUG_CPU */
@@ -43,6 +47,11 @@ static inline void cpu_hotplug_disable(void) { }
static inline void cpu_hotplug_enable(void) { }
static inline int remove_cpu(unsigned int cpu) { return -EPERM; }
static inline void smp_shutdown_nonboot_cpus(unsigned int primary_cpu) { }
+static inline int cpuhp_offline_cb(struct cpumask *mask, cpuhp_cb_t func, void *arg)
+{
+ return -EPERM;
+}
+#define cpuhp_offline_cb_mode false
#endif /* !CONFIG_HOTPLUG_CPU */
DEFINE_LOCK_GUARD_0(cpus_read_lock, cpus_read_lock(), cpus_read_unlock())
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 0d02b5d7a7ba..9b32f742cd1d 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1520,6 +1520,76 @@ int remove_cpu(unsigned int cpu)
}
EXPORT_SYMBOL_GPL(remove_cpu);
+bool cpuhp_offline_cb_mode;
+
+/**
+ * cpuhp_offline_cb - offline CPUs, invoke callback function & online CPUs afterward
+ * @mask: A mask of CPUs to be taken offline and then online
+ * @func: A callback function to be invoked while the given CPUs are offline
+ * @arg: Argument to be passed back to the callback function
+ *
+ * Return: 0 if successful, an error code otherwise
+ */
+int cpuhp_offline_cb(struct cpumask *mask, cpuhp_cb_t func, void *arg)
+{
+ int off_cpu, on_cpu, ret, ret2 = 0;
+
+ if (WARN_ON_ONCE(cpumask_empty(mask) ||
+ !cpumask_subset(mask, cpu_online_mask)))
+ return -EINVAL;
+
+ pr_debug("%s: begin (CPU list = %*pbl)\n", __func__, cpumask_pr_args(mask));
+ lock_device_hotplug();
+ cpuhp_offline_cb_mode = true;
+ /*
+ * If all offline operations succeed, off_cpu should become nr_cpu_ids.
+ */
+ for_each_cpu(off_cpu, mask) {
+ ret = device_offline(get_cpu_device(off_cpu));
+ if (unlikely(ret))
+ break;
+ }
+ if (!ret)
+ ret = func(arg);
+
+ /* Bring previously offline CPUs back online */
+ for_each_cpu(on_cpu, mask) {
+ int retries = 0;
+
+ if (on_cpu == off_cpu)
+ break;
+
+retry:
+ ret2 = device_online(get_cpu_device(on_cpu));
+
+ /*
+ * With the unlikely event that CPU hotplug is disabled while
+ * this operation is in progress, we will need to wait a bit
+ * for hotplug to hopefully be re-enabled again. If not, print
+ * a warning and return the error.
+ *
+ * cpu_hotplug_disabled is supposed to be accessed while
+ * holding the cpu_add_remove_lock mutex. So we need to
+ * use the data_race() macro to access it here.
+ */
+ while ((ret2 == -EBUSY) && data_race(cpu_hotplug_disabled) &&
+ (++retries <= 5)) {
+ msleep(20);
+ if (!data_race(cpu_hotplug_disabled))
+ goto retry;
+ }
+ if (ret2) {
+ pr_warn("%s: Failed to bring CPU %d back online!\n",
+ __func__, on_cpu);
+ break;
+ }
+ }
+ cpuhp_offline_cb_mode = false;
+ unlock_device_hotplug();
+ pr_debug("%s: end\n", __func__);
+ return ret ? ret : ret2;
+}
+
void smp_shutdown_nonboot_cpus(unsigned int primary_cpu)
{
unsigned int cpu;
--
2.53.0
^ permalink raw reply related
* [PATCH 17/23] sched/isolation: Extend housekeeping_dereference_check() to cover changes in nohz_full or manged_irqs cpumasks
From: Waiman Long @ 2026-04-21 3:03 UTC (permalink / raw)
To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>
As we are going to make HK_TYPE_KERNEL_NOISE and
HK_TYPE_MANAGED_IRQ housekeeping cpumasks run time changeable, extend
housekeeping_dereference_check() to cover changes to those cpumasks
as well.
Signed-off-by: Waiman Long <longman@redhat.com>
---
kernel/sched/isolation.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c
index 1f3f1c83dd12..1647e7b08bac 100644
--- a/kernel/sched/isolation.c
+++ b/kernel/sched/isolation.c
@@ -38,7 +38,8 @@ EXPORT_SYMBOL_GPL(housekeeping_enabled);
static bool housekeeping_dereference_check(enum hk_type type)
{
- if (IS_ENABLED(CONFIG_LOCKDEP) && type == HK_TYPE_DOMAIN) {
+ if (IS_ENABLED(CONFIG_LOCKDEP) &&
+ (BIT(type) & (HK_FLAG_DOMAIN | HK_FLAG_KERNEL_NOISE | HK_FLAG_MANAGED_IRQ))) {
/* Cpuset isn't even writable yet? */
if (system_state <= SYSTEM_SCHEDULING)
return true;
--
2.53.0
^ permalink raw reply related
* [PATCH 16/23] genirq/cpuhotplug: Use RCU to protect access of HK_TYPE_MANAGED_IRQ cpumask
From: Waiman Long @ 2026-04-21 3:03 UTC (permalink / raw)
To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>
As HK_TYPE_MANAGED_IRQ cpumask is going to be changeable at run time,
use RCU to protect access to the cpumask.
To enable the new HK_TYPE_MANAGED_IRQ cpumask to take effect, the
following steps can be done.
1) Update the HK_TYPE_MANAGED_IRQ cpumask to take out the newly isolated
CPUs and add back the de-isolated CPUs.
2) Tear down the affected CPUs to cause irq_migrate_all_off_this_cpu()
to be called on the affected CPUs to migrate the irqs to other
HK_TYPE_MANAGED_IRQ housekeeping CPUs.
3) Bring up the previously offline CPUs to invoke
irq_affinity_online_cpu() to allow the newly de-isolated CPUs to
be used for managed irqs.
Signed-off-by: Waiman Long <longman@redhat.com>
---
kernel/irq/cpuhotplug.c | 1 +
kernel/irq/manage.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c
index cd5689e383b0..86437c78f1f2 100644
--- a/kernel/irq/cpuhotplug.c
+++ b/kernel/irq/cpuhotplug.c
@@ -196,6 +196,7 @@ static bool hk_should_isolate(struct irq_data *data, unsigned int cpu)
if (!housekeeping_enabled(HK_TYPE_MANAGED_IRQ))
return false;
+ guard(rcu)();
hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ);
if (cpumask_subset(irq_data_get_effective_affinity_mask(data), hk_mask))
return false;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 2e8072437826..8270c4de260b 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -263,6 +263,7 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, bool
housekeeping_enabled(HK_TYPE_MANAGED_IRQ)) {
const struct cpumask *hk_mask;
+ guard(rcu)();
hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ);
cpumask_and(tmp_mask, mask, hk_mask);
--
2.53.0
^ permalink raw reply related
* [PATCH 15/23] Drivers: hv: Use RCU to protect access of HK_TYPE_MANAGED_IRQ cpumask
From: Waiman Long @ 2026-04-21 3:03 UTC (permalink / raw)
To: Tejun Heo, Johannes Weiner, Michal Koutný, Jonathan Corbet,
Shuah Khan, Catalin Marinas, Will Deacon, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li, Guenter Roeck,
Frederic Weisbecker, Paul E. McKenney, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Boqun Feng, Uladzislau Rezki,
Steven Rostedt, Mathieu Desnoyers, Lai Jiangshan, Zqiang,
Anna-Maria Behnsen, Ingo Molnar, Thomas Gleixner, Chen Ridong,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan, Waiman Long
In-Reply-To: <20260421030351.281436-1-longman@redhat.com>
As HK_TYPE_MANAGED_IRQ cpumask is going to be changeable at run time,
use RCU to protect access to the cpumask. The memory allocation
alloc_cpumask_var() call is done before taking the rcu_read_lock()
as this call can be sleepable.
Signed-off-by: Waiman Long <longman@redhat.com>
---
drivers/hv/channel_mgmt.c | 15 +++++++++------
drivers/hv/vmbus_drv.c | 7 +++++--
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 84eb0a6a0b54..44441dafed90 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -752,13 +752,16 @@ static void init_vp_index(struct vmbus_channel *channel)
u32 i, ncpu = num_online_cpus();
cpumask_var_t available_mask;
struct cpumask *allocated_mask;
- const struct cpumask *hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ);
+ const struct cpumask *hk_mask;
u32 target_cpu;
int numa_node;
+ bool alloc_ok;
- if (!perf_chn ||
- !alloc_cpumask_var(&available_mask, GFP_KERNEL) ||
- cpumask_empty(hk_mask)) {
+ alloc_ok = alloc_cpumask_var(&available_mask, GFP_KERNEL);
+ guard(rcu)();
+ hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ);
+
+ if (!perf_chn || !alloc_ok || cpumask_empty(hk_mask)) {
/*
* If the channel is not a performance critical
* channel, bind it to VMBUS_CONNECT_CPU.
@@ -770,7 +773,7 @@ static void init_vp_index(struct vmbus_channel *channel)
channel->target_cpu = VMBUS_CONNECT_CPU;
if (perf_chn)
hv_set_allocated_cpu(VMBUS_CONNECT_CPU);
- return;
+ goto out_free;
}
for (i = 1; i <= ncpu + 1; i++) {
@@ -808,7 +811,7 @@ static void init_vp_index(struct vmbus_channel *channel)
}
channel->target_cpu = target_cpu;
-
+out_free:
free_cpumask_var(available_mask);
}
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 3faa74e49a6b..60c7a5ac15c0 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1763,8 +1763,11 @@ int vmbus_channel_set_cpu(struct vmbus_channel *channel, u32 target_cpu)
if (target_cpu >= nr_cpumask_bits)
return -EINVAL;
- if (!cpumask_test_cpu(target_cpu, housekeeping_cpumask(HK_TYPE_MANAGED_IRQ)))
- return -EINVAL;
+ scoped_guard(rcu) {
+ if (!cpumask_test_cpu(target_cpu,
+ housekeeping_cpumask(HK_TYPE_MANAGED_IRQ)))
+ return -EINVAL;
+ }
if (!cpu_online(target_cpu))
return -EINVAL;
--
2.53.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox