From: Waiman Long <[email protected]> Sent: Friday, August 28, 2026 6:22 PM
> 
> On 8/27/26 5:10 PM, Michael Kelley wrote:
> > From: Waiman Long <[email protected]> Sent: Thursday, August 27, 2026 
> > 12:38 PM
> >> There is a retry loop in init_vp_index() where the CPUs from a certain
> >> node are stripped out if they have already been in the allocated cpumask
> >> or not in HK_TYPE_MANAGED_IRQ housekeeping cpumask. If there is no
> >> CPU left, the allocated cpumask is ignored and the process is retried
> >> again. However, if the HK_TYPE_MANAGED_IRQ housekeeping cpumask turns
> >> out not to contain any CPU in that particular node, that will become an
> >> infinite retry loop.  This particular problem was reported by sashiko
> >> [1]. This should rarely happen, but we still need to guard against this.
> >>
> >> Fix this infinite loop problem by also skipping NUMA node that has no
> >> housekeeping CPU in the inner while loop of init_vp_index(). As the outer
> >> for loop will only be reached if the housekeeping cpumask isn't empty,
> >> a NUMA node with housekeeping CPUs will eventually be found.
> >>
> >> Link: 
> >> https://sashiko.dev/#/message/20260422030903.E1BFCC2BCB0%40smtp.kernel.org 
> >> [1]
> >> Fixes: 6640b5df1a38 ("Drivers: hv: vmbus: Don't assign VMbus channel 
> >> interrupts to isolated CPUs")
> >> Signed-off-by: Waiman Long <[email protected]>
> >> ---
> >>   drivers/hv/channel_mgmt.c | 7 +++++--
> >>   1 file changed, 5 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
> >> index 89d214dda360..ed121d74d73f 100644
> >> --- a/drivers/hv/channel_mgmt.c
> >> +++ b/drivers/hv/channel_mgmt.c
> >> @@ -752,6 +752,7 @@ 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 *node_mask;
> >>    const struct cpumask *hk_mask = 
> >> housekeeping_cpumask(HK_TYPE_MANAGED_IRQ);
> >>    u32 target_cpu;
> >>    int numa_node;
> >> @@ -780,14 +781,16 @@ static void init_vp_index(struct vmbus_channel 
> >> *channel)
> >>                            next_numa_node_id = 0;
> >>                            continue;
> >>                    }
> >> -                  if (cpumask_empty(cpumask_of_node(numa_node)))
> >> +                  node_mask = cpumask_of_node(numa_node);
> >> +                  if (cpumask_empty(node_mask) ||
> >> +                      !cpumask_intersects(node_mask, hk_mask))
> > The cpumask_empty() test looks to be redundant. The
> > cpumask_intersects() test will catch the case where
> > node_mask is empty.
> >
> > Otherwise, I think this looks good as a solution to the core
> > problem.
> >
> > Michael
> 
> Yes, I am aware that cpumask_empty() test is redundant and can be
> skipped. I keep it just to make it easier to read. I can certainly drop
> the cpumask_empty() statement.
> 

The flip side is people like me try to figure out "why is this
here?", thinking there must be a reason. :-)  I'd say drop the
code and add a comment like "Also catches an empty node_mask".

Michael

Reply via email to