From: Roman 'Hedin' Storozhenko <romeusmeister@gmail.com>
To: "H. Peter Anvin" <hpa@zytor.com>,
Thomas Gleixner <tglx@kernel.org>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org
Cc: linux-kernel@vger.kernel.org,
Roman 'Hedin' Storozhenko <romeusmeister@gmail.com>
Subject: [PATCH] x86/msr: Use num_possible_cpus() for chrdev minor count
Date: Wed, 01 Apr 2026 20:55:43 +0200 [thread overview]
Message-ID: <20260401-msr_cpu-v1-1-d8016f61d455@gmail.com> (raw)
The MSR driver currently register their character device
regions using NR_CPUS as the minor count:
__register_chrdev(..., 0, NR_CPUS, ...)
This dates back to commit 0b962d473af3 ("x86, msr/cpuid: Register
enough minors for the MSR and CPUID drivers"), which intentionally
used NR_CPUS as a static upper bound on the maximum CPU index.
However, NR_CPUS is a compile-time upper bound and may significantly
exceed the actual number of CPUs supported by the running system
(i.e. cpu_possible_mask). As a result, the drivers may reserve a much
larger minor range than can ever be used at runtime.
Replace NR_CPUS with num_possible_cpus() so that the registered minor
range reflects the actual system topology instead of a static maximum.
The driver already creates and destroy devices dynamically based on
CPU hotplug state, so this change only affects the size of the
internally reserved minor range and does not alter runtime behavior
or userspace-visible interfaces.
Signed-off-by: Roman 'Hedin' Storozhenko <romeusmeister@gmail.com>
---
This series replaces NR_CPUS with num_possible_cpus() when registering
character device regions for the MSR and CPUID drivers.
Historically, commit 0b962d473af3 ("x86, msr/cpuid: Register enough minors
for the MSR and CPUID drivers") switched to using NR_CPUS as a static upper
bound on the maximum CPU index. While correct, this may result in reserving
a significantly larger minor range than is actually usable on a given system.
This series updates the drivers to use num_possible_cpus(), aligning the
registered minor range with the system’s CPU topology.
The change does not affect runtime behavior: devices are still created and
destroyed dynamically based on CPU hotplug state.
Validation
----------
The change was validated in a virtme-ng environment with:
CONFIG_NR_CPUS=64
possible CPUs: 0-7 (8 CPUs)
1) Internal state (eBPF)
Using bpftrace on __register_chrdev_region():
Before:
count = 64
After:
count = 8
This confirms that the registered minor range now reflects
num_possible_cpus() instead of NR_CPUS.
2) Userspace-visible behavior
No change observed:
/dev/cpu/*/msr count: unchanged (8)
/sys/class/msr entries: unchanged (8)
3) Functional correctness
rdmsr access continues to work as expected.
4) CPU hotplug
Tracing msr_device_create shows identical behavior before and after,
confirming that device lifecycle remains driven by CPU hotplug events.
----------
Overall, this change reduces over-allocation of minor numbers while
preserving existing behavior and interfaces.
---
arch/x86/kernel/msr.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 4469c784eaa0..7f93f59d3cd9 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -263,7 +263,7 @@ static int __init msr_init(void)
{
int err;
- if (__register_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr", &msr_fops)) {
+ if (__register_chrdev(MSR_MAJOR, 0, num_possible_cpus(), "cpu/msr", &msr_fops)) {
pr_err("unable to get major %d for msr\n", MSR_MAJOR);
return -EBUSY;
}
@@ -281,7 +281,7 @@ static int __init msr_init(void)
out_class:
class_unregister(&msr_class);
out_chrdev:
- __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
+ __unregister_chrdev(MSR_MAJOR, 0, num_possible_cpus(), "cpu/msr");
return err;
}
module_init(msr_init);
@@ -290,7 +290,7 @@ static void __exit msr_exit(void)
{
cpuhp_remove_state(cpuhp_msr_state);
class_unregister(&msr_class);
- __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
+ __unregister_chrdev(MSR_MAJOR, 0, num_possible_cpus(), "cpu/msr");
}
module_exit(msr_exit)
---
base-commit: 25f9333c7244d9c5a0243bcf045903ba19635d35
change-id: 20260401-msr_cpu-d88ade162ca0
Best regards,
--
Roman 'Hedin' Storozhenko <romeusmeister@gmail.com>
next reply other threads:[~2026-04-01 18:56 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-01 18:55 Roman 'Hedin' Storozhenko [this message]
2026-04-01 19:24 ` Michael Kelley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260401-msr_cpu-v1-1-d8016f61d455@gmail.com \
--to=romeusmeister@gmail.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=tglx@kernel.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®