From 2f03e6e3d823d7381ac7c2b3d076f20d1978d5a1 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 29 Jan 2018 18:02:49 -0500 Subject: [PATCH] RH7: add optional vmbus parameter for HT when assigning CPU to channel By default, in RH7 code, vmbus will assign CPUs to channels by considering the CPU hyper-threading. Now, add a kernel parameter to disable it: "hv_vmbus.affinity_mode=0" --- hv-rhel7.x/hv/channel_mgmt.c | 34 +++++++++++++++------------- hv-rhel7.x/hv/hyperv_vmbus.h | 2 ++ hv-rhel7.x/hv/include/linux/hyperv.h | 5 ++++ hv-rhel7.x/hv/vmbus_drv.c | 5 ++++ 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/hv-rhel7.x/hv/channel_mgmt.c b/hv-rhel7.x/hv/channel_mgmt.c index 5fa49b320..a6c69d102 100644 --- a/hv-rhel7.x/hv/channel_mgmt.c +++ b/hv-rhel7.x/hv/channel_mgmt.c @@ -712,22 +712,24 @@ static void init_vp_index(struct vmbus_channel *channel, u16 dev_type) continue; } -#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)) - cpu_sibling_mask = topology_sibling_cpumask(cur_cpu); - cpumask_and(cpu_thread_tmp_mask, - cpu_sibling_mask, - &available_mask); - if (!cpumask_equal(cpu_thread_tmp_mask, cpu_sibling_mask)) { - /* - * NOTE: The thread sibling of this CPU has been - * assigned to a channel. - * We do not assign both Hyper-Threading CPUs of - * the same physical core to vmbus channels. - * So, mark this CPU as occupied too then move to - * next one and try. - */ - cpumask_set_cpu(cur_cpu, alloced_mask); - continue; +#if (RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3)) + if (affinity_mode == HV_SKIP_HT_CPU) { + cpu_sibling_mask = topology_sibling_cpumask(cur_cpu); + cpumask_and(cpu_thread_tmp_mask, + cpu_sibling_mask, + &available_mask); + if (!cpumask_equal(cpu_thread_tmp_mask, cpu_sibling_mask)) { + /* + * NOTE: The thread sibling of this CPU has been + * assigned to a channel. + * We do not assign both Hyper-Threading CPUs of + * the same physical core to vmbus channels. + * So, mark this CPU as occupied too then move to + * next one and try. + */ + cpumask_set_cpu(cur_cpu, alloced_mask); + continue; + } } #endif diff --git a/hv-rhel7.x/hv/hyperv_vmbus.h b/hv-rhel7.x/hv/hyperv_vmbus.h index a945b8194..fae02f70e 100644 --- a/hv-rhel7.x/hv/hyperv_vmbus.h +++ b/hv-rhel7.x/hv/hyperv_vmbus.h @@ -242,6 +242,8 @@ struct hv_context { extern struct hv_context hv_context; +extern int affinity_mode; + /* Hv Interface */ extern int hv_init(void); diff --git a/hv-rhel7.x/hv/include/linux/hyperv.h b/hv-rhel7.x/hv/include/linux/hyperv.h index 79fa1c951..c00ce51b4 100644 --- a/hv-rhel7.x/hv/include/linux/hyperv.h +++ b/hv-rhel7.x/hv/include/linux/hyperv.h @@ -667,6 +667,11 @@ enum hv_numa_policy { HV_LOCALIZED, }; +enum hv_channel_affinity_mode { + HV_KEEP_HT_CPU = 0, + HV_SKIP_HT_CPU, +}; + enum vmbus_device_type { HV_IDE = 0, HV_SCSI, diff --git a/hv-rhel7.x/hv/vmbus_drv.c b/hv-rhel7.x/hv/vmbus_drv.c index e570e0626..29bf51fbd 100644 --- a/hv-rhel7.x/hv/vmbus_drv.c +++ b/hv-rhel7.x/hv/vmbus_drv.c @@ -48,6 +48,10 @@ static struct acpi_device *hv_acpi_dev; +int affinity_mode = 1; +module_param(affinity_mode, int, S_IRUGO); +MODULE_PARM_DESC(affinity_mode, "vmbus channel cpu affinity mode: 0, 1"); + static struct completion probe_event; #if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,2)) static int irq; @@ -1838,6 +1842,7 @@ static int __init hv_acpi_init(void) hv_setup_crash_handler(hv_crash_handler); #endif + pr_info("vmbus channel cpu affinity mode: %d\n", affinity_mode); return 0; cleanup: