public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Question about num_possible_cpus() and cpu_possible_mask
@ 2024-09-25  4:04 Michael Kelley
  2024-09-30  7:56 ` Peter Zijlstra
  2024-09-30  9:16 ` Mark Rutland
  0 siblings, 2 replies; 5+ messages in thread
From: Michael Kelley @ 2024-09-25  4:04 UTC (permalink / raw)
  To: Thomas Gleixner, peterz@infradead.org, Borislav Petkov,
	Yury Norov
  Cc: x86@kernel.org, linux-kernel@vger.kernel.org

Question:  Is there any intention to guarantee that the cpu_possible_mask is
"dense", in that all bit positions 0 thru (nr_cpu_ids - 1) are set, with no
"holes"? If that were true, then num_possible_cpus() would be equal to
nr_cpu_ids.

x86 always sets up cpu_possible_mask as dense, as does ARM64 with ACPI.
But it appears there are errors cases on ARM64 with DeviceTree where this
is not the case. I haven't looked at other architectures.

There's evidence both ways:
1) A somewhat recent report[1] on SPARC where cpu_possible_mask
   isn't dense, and there's code assuming that it is dense. This report
   got me thinking about the question.
  
2) setup_nr_cpu_ids() in kernel/smp.c is coded to *not* assume it is dense

3) But there are several places throughout the kernel that do something like
   the following, which assumes they are dense:

	array = kcalloc(num_possible_cpus(), sizeof(<some struct>), GFP_KERNEL);
	....
	index into "array" with smp_processor_id()

On balance, I'm assuming that there's no requirement for cpu_possible_mask
to be dense, and code like #3 above is technically wrong. It should be
using nr_cpu_ids instead of num_possible_cpus(), which is also faster.
We get away with it 99.99% of the time because all (or almost all?)
architectures populate cpu_possible_mask as dense.

There are 6 places in Hyper-V specific code that do #3. And it works because
Hyper-V code only runs on x86 and ARM64 where cpu_possible_mask is
always dense. But in the interest of correctness and robustness against
future changes, I'm planning to fix the Hyper-V code.

There are also a few other places throughout the kernel with the same
problem, and I may look at fixing those as well.

Or maybe my assumptions are off-base. Any thoughts or guidance before
I start submitting patches?

Thanks,

Michael

[1] https://lore.kernel.org/lkml/20240621033005.6mccm7waduelb4m5@oppo.com/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Question about num_possible_cpus() and cpu_possible_mask
  2024-09-25  4:04 Question about num_possible_cpus() and cpu_possible_mask Michael Kelley
@ 2024-09-30  7:56 ` Peter Zijlstra
  2024-09-30  9:06   ` Thomas Gleixner
  2024-09-30 19:33   ` Michael Kelley
  2024-09-30  9:16 ` Mark Rutland
  1 sibling, 2 replies; 5+ messages in thread
From: Peter Zijlstra @ 2024-09-30  7:56 UTC (permalink / raw)
  To: Michael Kelley
  Cc: Thomas Gleixner, Borislav Petkov, Yury Norov, x86@kernel.org,
	linux-kernel@vger.kernel.org

On Wed, Sep 25, 2024 at 04:04:33AM +0000, Michael Kelley wrote:
> Question:  Is there any intention to guarantee that the cpu_possible_mask is
> "dense", in that all bit positions 0 thru (nr_cpu_ids - 1) are set, with no
> "holes"? If that were true, then num_possible_cpus() would be equal to
> nr_cpu_ids.

I think we've historically had machines where there were holes in. And I
think we're wanting to have holes in for modern hybrid x86 that have HT,
although I'm not entirely sure where those patches are atm.

Thomas, didn't we have a patch that renumbers CPUs for hybrid crud sich
that HT is always the low bit and we end up with holes because the atoms
don't have HT on?

Or was that on my plate and it got lost in the giant todo pile?

> x86 always sets up cpu_possible_mask as dense, as does ARM64 with ACPI.
> But it appears there are errors cases on ARM64 with DeviceTree where this
> is not the case. I haven't looked at other architectures.
> 
> There's evidence both ways:
> 1) A somewhat recent report[1] on SPARC where cpu_possible_mask
>    isn't dense, and there's code assuming that it is dense. This report
>    got me thinking about the question.
>   
> 2) setup_nr_cpu_ids() in kernel/smp.c is coded to *not* assume it is dense
> 
> 3) But there are several places throughout the kernel that do something like
>    the following, which assumes they are dense:
> 
> 	array = kcalloc(num_possible_cpus(), sizeof(<some struct>), GFP_KERNEL);
> 	....
> 	index into "array" with smp_processor_id()

I would consider this pattern broken.

> On balance, I'm assuming that there's no requirement for cpu_possible_mask
> to be dense, and code like #3 above is technically wrong. It should be
> using nr_cpu_ids instead of num_possible_cpus(), which is also faster.
> We get away with it 99.99% of the time because all (or almost all?)
> architectures populate cpu_possible_mask as dense.
> 
> There are 6 places in Hyper-V specific code that do #3. And it works because
> Hyper-V code only runs on x86 and ARM64 where cpu_possible_mask is
> always dense. But in the interest of correctness and robustness against
> future changes, I'm planning to fix the Hyper-V code.
> 
> There are also a few other places throughout the kernel with the same
> problem, and I may look at fixing those as well.
> 
> Or maybe my assumptions are off-base. Any thoughts or guidance before
> I start submitting patches?

You're on the right track, should not assume the mask is dense.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Question about num_possible_cpus() and cpu_possible_mask
  2024-09-30  7:56 ` Peter Zijlstra
@ 2024-09-30  9:06   ` Thomas Gleixner
  2024-09-30 19:33   ` Michael Kelley
  1 sibling, 0 replies; 5+ messages in thread
From: Thomas Gleixner @ 2024-09-30  9:06 UTC (permalink / raw)
  To: Peter Zijlstra, Michael Kelley
  Cc: Borislav Petkov, Yury Norov, x86@kernel.org,
	linux-kernel@vger.kernel.org

On Mon, Sep 30 2024 at 09:56, Peter Zijlstra wrote:
> On Wed, Sep 25, 2024 at 04:04:33AM +0000, Michael Kelley wrote:
>> Question:  Is there any intention to guarantee that the cpu_possible_mask is
>> "dense", in that all bit positions 0 thru (nr_cpu_ids - 1) are set, with no
>> "holes"? If that were true, then num_possible_cpus() would be equal to
>> nr_cpu_ids.
>
> I think we've historically had machines where there were holes in. And I
> think we're wanting to have holes in for modern hybrid x86 that have HT,
> although I'm not entirely sure where those patches are atm.
>
> Thomas, didn't we have a patch that renumbers CPUs for hybrid crud sich
> that HT is always the low bit and we end up with holes because the atoms
> don't have HT on?
>
> Or was that on my plate and it got lost in the giant todo pile?

We talked about it some time ago, but that went nowhere.

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Question about num_possible_cpus() and cpu_possible_mask
  2024-09-25  4:04 Question about num_possible_cpus() and cpu_possible_mask Michael Kelley
  2024-09-30  7:56 ` Peter Zijlstra
@ 2024-09-30  9:16 ` Mark Rutland
  1 sibling, 0 replies; 5+ messages in thread
From: Mark Rutland @ 2024-09-30  9:16 UTC (permalink / raw)
  To: Michael Kelley
  Cc: Thomas Gleixner, peterz@infradead.org, Borislav Petkov,
	Yury Norov, x86@kernel.org, linux-kernel@vger.kernel.org

On Wed, Sep 25, 2024 at 04:04:33AM +0000, Michael Kelley wrote:
> Question:  Is there any intention to guarantee that the cpu_possible_mask is
> "dense", in that all bit positions 0 thru (nr_cpu_ids - 1) are set, with no
> "holes"? If that were true, then num_possible_cpus() would be equal to
> nr_cpu_ids.
> 
> x86 always sets up cpu_possible_mask as dense, as does ARM64 with ACPI.
> But it appears there are errors cases on ARM64 with DeviceTree where this
> is not the case. I haven't looked at other architectures.
> 
> There's evidence both ways:
> 1) A somewhat recent report[1] on SPARC where cpu_possible_mask
>    isn't dense, and there's code assuming that it is dense. This report
>    got me thinking about the question.
>   
> 2) setup_nr_cpu_ids() in kernel/smp.c is coded to *not* assume it is dense
> 
> 3) But there are several places throughout the kernel that do something like
>    the following, which assumes they are dense:
> 
> 	array = kcalloc(num_possible_cpus(), sizeof(<some struct>), GFP_KERNEL);
> 	....
> 	index into "array" with smp_processor_id()
> 
> On balance, I'm assuming that there's no requirement for cpu_possible_mask
> to be dense, and code like #3 above is technically wrong. It should be
> using nr_cpu_ids instead of num_possible_cpus(), which is also faster.
> We get away with it 99.99% of the time because all (or almost all?)
> architectures populate cpu_possible_mask as dense.
> 
> There are 6 places in Hyper-V specific code that do #3. And it works because
> Hyper-V code only runs on x86 and ARM64 where cpu_possible_mask is
> always dense.

Maybe that happens be be true under Hyper-V, but in general
cpu_possible_mask is not always dense on arm64, and we've had the change
core code to handle that in the past, e.g.

  bc75e99983df1efd ("rcu: Correctly handle sparse possible cpu")

> But in the interest of correctness and robustness against
> future changes, I'm planning to fix the Hyper-V code.

To me, that sounds like the right thing to do.

Mark.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: Question about num_possible_cpus() and cpu_possible_mask
  2024-09-30  7:56 ` Peter Zijlstra
  2024-09-30  9:06   ` Thomas Gleixner
@ 2024-09-30 19:33   ` Michael Kelley
  1 sibling, 0 replies; 5+ messages in thread
From: Michael Kelley @ 2024-09-30 19:33 UTC (permalink / raw)
  To: Peter Zijlstra, Mark Rutland
  Cc: Thomas Gleixner, Borislav Petkov, Yury Norov, x86@kernel.org,
	linux-kernel@vger.kernel.org

From: Peter Zijlstra <peterz@infradead.org> Sent: Monday, September 30, 2024 12:56 AM
> 
> On Wed, Sep 25, 2024 at 04:04:33AM +0000, Michael Kelley wrote:
> > Question:  Is there any intention to guarantee that the cpu_possible_mask is
> > "dense", in that all bit positions 0 thru (nr_cpu_ids - 1) are set, with no
> > "holes"? If that were true, then num_possible_cpus() would be equal to
> > nr_cpu_ids.
> 
> I think we've historically had machines where there were holes in. And I
> think we're wanting to have holes in for modern hybrid x86 that have HT,
> although I'm not entirely sure where those patches are atm.
> 
> Thomas, didn't we have a patch that renumbers CPUs for hybrid crud sich
> that HT is always the low bit and we end up with holes because the atoms
> don't have HT on?
> 
> Or was that on my plate and it got lost in the giant todo pile?
> 
> > x86 always sets up cpu_possible_mask as dense, as does ARM64 with ACPI.
> > But it appears there are errors cases on ARM64 with DeviceTree where this
> > is not the case. I haven't looked at other architectures.
> >
> > There's evidence both ways:
> > 1) A somewhat recent report[1] on SPARC where cpu_possible_mask
> >    isn't dense, and there's code assuming that it is dense. This report
> >    got me thinking about the question.
> >
> > 2) setup_nr_cpu_ids() in kernel/smp.c is coded to *not* assume it is dense
> >
> > 3) But there are several places throughout the kernel that do something like
> >    the following, which assumes they are dense:
> >
> > 	array = kcalloc(num_possible_cpus(), sizeof(<some struct>), GFP_KERNEL);
> > 	....
> > 	index into "array" with smp_processor_id()
> 
> I would consider this pattern broken.
> 
> > On balance, I'm assuming that there's no requirement for cpu_possible_mask
> > to be dense, and code like #3 above is technically wrong. It should be
> > using nr_cpu_ids instead of num_possible_cpus(), which is also faster.
> > We get away with it 99.99% of the time because all (or almost all?)
> > architectures populate cpu_possible_mask as dense.
> >
> > There are 6 places in Hyper-V specific code that do #3. And it works because
> > Hyper-V code only runs on x86 and ARM64 where cpu_possible_mask is
> > always dense. But in the interest of correctness and robustness against
> > future changes, I'm planning to fix the Hyper-V code.
> >
> > There are also a few other places throughout the kernel with the same
> > problem, and I may look at fixing those as well.
> >
> > Or maybe my assumptions are off-base. Any thoughts or guidance before
> > I start submitting patches?
> 
> You're on the right track, should not assume the mask is dense.

Thanks Peter and Mark for your confirmation. I'll work on some patches.

Michael

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-09-30 19:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-25  4:04 Question about num_possible_cpus() and cpu_possible_mask Michael Kelley
2024-09-30  7:56 ` Peter Zijlstra
2024-09-30  9:06   ` Thomas Gleixner
2024-09-30 19:33   ` Michael Kelley
2024-09-30  9:16 ` Mark Rutland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox