Skip to content

Commit 6640b5d

Browse files
Saurabh Sengarliuw
authored andcommitted
Drivers: hv: vmbus: Don't assign VMbus channel interrupts to isolated CPUs
When initially assigning a VMbus channel interrupt to a CPU, don’t choose a managed IRQ isolated CPU (as specified on the kernel boot line with parameter 'isolcpus=managed_irq,<#cpu>'). Also, when using sysfs to change the CPU that a VMbus channel will interrupt, don't allow changing to a managed IRQ isolated CPU. Signed-off-by: Saurabh Sengar <[email protected]> Reviewed-by: Michael Kelley <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Wei Liu <[email protected]>
1 parent f2906aa commit 6640b5d

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

drivers/hv/channel_mgmt.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/cpu.h>
2222
#include <linux/hyperv.h>
2323
#include <asm/mshyperv.h>
24+
#include <linux/sched/isolation.h>
2425

2526
#include "hyperv_vmbus.h"
2627

@@ -728,16 +729,20 @@ static void init_vp_index(struct vmbus_channel *channel)
728729
u32 i, ncpu = num_online_cpus();
729730
cpumask_var_t available_mask;
730731
struct cpumask *allocated_mask;
732+
const struct cpumask *hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ);
731733
u32 target_cpu;
732734
int numa_node;
733735

734736
if (!perf_chn ||
735-
!alloc_cpumask_var(&available_mask, GFP_KERNEL)) {
737+
!alloc_cpumask_var(&available_mask, GFP_KERNEL) ||
738+
cpumask_empty(hk_mask)) {
736739
/*
737740
* If the channel is not a performance critical
738741
* channel, bind it to VMBUS_CONNECT_CPU.
739742
* In case alloc_cpumask_var() fails, bind it to
740743
* VMBUS_CONNECT_CPU.
744+
* If all the cpus are isolated, bind it to
745+
* VMBUS_CONNECT_CPU.
741746
*/
742747
channel->target_cpu = VMBUS_CONNECT_CPU;
743748
if (perf_chn)
@@ -758,17 +763,19 @@ static void init_vp_index(struct vmbus_channel *channel)
758763
}
759764
allocated_mask = &hv_context.hv_numa_map[numa_node];
760765

761-
if (cpumask_equal(allocated_mask, cpumask_of_node(numa_node))) {
766+
retry:
767+
cpumask_xor(available_mask, allocated_mask, cpumask_of_node(numa_node));
768+
cpumask_and(available_mask, available_mask, hk_mask);
769+
770+
if (cpumask_empty(available_mask)) {
762771
/*
763772
* We have cycled through all the CPUs in the node;
764773
* reset the allocated map.
765774
*/
766775
cpumask_clear(allocated_mask);
776+
goto retry;
767777
}
768778

769-
cpumask_xor(available_mask, allocated_mask,
770-
cpumask_of_node(numa_node));
771-
772779
target_cpu = cpumask_first(available_mask);
773780
cpumask_set_cpu(target_cpu, allocated_mask);
774781

drivers/hv/vmbus_drv.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/kernel_stat.h>
2222
#include <linux/clockchips.h>
2323
#include <linux/cpu.h>
24+
#include <linux/sched/isolation.h>
2425
#include <linux/sched/task_stack.h>
2526

2627
#include <linux/delay.h>
@@ -1770,6 +1771,9 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel,
17701771
if (target_cpu >= nr_cpumask_bits)
17711772
return -EINVAL;
17721773

1774+
if (!cpumask_test_cpu(target_cpu, housekeeping_cpumask(HK_TYPE_MANAGED_IRQ)))
1775+
return -EINVAL;
1776+
17731777
/* No CPUs should come up or down during this. */
17741778
cpus_read_lock();
17751779

0 commit comments

Comments
 (0)