Re: [PATCH v5 07/10] hyper-v: globalize vp_index

2017-05-30 Thread Andy Shevchenko
On Tue, May 30, 2017 at 2:34 PM, Vitaly Kuznetsov  wrote:
> To support implementing remote TLB flushing on Hyper-V with a hypercall
> we need to make vp_index available outside of vmbus module. Rename and
> globalize.

> +u32 *hv_vp_index;

> +   hv_vp_index[smp_processor_id()] = (u32)msr_vp_index;

Redundant casting.

> +   /* Allocate percpu VP index */
> +   hv_vp_index = kcalloc(num_possible_cpus(), sizeof(*hv_vp_index),
> + GFP_KERNEL);
> +   if (!hv_vp_index)
> +   return;

Consider to use kmalloc_array _if_ it doesn't require to be zeroed.

> +static inline int hv_cpu_number_to_vp_number(int cpu_number)
> +{

> +   WARN_ON(hv_vp_index[cpu_number] == -1);

How come? u32 will be never negative.

Perhaps you meant == ~0U or U32_MAX

> for_each_cpu_and(cpu, dest, cpu_online_mask)
> -   params->vp_mask |= (1ULL << 
> vmbus_cpu_number_to_vp_number(cpu));
> +   params->vp_mask |= (1ULL << hv_cpu_number_to_vp_number(cpu));

__set_bit() ?

> for_each_cpu_and(cpu, affinity, cpu_online_mask) {
> int_pkt->int_desc.cpu_mask |=
> -   (1ULL << vmbus_cpu_number_to_vp_number(cpu));
> +   (1ULL << hv_cpu_number_to_vp_number(cpu));

Ditto.

-- 
With Best Regards,
Andy Shevchenko
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 07/10] hyper-v: globalize vp_index

2017-05-30 Thread Vitaly Kuznetsov
To support implementing remote TLB flushing on Hyper-V with a hypercall
we need to make vp_index available outside of vmbus module. Rename and
globalize.

Signed-off-by: Vitaly Kuznetsov 
Acked-by: K. Y. Srinivasan 
Tested-by: Simon Xiao 
Tested-by: Srikanth Myakam 
---
 arch/x86/hyperv/hv_init.c   | 34 +-
 arch/x86/include/asm/mshyperv.h | 26 ++
 drivers/hv/channel_mgmt.c   |  7 +++
 drivers/hv/connection.c |  3 ++-
 drivers/hv/hv.c |  9 -
 drivers/hv/hyperv_vmbus.h   | 11 ---
 drivers/hv/vmbus_drv.c  | 17 -
 drivers/pci/host/pci-hyperv.c   |  4 ++--
 include/linux/hyperv.h  |  1 -
 9 files changed, 66 insertions(+), 46 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 691603e..7fd9cd3 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -26,6 +26,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #ifdef CONFIG_HYPERV_TSCPAGE
 
@@ -80,6 +82,20 @@ EXPORT_SYMBOL_GPL(hv_hypercall_pg);
 struct clocksource *hyperv_cs;
 EXPORT_SYMBOL_GPL(hyperv_cs);
 
+u32 *hv_vp_index;
+EXPORT_SYMBOL_GPL(hv_vp_index);
+
+static int hv_cpu_init(unsigned int cpu)
+{
+   u64 msr_vp_index;
+
+   hv_get_vp_index(msr_vp_index);
+
+   hv_vp_index[smp_processor_id()] = (u32)msr_vp_index;
+
+   return 0;
+}
+
 /*
  * This function is to be invoked early in the boot sequence after the
  * hypervisor has been detected.
@@ -95,6 +111,16 @@ void hyperv_init(void)
if (x86_hyper != _hyper_ms_hyperv)
return;
 
+   /* Allocate percpu VP index */
+   hv_vp_index = kcalloc(num_possible_cpus(), sizeof(*hv_vp_index),
+ GFP_KERNEL);
+   if (!hv_vp_index)
+   return;
+
+   if (cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/hyperv_init:online",
+ hv_cpu_init, NULL) < 0)
+   goto free_vp_index;
+
/*
 * Setup the hypercall page and enable hypercalls.
 * 1. Register the guest ID
@@ -106,7 +132,7 @@ void hyperv_init(void)
hv_hypercall_pg  = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX);
if (hv_hypercall_pg == NULL) {
wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
-   return;
+   goto free_vp_index;
}
 
rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
@@ -149,6 +175,12 @@ void hyperv_init(void)
hyperv_cs = _cs_msr;
if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
clocksource_register_hz(_cs_msr, NSEC_PER_SEC/100);
+
+   return;
+
+free_vp_index:
+   kfree(hv_vp_index);
+   hv_vp_index = NULL;
 }
 
 /*
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 7c79a17..702abaf 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -280,6 +280,32 @@ static inline u64 hv_do_rep_hypercall(u16 code, u16 
rep_count, u16 varhead_size,
return status;
 }
 
+/*
+ * Hypervisor's notion of virtual processor ID is different from
+ * Linux' notion of CPU ID. This information can only be retrieved
+ * in the context of the calling CPU. Setup a map for easy access
+ * to this information.
+ */
+extern u32 __percpu *hv_vp_index;
+
+/**
+ * hv_cpu_number_to_vp_number() - Map CPU to VP.
+ * @cpu_number: CPU number in Linux terms
+ *
+ * This function returns the mapping between the Linux processor
+ * number and the hypervisor's virtual processor number, useful
+ * in making hypercalls and such that talk about specific
+ * processors.
+ *
+ * Return: Virtual processor number in Hyper-V terms
+ */
+static inline int hv_cpu_number_to_vp_number(int cpu_number)
+{
+   WARN_ON(hv_vp_index[cpu_number] == -1);
+
+   return hv_vp_index[cpu_number];
+}
+
 void hyperv_init(void);
 void hyperv_report_panic(struct pt_regs *regs);
 bool hv_is_hypercall_page_setup(void);
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index f501ce1..331b314 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -600,7 +600,7 @@ static void init_vp_index(struct vmbus_channel *channel, 
u16 dev_type)
 */
channel->numa_node = 0;
channel->target_cpu = 0;
-   channel->target_vp = hv_context.vp_index[0];
+   channel->target_vp = hv_cpu_number_to_vp_number(0);
return;
}
 
@@ -684,7 +684,7 @@ static void init_vp_index(struct vmbus_channel *channel, 
u16 dev_type)
}
 
channel->target_cpu = cur_cpu;
-   channel->target_vp = hv_context.vp_index[cur_cpu];
+   channel->target_vp = hv_cpu_number_to_vp_number(cur_cpu);
 }
 
 static void vmbus_wait_for_unload(void)
@@ -1220,8 +1220,7 @@ struct vmbus_channel