lkml.org 
[lkml]   [2017]   [Apr]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRE: [PATCH 5/7] hyper-v: globalize vp_index
    Date


    > -----Original Message-----
    > From: Vitaly Kuznetsov [mailto:vkuznets@redhat.com]
    > Sent: Friday, April 7, 2017 4:27 AM
    > To: devel@linuxdriverproject.org; x86@kernel.org
    > Cc: linux-kernel@vger.kernel.org; KY Srinivasan <kys@microsoft.com>;
    > Haiyang Zhang <haiyangz@microsoft.com>; Stephen Hemminger
    > <sthemmin@microsoft.com>; Thomas Gleixner <tglx@linutronix.de>; Ingo
    > Molnar <mingo@redhat.com>; H. Peter Anvin <hpa@zytor.com>; Steven
    > Rostedt <rostedt@goodmis.org>; Jork Loeser <Jork.Loeser@microsoft.com>
    > Subject: [PATCH 5/7] hyper-v: globalize vp_index
    >
    > 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 <vkuznets@redhat.com>
    > ---
    > 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 -----------------
    > include/linux/hyperv.h | 1 -
    > 8 files changed, 64 insertions(+), 44 deletions(-)
    >
    > diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
    > index 7d961d4..1c14088 100644
    > --- a/arch/x86/hyperv/hv_init.c
    > +++ b/arch/x86/hyperv/hv_init.c
    > @@ -26,6 +26,8 @@
    > #include <linux/mm.h>
    > #include <linux/clockchips.h>
    > #include <linux/hyperv.h>
    > +#include <linux/slab.h>
    > +#include <linux/cpuhotplug.h>
    >
    > #ifdef CONFIG_X86_64
    >
    > @@ -103,6 +105,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.
    > @@ -118,6 +134,16 @@ void hyperv_init(void)
    > if (x86_hyper != &x86_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
    > @@ -129,7 +155,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);
    > @@ -169,6 +195,12 @@ void hyperv_init(void)
    > hyperv_cs = &hyperv_cs_msr;
    > if (ms_hyperv.features &
    > HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
    > clocksource_register_hz(&hyperv_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 a2c996b..1293c84 100644
    > --- a/arch/x86/include/asm/mshyperv.h
    > +++ b/arch/x86/include/asm/mshyperv.h
    > @@ -274,6 +274,32 @@ static inline u64 hv_do_rep_hypercall(u16 code, u16
    > rep_count, void *input,
    > 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;
    > +
    > +/**
    > + * vmbus_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 vmbus_cpu_number_to_vp_number(int cpu_number)
    > +{
    > + WARN_ON(hv_vp_index[cpu_number] == -1);
    > +
    > + return hv_vp_index[cpu_number];
    > +}

    Now that we have moved this functionality into the Hyper-V specific
    base kernel, a hv prefix maybe more appropriate for the function.

    > +
    > 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 6cfa297..9969c82 100644
    > --- a/drivers/hv/channel_mgmt.c
    > +++ b/drivers/hv/channel_mgmt.c
    > @@ -599,7 +599,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 =
    > vmbus_cpu_number_to_vp_number(0);
    > return;
    > }
    >
    > @@ -683,7 +683,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 =
    > vmbus_cpu_number_to_vp_number(cur_cpu);
    > }
    >
    > static void vmbus_wait_for_unload(void)
    > @@ -1187,8 +1187,7 @@ struct vmbus_channel
    > *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
    > return outgoing_channel;
    > }
    >
    > - cur_cpu = hv_context.vp_index[get_cpu()];
    > - put_cpu();
    > + cur_cpu =
    > vmbus_cpu_number_to_vp_number(smp_processor_id());
    > list_for_each_safe(cur, tmp, &primary->sc_list) {
    > cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
    > if (cur_channel->state != CHANNEL_OPENED_STATE)
    > diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
    > index 545f2a4..7026d13 100644
    > --- a/drivers/hv/connection.c
    > +++ b/drivers/hv/connection.c
    > @@ -96,7 +96,8 @@ static int vmbus_negotiate_version(struct
    > vmbus_channel_msginfo *msginfo,
    > * the CPU attempting to connect may not be CPU 0.
    > */
    > if (version >= VERSION_WIN8_1)
    > - msg->target_vcpu =
    > hv_context.vp_index[smp_processor_id()];
    > + msg->target_vcpu =
    > +
    > vmbus_cpu_number_to_vp_number(smp_processor_id());
    > else
    > msg->target_vcpu = 0;
    >
    > diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
    > index 12e7bae..7e67ef4 100644
    > --- a/drivers/hv/hv.c
    > +++ b/drivers/hv/hv.c
    > @@ -229,7 +229,6 @@ int hv_synic_init(unsigned int cpu)
    > union hv_synic_siefp siefp;
    > union hv_synic_sint shared_sint;
    > union hv_synic_scontrol sctrl;
    > - u64 vp_index;
    >
    > /* Setup the Synic's message page */
    > hv_get_simp(simp.as_uint64);
    > @@ -271,14 +270,6 @@ int hv_synic_init(unsigned int cpu)
    > hv_context.synic_initialized = true;
    >
    > /*
    > - * Setup the mapping between Hyper-V's notion
    > - * of cpuid and Linux' notion of cpuid.
    > - * This array will be indexed using Linux cpuid.
    > - */
    > - hv_get_vp_index(vp_index);
    > - hv_context.vp_index[cpu] = (u32)vp_index;
    > -
    > - /*
    > * Register the per-cpu clockevent source.
    > */
    > if (ms_hyperv.features & HV_X64_MSR_SYNTIMER_AVAILABLE)
    > diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
    > index 6113e91..d624526 100644
    > --- a/drivers/hv/hyperv_vmbus.h
    > +++ b/drivers/hv/hyperv_vmbus.h
    > @@ -229,17 +229,6 @@ struct hv_context {
    > struct hv_per_cpu_context __percpu *cpu_context;
    >
    > /*
    > - * 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:
    > - *
    > - * vp_index[a] is the Hyper-V's processor ID corresponding to
    > - * Linux cpuid 'a'.
    > - */
    > - u32 vp_index[NR_CPUS];
    > -
    > - /*
    > * To manage allocations in a NUMA node.
    > * Array indexed by numa node ID.
    > */
    > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
    > index 0087b49..63e743d 100644
    > --- a/drivers/hv/vmbus_drv.c
    > +++ b/drivers/hv/vmbus_drv.c
    > @@ -1455,23 +1455,6 @@ void vmbus_free_mmio(resource_size_t start,
    > resource_size_t size)
    > }
    > EXPORT_SYMBOL_GPL(vmbus_free_mmio);
    >
    > -/**
    > - * vmbus_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
    > - */
    > -int vmbus_cpu_number_to_vp_number(int cpu_number)
    > -{
    > - return hv_context.vp_index[cpu_number];
    > -}
    > -EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
    > -
    > static int vmbus_acpi_add(struct acpi_device *device)
    > {
    > acpi_status result;
    > diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
    > index 5d6777c..2450e07 100644
    > --- a/include/linux/hyperv.h
    > +++ b/include/linux/hyperv.h
    > @@ -1184,7 +1184,6 @@ int vmbus_allocate_mmio(struct resource **new,
    > struct hv_device *device_obj,
    > resource_size_t size, resource_size_t align,
    > bool fb_overlap_ok);
    > void vmbus_free_mmio(resource_size_t start, resource_size_t size);
    > -int vmbus_cpu_number_to_vp_number(int cpu_number);
    >
    > /*
    > * GUID definitions of various offer types - services offered to the guest.
    > --
    > 2.9.3

    \
     
     \ /
      Last update: 2017-04-08 17:43    [W:4.438 / U:0.516 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site