* RE: [PATCH 00/13] Drivers: hv: vmbus: Miscellaneous fixes
2015-08-05 7:52 [PATCH 00/13] Drivers: hv: vmbus: Miscellaneous fixes K. Y. Srinivasan
@ 2015-08-05 6:29 ` KY Srinivasan
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
1 sibling, 0 replies; 15+ messages in thread
From: KY Srinivasan @ 2015-08-05 6:29 UTC (permalink / raw)
To: KY Srinivasan, gregkh, linux-kernel, devel, olaf, apw, vkuznets,
jasowang
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2809 bytes --]
> -----Original Message-----
> From: K. Y. Srinivasan [mailto:kys@microsoft.com]
> Sent: Wednesday, August 5, 2015 12:52 AM
> To: gregkh@linuxfoundation.org; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; olaf@aepfle.de; apw@canonical.com;
> vkuznets@redhat.com; jasowang@redhat.com
> Cc: KY Srinivasan <kys@microsoft.com>
> Subject: [PATCH 00/13] Drivers: hv: vmbus: Miscellaneous fixes
>
> Miscellaneous fixes/improvements. The patches that were sent over the last
> couple of months have been consolidated in this submission. All review
> comments have been addressed.
This is the remaining 13 matches being sent. I have fixed up Jake's name.
Regards,
K. Y
>
> Christopher Oo (1):
> Drivers: hv_vmbus: Fix signal to host condition
>
> Dexuan Cui (4):
> Drivers: hv: vmbus: Further improve CPU affiliation logic
> Drivers: hv: vmbus: add a sysfs attr to show the binding of
> channel/VP
> tools: hv: add a python script lsvmbus to list VMBus devices
> Drivers: hv: vmbus: document the VMBus sysfs files
>
> Jake Oshins (2):
> drivers:hv: Modify hv_vmbus to search for all MMIO ranges available.
> drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus
>
> K. Y. Srinivasan (2):
> Drivers: hv: vmbus: Improve the CPU affiliation for channels
> Drivers: hv: vmbus: Implement a clocksource based on the TSC page
>
> Viresh Kumar (1):
> drivers/hv: Migrate to new 'set-state' interface
>
> Vitaly Kuznetsov (3):
> cpu-hotplug: convert cpu_hotplug_disabled to a counter
> cpu-hotplug: export cpu_hotplug_enable/cpu_hotplug_disable
> Drivers: hv: vmbus: use cpu_hotplug_enable/disable
>
> Documentation/ABI/stable/sysfs-bus-vmbus | 29 +++
> Documentation/power/suspend-and-cpuhotplug.txt | 6 +-
> MAINTAINERS | 1 +
> arch/x86/include/uapi/asm/hyperv.h | 2 +
> drivers/hv/channel_mgmt.c | 29 ++-
> drivers/hv/hv.c | 137 ++++++++++---
> drivers/hv/hyperv_vmbus.h | 14 ++
> drivers/hv/ring_buffer.c | 14 +-
> drivers/hv/vmbus_drv.c | 280 ++++++++++++++++++------
> drivers/video/fbdev/hyperv_fb.c | 46 ++--
> include/linux/hyperv.h | 7 +-
> kernel/cpu.c | 24 ++-
> tools/hv/lsvmbus | 101 +++++++++
> 13 files changed, 544 insertions(+), 146 deletions(-)
> create mode 100644 Documentation/ABI/stable/sysfs-bus-vmbus
> create mode 100644 tools/hv/lsvmbus
>
> --
> 1.7.4.1
ÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±þG«éÿ{ayº\x1dÊÚë,j\a¢f£¢·hïêÿêçz_è®\x03(éÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?¨èÚ&£ø§~á¶iOæ¬z·vØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?I¥
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 00/13] Drivers: hv: vmbus: Miscellaneous fixes
@ 2015-08-05 7:52 K. Y. Srinivasan
2015-08-05 6:29 ` KY Srinivasan
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
0 siblings, 2 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
Miscellaneous fixes/improvements. The patches that were sent over the last
couple of months have been consolidated in this submission. All review
comments have been addressed.
Christopher Oo (1):
Drivers: hv_vmbus: Fix signal to host condition
Dexuan Cui (4):
Drivers: hv: vmbus: Further improve CPU affiliation logic
Drivers: hv: vmbus: add a sysfs attr to show the binding of
channel/VP
tools: hv: add a python script lsvmbus to list VMBus devices
Drivers: hv: vmbus: document the VMBus sysfs files
Jake Oshins (2):
drivers:hv: Modify hv_vmbus to search for all MMIO ranges available.
drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus
K. Y. Srinivasan (2):
Drivers: hv: vmbus: Improve the CPU affiliation for channels
Drivers: hv: vmbus: Implement a clocksource based on the TSC page
Viresh Kumar (1):
drivers/hv: Migrate to new 'set-state' interface
Vitaly Kuznetsov (3):
cpu-hotplug: convert cpu_hotplug_disabled to a counter
cpu-hotplug: export cpu_hotplug_enable/cpu_hotplug_disable
Drivers: hv: vmbus: use cpu_hotplug_enable/disable
Documentation/ABI/stable/sysfs-bus-vmbus | 29 +++
Documentation/power/suspend-and-cpuhotplug.txt | 6 +-
MAINTAINERS | 1 +
arch/x86/include/uapi/asm/hyperv.h | 2 +
drivers/hv/channel_mgmt.c | 29 ++-
drivers/hv/hv.c | 137 ++++++++++---
drivers/hv/hyperv_vmbus.h | 14 ++
drivers/hv/ring_buffer.c | 14 +-
drivers/hv/vmbus_drv.c | 280 ++++++++++++++++++------
drivers/video/fbdev/hyperv_fb.c | 46 ++--
include/linux/hyperv.h | 7 +-
kernel/cpu.c | 24 ++-
tools/hv/lsvmbus | 101 +++++++++
13 files changed, 544 insertions(+), 146 deletions(-)
create mode 100644 Documentation/ABI/stable/sysfs-bus-vmbus
create mode 100644 tools/hv/lsvmbus
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available.
2015-08-05 7:52 [PATCH 00/13] Drivers: hv: vmbus: Miscellaneous fixes K. Y. Srinivasan
2015-08-05 6:29 ` KY Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 02/13] drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus K. Y. Srinivasan
` (11 more replies)
1 sibling, 12 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: Jake Oshins, K. Y. Srinivasan
From: Jake Oshins <jakeo@microsoft.com>
This patch changes the logic in hv_vmbus to record all of the ranges in the
VM's firmware (BIOS or UEFI) that offer regions of memory-mapped I/O space for
use by paravirtual front-end drivers. The old logic just found one range
above 4GB and called it good. This logic will find any ranges above 1MB.
It would have been possible with this patch to just use existing resource
allocation functions, rather than keep track of the entire set of Hyper-V
related MMIO regions in VMBus. This strategy, however, is not sufficient
when the resource allocator needs to be aware of the constraints of a
Hyper-V virtual machine, which is what happens in the next patch in the series.
So this first patch exists to show the first steps in reworking the MMIO
allocation paths for Hyper-V front-end drivers.
Signed-off-by: Jake Oshins <jakeo@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/vmbus_drv.c | 116 ++++++++++++++++++++++++++++++---------
drivers/video/fbdev/hyperv_fb.c | 2 +-
include/linux/hyperv.h | 2 +-
3 files changed, 92 insertions(+), 28 deletions(-)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index b6114cc..21bb287 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -102,10 +102,7 @@ static struct notifier_block hyperv_panic_block = {
.notifier_call = hyperv_panic_event,
};
-struct resource hyperv_mmio = {
- .name = "hyperv mmio",
- .flags = IORESOURCE_MEM,
-};
+struct resource *hyperv_mmio;
EXPORT_SYMBOL_GPL(hyperv_mmio);
static int vmbus_exists(void)
@@ -1013,30 +1010,105 @@ void vmbus_device_unregister(struct hv_device *device_obj)
/*
- * VMBUS is an acpi enumerated device. Get the the information we
+ * VMBUS is an acpi enumerated device. Get the information we
* need from DSDT.
*/
-
+#define VTPM_BASE_ADDRESS 0xfed40000
static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
{
+ resource_size_t start = 0;
+ resource_size_t end = 0;
+ struct resource *new_res;
+ struct resource **old_res = &hyperv_mmio;
+ struct resource **prev_res = NULL;
+
switch (res->type) {
case ACPI_RESOURCE_TYPE_IRQ:
irq = res->data.irq.interrupts[0];
+ return AE_OK;
+
+ /*
+ * "Address" descriptors are for bus windows. Ignore
+ * "memory" descriptors, which are for registers on
+ * devices.
+ */
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+ start = res->data.address32.address.minimum;
+ end = res->data.address32.address.maximum;
break;
case ACPI_RESOURCE_TYPE_ADDRESS64:
- hyperv_mmio.start = res->data.address64.address.minimum;
- hyperv_mmio.end = res->data.address64.address.maximum;
+ start = res->data.address64.address.minimum;
+ end = res->data.address64.address.maximum;
break;
+
+ default:
+ /* Unused resource type */
+ return AE_OK;
+
}
+ /*
+ * Ignore ranges that are below 1MB, as they're not
+ * necessary or useful here.
+ */
+ if (end < 0x100000)
+ return AE_OK;
+
+ new_res = kzalloc(sizeof(*new_res), GFP_ATOMIC);
+ if (!new_res)
+ return AE_NO_MEMORY;
+
+ /* If this range overlaps the virtual TPM, truncate it. */
+ if (end > VTPM_BASE_ADDRESS && start < VTPM_BASE_ADDRESS)
+ end = VTPM_BASE_ADDRESS;
+
+ new_res->name = "hyperv mmio";
+ new_res->flags = IORESOURCE_MEM;
+ new_res->start = start;
+ new_res->end = end;
+
+ do {
+ if (!*old_res) {
+ *old_res = new_res;
+ break;
+ }
+
+ if ((*old_res)->end < new_res->start) {
+ new_res->sibling = *old_res;
+ if (prev_res)
+ (*prev_res)->sibling = new_res;
+ *old_res = new_res;
+ break;
+ }
+
+ prev_res = old_res;
+ old_res = &(*old_res)->sibling;
+
+ } while (1);
return AE_OK;
}
+static int vmbus_acpi_remove(struct acpi_device *device)
+{
+ struct resource *cur_res;
+ struct resource *next_res;
+
+ if (hyperv_mmio) {
+ for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
+ next_res = cur_res->sibling;
+ kfree(cur_res);
+ }
+ }
+
+ return 0;
+}
+
static int vmbus_acpi_add(struct acpi_device *device)
{
acpi_status result;
int ret_val = -ENODEV;
+ struct acpi_device *ancestor;
hv_acpi_dev = device;
@@ -1046,35 +1118,27 @@ static int vmbus_acpi_add(struct acpi_device *device)
if (ACPI_FAILURE(result))
goto acpi_walk_err;
/*
- * The parent of the vmbus acpi device (Gen2 firmware) is the VMOD that
- * has the mmio ranges. Get that.
+ * Some ancestor of the vmbus acpi device (Gen1 or Gen2
+ * firmware) is the VMOD that has the mmio ranges. Get that.
*/
- if (device->parent) {
- result = acpi_walk_resources(device->parent->handle,
- METHOD_NAME__CRS,
- vmbus_walk_resources, NULL);
+ for (ancestor = device->parent; ancestor; ancestor = ancestor->parent) {
+ result = acpi_walk_resources(ancestor->handle, METHOD_NAME__CRS,
+ vmbus_walk_resources, NULL);
if (ACPI_FAILURE(result))
- goto acpi_walk_err;
- if (hyperv_mmio.start && hyperv_mmio.end)
- request_resource(&iomem_resource, &hyperv_mmio);
+ continue;
+ if (hyperv_mmio)
+ break;
}
ret_val = 0;
acpi_walk_err:
complete(&probe_event);
+ if (ret_val)
+ vmbus_acpi_remove(device);
return ret_val;
}
-static int vmbus_acpi_remove(struct acpi_device *device)
-{
- int ret = 0;
-
- if (hyperv_mmio.start && hyperv_mmio.end)
- ret = release_resource(&hyperv_mmio);
- return ret;
-}
-
static const struct acpi_device_id vmbus_acpi_device_ids[] = {
{"VMBUS", 0},
{"VMBus", 0},
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index 807ee22..b54ee1c 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -688,7 +688,7 @@ static int hvfb_getmem(struct fb_info *info)
par->mem.name = KBUILD_MODNAME;
par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
if (gen2vm) {
- ret = allocate_resource(&hyperv_mmio, &par->mem,
+ ret = allocate_resource(hyperv_mmio, &par->mem,
screen_fb_size,
0, -1,
screen_fb_size,
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 30d3a1f..217e14b 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1233,7 +1233,7 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *,
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
-extern struct resource hyperv_mmio;
+extern struct resource *hyperv_mmio;
/*
* Negotiated version with the Host.
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 02/13] drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 03/13] Drivers: hv: vmbus: Improve the CPU affiliation for channels K. Y. Srinivasan
` (10 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: Jake Oshins, K. Y. Srinivasan
From: Jake Oshins <jakeo@microsoft.com>
This patch deletes the logic from hyperv_fb which picked a range of MMIO space
for the frame buffer and adds new logic to hv_vmbus which picks ranges for
child drivers. The new logic isn't quite the same as the old, as it considers
more possible ranges.
Signed-off-by: Jake Oshins <jakeo@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/vmbus_drv.c | 88 +++++++++++++++++++++++++++++++++++++--
drivers/video/fbdev/hyperv_fb.c | 46 +++++++++-----------
include/linux/hyperv.h | 7 ++-
3 files changed, 110 insertions(+), 31 deletions(-)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 21bb287..83759c1 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -39,6 +39,7 @@
#include <asm/mshyperv.h>
#include <linux/notifier.h>
#include <linux/ptrace.h>
+#include <linux/screen_info.h>
#include <linux/kdebug.h>
#include "hyperv_vmbus.h"
@@ -103,7 +104,6 @@ static struct notifier_block hyperv_panic_block = {
};
struct resource *hyperv_mmio;
-EXPORT_SYMBOL_GPL(hyperv_mmio);
static int vmbus_exists(void)
{
@@ -891,8 +891,8 @@ err_cleanup:
}
/**
- * __vmbus_child_driver_register - Register a vmbus's driver
- * @drv: Pointer to driver structure you want to register
+ * __vmbus_child_driver_register() - Register a vmbus's driver
+ * @hv_driver: Pointer to driver structure you want to register
* @owner: owner module of the drv
* @mod_name: module name string
*
@@ -924,7 +924,8 @@ EXPORT_SYMBOL_GPL(__vmbus_driver_register);
/**
* vmbus_driver_unregister() - Unregister a vmbus's driver
- * @drv: Pointer to driver structure you want to un-register
+ * @hv_driver: Pointer to driver structure you want to
+ * un-register
*
* Un-register the given driver that was previous registered with a call to
* vmbus_driver_register()
@@ -1104,6 +1105,85 @@ static int vmbus_acpi_remove(struct acpi_device *device)
return 0;
}
+/**
+ * vmbus_allocate_mmio() - Pick a memory-mapped I/O range.
+ * @new: If successful, supplied a pointer to the
+ * allocated MMIO space.
+ * @device_obj: Identifies the caller
+ * @min: Minimum guest physical address of the
+ * allocation
+ * @max: Maximum guest physical address
+ * @size: Size of the range to be allocated
+ * @align: Alignment of the range to be allocated
+ * @fb_overlap_ok: Whether this allocation can be allowed
+ * to overlap the video frame buffer.
+ *
+ * This function walks the resources granted to VMBus by the
+ * _CRS object in the ACPI namespace underneath the parent
+ * "bridge" whether that's a root PCI bus in the Generation 1
+ * case or a Module Device in the Generation 2 case. It then
+ * attempts to allocate from the global MMIO pool in a way that
+ * matches the constraints supplied in these parameters and by
+ * that _CRS.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
+ resource_size_t min, resource_size_t max,
+ resource_size_t size, resource_size_t align,
+ bool fb_overlap_ok)
+{
+ struct resource *iter;
+ resource_size_t range_min, range_max, start, local_min, local_max;
+ const char *dev_n = dev_name(&device_obj->device);
+ u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
+ int i;
+
+ for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+ if ((iter->start >= max) || (iter->end <= min))
+ continue;
+
+ range_min = iter->start;
+ range_max = iter->end;
+
+ /* If this range overlaps the frame buffer, split it into
+ two tries. */
+ for (i = 0; i < 2; i++) {
+ local_min = range_min;
+ local_max = range_max;
+ if (fb_overlap_ok || (range_min >= fb_end) ||
+ (range_max <= screen_info.lfb_base)) {
+ i++;
+ } else {
+ if ((range_min <= screen_info.lfb_base) &&
+ (range_max >= screen_info.lfb_base)) {
+ /*
+ * The frame buffer is in this window,
+ * so trim this into the part that
+ * preceeds the frame buffer.
+ */
+ local_max = screen_info.lfb_base - 1;
+ range_min = fb_end;
+ } else {
+ range_min = fb_end;
+ continue;
+ }
+ }
+
+ start = (local_min + align - 1) & ~(align - 1);
+ for (; start + size - 1 <= local_max; start += align) {
+ *new = request_mem_region_exclusive(start, size,
+ dev_n);
+ if (*new)
+ return 0;
+ }
+ }
+ }
+
+ return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
+
static int vmbus_acpi_add(struct acpi_device *device)
{
acpi_status result;
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index b54ee1c..e2451bd 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -213,7 +213,7 @@ struct synthvid_msg {
struct hvfb_par {
struct fb_info *info;
- struct resource mem;
+ struct resource *mem;
bool fb_ready; /* fb device is ready */
struct completion wait;
u32 synthvid_version;
@@ -677,26 +677,18 @@ static void hvfb_get_option(struct fb_info *info)
/* Get framebuffer memory from Hyper-V video pci space */
-static int hvfb_getmem(struct fb_info *info)
+static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
{
struct hvfb_par *par = info->par;
struct pci_dev *pdev = NULL;
void __iomem *fb_virt;
int gen2vm = efi_enabled(EFI_BOOT);
+ resource_size_t pot_start, pot_end;
int ret;
- par->mem.name = KBUILD_MODNAME;
- par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
if (gen2vm) {
- ret = allocate_resource(hyperv_mmio, &par->mem,
- screen_fb_size,
- 0, -1,
- screen_fb_size,
- NULL, NULL);
- if (ret != 0) {
- pr_err("Unable to allocate framebuffer memory\n");
- return -ENODEV;
- }
+ pot_start = 0;
+ pot_end = -1;
} else {
pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
@@ -709,16 +701,18 @@ static int hvfb_getmem(struct fb_info *info)
pci_resource_len(pdev, 0) < screen_fb_size)
goto err1;
- par->mem.end = pci_resource_end(pdev, 0);
- par->mem.start = par->mem.end - screen_fb_size + 1;
- ret = request_resource(&pdev->resource[0], &par->mem);
- if (ret != 0) {
- pr_err("Unable to request framebuffer memory\n");
- goto err1;
- }
+ pot_end = pci_resource_end(pdev, 0);
+ pot_start = pot_end - screen_fb_size + 1;
+ }
+
+ ret = vmbus_allocate_mmio(&par->mem, hdev, pot_start, pot_end,
+ screen_fb_size, 0x100000, true);
+ if (ret != 0) {
+ pr_err("Unable to allocate framebuffer memory\n");
+ goto err1;
}
- fb_virt = ioremap(par->mem.start, screen_fb_size);
+ fb_virt = ioremap(par->mem->start, screen_fb_size);
if (!fb_virt)
goto err2;
@@ -736,7 +730,7 @@ static int hvfb_getmem(struct fb_info *info)
info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
}
- info->fix.smem_start = par->mem.start;
+ info->fix.smem_start = par->mem->start;
info->fix.smem_len = screen_fb_size;
info->screen_base = fb_virt;
info->screen_size = screen_fb_size;
@@ -749,7 +743,8 @@ static int hvfb_getmem(struct fb_info *info)
err3:
iounmap(fb_virt);
err2:
- release_resource(&par->mem);
+ release_mem_region(par->mem->start, screen_fb_size);
+ par->mem = NULL;
err1:
if (!gen2vm)
pci_dev_put(pdev);
@@ -763,7 +758,8 @@ static void hvfb_putmem(struct fb_info *info)
struct hvfb_par *par = info->par;
iounmap(info->screen_base);
- release_resource(&par->mem);
+ release_mem_region(par->mem->start, screen_fb_size);
+ par->mem = NULL;
}
@@ -794,7 +790,7 @@ static int hvfb_probe(struct hv_device *hdev,
goto error1;
}
- ret = hvfb_getmem(info);
+ ret = hvfb_getmem(hdev, info);
if (ret) {
pr_err("No memory for framebuffer\n");
goto error2;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 217e14b..54733d5 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -977,6 +977,11 @@ int __must_check __vmbus_driver_register(struct hv_driver *hv_driver,
const char *mod_name);
void vmbus_driver_unregister(struct hv_driver *hv_driver);
+int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
+ resource_size_t min, resource_size_t max,
+ resource_size_t size, resource_size_t align,
+ bool fb_overlap_ok);
+
/**
* VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
*
@@ -1233,8 +1238,6 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *,
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
-extern struct resource *hyperv_mmio;
-
/*
* Negotiated version with the Host.
*/
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 03/13] Drivers: hv: vmbus: Improve the CPU affiliation for channels
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 02/13] drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 04/13] Drivers: hv: vmbus: Further improve CPU affiliation logic K. Y. Srinivasan
` (9 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
The current code tracks the assigned CPUs within a NUMA node in the context of
the primary channel. So, if we have a VM with a single NUMA node with 8 VCPUs, we may
end up unevenly distributing the channel load. Fix the issue by tracking affiliations
globally.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/channel_mgmt.c | 11 ++++++-----
drivers/hv/hv.c | 9 +++++++++
drivers/hv/hyperv_vmbus.h | 5 +++++
include/linux/hyperv.h | 1 -
4 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 4506a66..f52373a 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -391,6 +391,7 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui
struct vmbus_channel *primary = channel->primary_channel;
int next_node;
struct cpumask available_mask;
+ struct cpumask *alloced_mask;
for (i = IDE; i < MAX_PERF_CHN; i++) {
if (!memcmp(type_guid->b, hp_devs[i].guid,
@@ -408,7 +409,6 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui
* channel, bind it to cpu 0.
*/
channel->numa_node = 0;
- cpumask_set_cpu(0, &channel->alloced_cpus_in_node);
channel->target_cpu = 0;
channel->target_vp = hv_context.vp_index[0];
return;
@@ -433,21 +433,22 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui
channel->numa_node = next_node;
primary = channel;
}
+ alloced_mask = &hv_context.hv_numa_map[primary->numa_node];
- if (cpumask_weight(&primary->alloced_cpus_in_node) ==
+ if (cpumask_weight(alloced_mask) ==
cpumask_weight(cpumask_of_node(primary->numa_node))) {
/*
* We have cycled through all the CPUs in the node;
* reset the alloced map.
*/
- cpumask_clear(&primary->alloced_cpus_in_node);
+ cpumask_clear(alloced_mask);
}
- cpumask_xor(&available_mask, &primary->alloced_cpus_in_node,
+ cpumask_xor(&available_mask, alloced_mask,
cpumask_of_node(primary->numa_node));
cur_cpu = cpumask_next(-1, &available_mask);
- cpumask_set_cpu(cur_cpu, &primary->alloced_cpus_in_node);
+ cpumask_set_cpu(cur_cpu, alloced_mask);
channel->target_cpu = cur_cpu;
channel->target_vp = hv_context.vp_index[cur_cpu];
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 41d8072..fd93cfd 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -332,6 +332,13 @@ int hv_synic_alloc(void)
size_t ced_size = sizeof(struct clock_event_device);
int cpu;
+ hv_context.hv_numa_map = kzalloc(sizeof(struct cpumask) * nr_node_ids,
+ GFP_ATOMIC);
+ if (hv_context.hv_numa_map == NULL) {
+ pr_err("Unable to allocate NUMA map\n");
+ goto err;
+ }
+
for_each_online_cpu(cpu) {
hv_context.event_dpc[cpu] = kmalloc(size, GFP_ATOMIC);
if (hv_context.event_dpc[cpu] == NULL) {
@@ -345,6 +352,7 @@ int hv_synic_alloc(void)
pr_err("Unable to allocate clock event device\n");
goto err;
}
+
hv_init_clockevent_device(hv_context.clk_evt[cpu], cpu);
hv_context.synic_message_page[cpu] =
@@ -393,6 +401,7 @@ void hv_synic_free(void)
{
int cpu;
+ kfree(hv_context.hv_numa_map);
for_each_online_cpu(cpu)
hv_synic_free_cpu(cpu);
}
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index cddc0c9..7bdef66 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -551,6 +551,11 @@ struct hv_context {
* Support PV clockevent device.
*/
struct clock_event_device *clk_evt[NR_CPUS];
+ /*
+ * To manage allocations in a NUMA node.
+ * Array indexed by numa node ID.
+ */
+ struct cpumask *hv_numa_map;
};
extern struct hv_context hv_context;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 54733d5..5a3df5a 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -699,7 +699,6 @@ struct vmbus_channel {
/*
* State to manage the CPU affiliation of channels.
*/
- struct cpumask alloced_cpus_in_node;
int numa_node;
/*
* Support for sub-channels. For high performance devices,
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 04/13] Drivers: hv: vmbus: Further improve CPU affiliation logic
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 02/13] drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 03/13] Drivers: hv: vmbus: Improve the CPU affiliation for channels K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 05/13] Drivers: hv_vmbus: Fix signal to host condition K. Y. Srinivasan
` (8 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: Dexuan Cui, K. Y. Srinivasan
From: Dexuan Cui <decui@microsoft.com>
Keep track of CPU affiliations of sub-channels within the scope of the primary
channel. This will allow us to better distribute the load amongst available
CPUs.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/channel_mgmt.c | 20 ++++++++++++++++++--
include/linux/hyperv.h | 1 +
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index f52373a..3ab4753 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -447,8 +447,24 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui
cpumask_xor(&available_mask, alloced_mask,
cpumask_of_node(primary->numa_node));
- cur_cpu = cpumask_next(-1, &available_mask);
- cpumask_set_cpu(cur_cpu, alloced_mask);
+ cur_cpu = -1;
+ while (true) {
+ cur_cpu = cpumask_next(cur_cpu, &available_mask);
+ if (cur_cpu >= nr_cpu_ids) {
+ cur_cpu = -1;
+ cpumask_copy(&available_mask,
+ cpumask_of_node(primary->numa_node));
+ continue;
+ }
+
+ if (!cpumask_test_cpu(cur_cpu,
+ &primary->alloced_cpus_in_node)) {
+ cpumask_set_cpu(cur_cpu,
+ &primary->alloced_cpus_in_node);
+ cpumask_set_cpu(cur_cpu, alloced_mask);
+ break;
+ }
+ }
channel->target_cpu = cur_cpu;
channel->target_vp = hv_context.vp_index[cur_cpu];
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 5a3df5a..54733d5 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -699,6 +699,7 @@ struct vmbus_channel {
/*
* State to manage the CPU affiliation of channels.
*/
+ struct cpumask alloced_cpus_in_node;
int numa_node;
/*
* Support for sub-channels. For high performance devices,
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 05/13] Drivers: hv_vmbus: Fix signal to host condition
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
` (2 preceding siblings ...)
2015-08-05 7:52 ` [PATCH 04/13] Drivers: hv: vmbus: Further improve CPU affiliation logic K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 06/13] drivers/hv: Migrate to new 'set-state' interface K. Y. Srinivasan
` (7 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: Christopher Oo, K. Y. Srinivasan
From: Christopher Oo <t-chriso@microsoft.com>
Fixes a bug where previously hv_ringbuffer_read would pass in the old
number of bytes available to read instead of the expected old read index
when calculating when to signal to the host that the ringbuffer is empty.
Since the previous write size is already saved, also changes the
hv_need_to_signal_on_read to use the previously read value rather than
recalculating it.
Signed-off-by: Christopher Oo <t-chriso@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/ring_buffer.c | 14 +++-----------
1 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 6361d12..70a1a9a 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -103,10 +103,9 @@ static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi)
* there is room for the producer to send the pending packet.
*/
-static bool hv_need_to_signal_on_read(u32 old_rd,
- struct hv_ring_buffer_info *rbi)
+static bool hv_need_to_signal_on_read(u32 prev_write_sz,
+ struct hv_ring_buffer_info *rbi)
{
- u32 prev_write_sz;
u32 cur_write_sz;
u32 r_size;
u32 write_loc = rbi->ring_buffer->write_index;
@@ -123,10 +122,6 @@ static bool hv_need_to_signal_on_read(u32 old_rd,
cur_write_sz = write_loc >= read_loc ? r_size - (write_loc - read_loc) :
read_loc - write_loc;
- prev_write_sz = write_loc >= old_rd ? r_size - (write_loc - old_rd) :
- old_rd - write_loc;
-
-
if ((prev_write_sz < pending_sz) && (cur_write_sz >= pending_sz))
return true;
@@ -517,7 +512,6 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
u32 next_read_location = 0;
u64 prev_indices = 0;
unsigned long flags;
- u32 old_read;
if (buflen <= 0)
return -EINVAL;
@@ -528,8 +522,6 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
&bytes_avail_toread,
&bytes_avail_towrite);
- old_read = bytes_avail_toread;
-
/* Make sure there is something to read */
if (bytes_avail_toread < buflen) {
spin_unlock_irqrestore(&inring_info->ring_lock, flags);
@@ -560,7 +552,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
spin_unlock_irqrestore(&inring_info->ring_lock, flags);
- *signal = hv_need_to_signal_on_read(old_read, inring_info);
+ *signal = hv_need_to_signal_on_read(bytes_avail_towrite, inring_info);
return 0;
}
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 06/13] drivers/hv: Migrate to new 'set-state' interface
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
` (3 preceding siblings ...)
2015-08-05 7:52 ` [PATCH 05/13] Drivers: hv_vmbus: Fix signal to host condition K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 07/13] Drivers: hv: vmbus: Implement a clocksource based on the TSC page K. Y. Srinivasan
` (6 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: Viresh Kumar, K. Y. Srinivasan, Haiyang Zhang
From: Viresh Kumar <viresh.kumar@linaro.org>
Migrate hv driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.
This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: devel@linuxdriverproject.org
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/hv.c | 45 +++++++++++++++++++--------------------------
1 files changed, 19 insertions(+), 26 deletions(-)
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index fd93cfd..c641faf 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -274,7 +274,7 @@ static int hv_ce_set_next_event(unsigned long delta,
{
cycle_t current_tick;
- WARN_ON(evt->mode != CLOCK_EVT_MODE_ONESHOT);
+ WARN_ON(!clockevent_state_oneshot(evt));
rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
current_tick += delta;
@@ -282,31 +282,24 @@ static int hv_ce_set_next_event(unsigned long delta,
return 0;
}
-static void hv_ce_setmode(enum clock_event_mode mode,
- struct clock_event_device *evt)
+static int hv_ce_shutdown(struct clock_event_device *evt)
+{
+ wrmsrl(HV_X64_MSR_STIMER0_COUNT, 0);
+ wrmsrl(HV_X64_MSR_STIMER0_CONFIG, 0);
+
+ return 0;
+}
+
+static int hv_ce_set_oneshot(struct clock_event_device *evt)
{
union hv_timer_config timer_cfg;
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- /* unsupported */
- break;
-
- case CLOCK_EVT_MODE_ONESHOT:
- timer_cfg.enable = 1;
- timer_cfg.auto_enable = 1;
- timer_cfg.sintx = VMBUS_MESSAGE_SINT;
- wrmsrl(HV_X64_MSR_STIMER0_CONFIG, timer_cfg.as_uint64);
- break;
-
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- wrmsrl(HV_X64_MSR_STIMER0_COUNT, 0);
- wrmsrl(HV_X64_MSR_STIMER0_CONFIG, 0);
- break;
- case CLOCK_EVT_MODE_RESUME:
- break;
- }
+ timer_cfg.enable = 1;
+ timer_cfg.auto_enable = 1;
+ timer_cfg.sintx = VMBUS_MESSAGE_SINT;
+ wrmsrl(HV_X64_MSR_STIMER0_CONFIG, timer_cfg.as_uint64);
+
+ return 0;
}
static void hv_init_clockevent_device(struct clock_event_device *dev, int cpu)
@@ -321,7 +314,8 @@ static void hv_init_clockevent_device(struct clock_event_device *dev, int cpu)
* references to the hv_vmbus module making it impossible to unload.
*/
- dev->set_mode = hv_ce_setmode;
+ dev->set_state_shutdown = hv_ce_shutdown;
+ dev->set_state_oneshot = hv_ce_set_oneshot;
dev->set_next_event = hv_ce_set_next_event;
}
@@ -515,8 +509,7 @@ void hv_synic_cleanup(void *arg)
/* Turn off clockevent device */
if (ms_hyperv.features & HV_X64_MSR_SYNTIMER_AVAILABLE)
- hv_ce_setmode(CLOCK_EVT_MODE_SHUTDOWN,
- hv_context.clk_evt[cpu]);
+ hv_ce_shutdown(hv_context.clk_evt[cpu]);
rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 07/13] Drivers: hv: vmbus: Implement a clocksource based on the TSC page
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
` (4 preceding siblings ...)
2015-08-05 7:52 ` [PATCH 06/13] drivers/hv: Migrate to new 'set-state' interface K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 08/13] Drivers: hv: vmbus: add a sysfs attr to show the binding of channel/VP K. Y. Srinivasan
` (5 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
The current Hyper-V clock source is based on the per-partition reference counter
and this counter is being accessed via s synthetic MSR - HV_X64_MSR_TIME_REF_COUNT.
Hyper-V has a more efficient way of computing the per-partition reference
counter value that does not involve reading a synthetic MSR. We implement
a time source based on this mechanism.
Tested-by: Vivek Yadav <vyadav@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
arch/x86/include/uapi/asm/hyperv.h | 2 +
drivers/hv/hv.c | 83 ++++++++++++++++++++++++++++++++++++
drivers/hv/hyperv_vmbus.h | 9 ++++
3 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 8fba544..89f15e3 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -27,6 +27,8 @@
#define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0)
/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1)
+/* Partition reference TSC MSR is available */
+#define HV_X64_MSR_REFERENCE_TSC_AVAILABLE (1 << 9)
/* A partition's reference time stamp counter (TSC) page */
#define HV_X64_MSR_REFERENCE_TSC 0x40000021
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index c641faf..6341be8 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -133,6 +133,56 @@ static u64 do_hypercall(u64 control, void *input, void *output)
#endif /* !x86_64 */
}
+#ifdef CONFIG_X86_64
+static cycle_t read_hv_clock_tsc(struct clocksource *arg)
+{
+ cycle_t current_tick;
+ struct ms_hyperv_tsc_page *tsc_pg = hv_context.tsc_page;
+
+ if (tsc_pg->tsc_sequence != -1) {
+ /*
+ * Use the tsc page to compute the value.
+ */
+
+ while (1) {
+ cycle_t tmp;
+ u32 sequence = tsc_pg->tsc_sequence;
+ u64 cur_tsc;
+ u64 scale = tsc_pg->tsc_scale;
+ s64 offset = tsc_pg->tsc_offset;
+
+ rdtscll(cur_tsc);
+ /* current_tick = ((cur_tsc *scale) >> 64) + offset */
+ asm("mulq %3"
+ : "=d" (current_tick), "=a" (tmp)
+ : "a" (cur_tsc), "r" (scale));
+
+ current_tick += offset;
+ if (tsc_pg->tsc_sequence == sequence)
+ return current_tick;
+
+ if (tsc_pg->tsc_sequence != -1)
+ continue;
+ /*
+ * Fallback using MSR method.
+ */
+ break;
+ }
+ }
+ rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
+ return current_tick;
+}
+
+static struct clocksource hyperv_cs_tsc = {
+ .name = "hyperv_clocksource_tsc_page",
+ .rating = 425,
+ .read = read_hv_clock_tsc,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+#endif
+
+
/*
* hv_init - Main initialization routine.
*
@@ -142,7 +192,9 @@ int hv_init(void)
{
int max_leaf;
union hv_x64_msr_hypercall_contents hypercall_msr;
+ union hv_x64_msr_hypercall_contents tsc_msr;
void *virtaddr = NULL;
+ void *va_tsc = NULL;
memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS);
memset(hv_context.synic_message_page, 0,
@@ -186,6 +238,22 @@ int hv_init(void)
hv_context.hypercall_page = virtaddr;
+#ifdef CONFIG_X86_64
+ if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) {
+ va_tsc = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL);
+ if (!va_tsc)
+ goto cleanup;
+ hv_context.tsc_page = va_tsc;
+
+ rdmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
+
+ tsc_msr.enable = 1;
+ tsc_msr.guest_physical_address = vmalloc_to_pfn(va_tsc);
+
+ wrmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
+ clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
+ }
+#endif
return 0;
cleanup:
@@ -219,6 +287,21 @@ void hv_cleanup(void)
vfree(hv_context.hypercall_page);
hv_context.hypercall_page = NULL;
}
+
+#ifdef CONFIG_X86_64
+ /*
+ * Cleanup the TSC page based CS.
+ */
+ if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) {
+ clocksource_change_rating(&hyperv_cs_tsc, 10);
+ clocksource_unregister(&hyperv_cs_tsc);
+
+ hypercall_msr.as_uint64 = 0;
+ wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64);
+ vfree(hv_context.tsc_page);
+ hv_context.tsc_page = NULL;
+ }
+#endif
}
/*
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 7bdef66..4b1eb6d 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -517,6 +517,7 @@ struct hv_context {
u64 guestid;
void *hypercall_page;
+ void *tsc_page;
bool synic_initialized;
@@ -560,6 +561,14 @@ struct hv_context {
extern struct hv_context hv_context;
+struct ms_hyperv_tsc_page {
+ volatile u32 tsc_sequence;
+ u32 reserved1;
+ volatile u64 tsc_scale;
+ volatile s64 tsc_offset;
+ u64 reserved2[509];
+};
+
struct hv_ring_buffer_debug_info {
u32 current_interrupt_mask;
u32 current_read_index;
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 08/13] Drivers: hv: vmbus: add a sysfs attr to show the binding of channel/VP
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
` (5 preceding siblings ...)
2015-08-05 7:52 ` [PATCH 07/13] Drivers: hv: vmbus: Implement a clocksource based on the TSC page K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 09/13] tools: hv: add a python script lsvmbus to list VMBus devices K. Y. Srinivasan
` (4 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: Dexuan Cui, K. Y. Srinivasan
From: Dexuan Cui <decui@microsoft.com>
This is useful to analyze performance issue.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/vmbus_drv.c | 38 ++++++++++++++++++++++++++++++++++++++
1 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 83759c1..50100ec 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -441,6 +441,43 @@ static ssize_t in_write_bytes_avail_show(struct device *dev,
}
static DEVICE_ATTR_RO(in_write_bytes_avail);
+static ssize_t channel_vp_mapping_show(struct device *dev,
+ struct device_attribute *dev_attr,
+ char *buf)
+{
+ struct hv_device *hv_dev = device_to_hv_device(dev);
+ struct vmbus_channel *channel = hv_dev->channel, *cur_sc;
+ unsigned long flags;
+ int buf_size = PAGE_SIZE, n_written, tot_written;
+ struct list_head *cur;
+
+ if (!channel)
+ return -ENODEV;
+
+ tot_written = snprintf(buf, buf_size, "%u:%u\n",
+ channel->offermsg.child_relid, channel->target_cpu);
+
+ spin_lock_irqsave(&channel->lock, flags);
+
+ list_for_each(cur, &channel->sc_list) {
+ if (tot_written >= buf_size - 1)
+ break;
+
+ cur_sc = list_entry(cur, struct vmbus_channel, sc_list);
+ n_written = scnprintf(buf + tot_written,
+ buf_size - tot_written,
+ "%u:%u\n",
+ cur_sc->offermsg.child_relid,
+ cur_sc->target_cpu);
+ tot_written += n_written;
+ }
+
+ spin_unlock_irqrestore(&channel->lock, flags);
+
+ return tot_written;
+}
+static DEVICE_ATTR_RO(channel_vp_mapping);
+
/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
static struct attribute *vmbus_attrs[] = {
&dev_attr_id.attr,
@@ -465,6 +502,7 @@ static struct attribute *vmbus_attrs[] = {
&dev_attr_in_write_index.attr,
&dev_attr_in_read_bytes_avail.attr,
&dev_attr_in_write_bytes_avail.attr,
+ &dev_attr_channel_vp_mapping.attr,
NULL,
};
ATTRIBUTE_GROUPS(vmbus);
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 09/13] tools: hv: add a python script lsvmbus to list VMBus devices
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
` (6 preceding siblings ...)
2015-08-05 7:52 ` [PATCH 08/13] Drivers: hv: vmbus: add a sysfs attr to show the binding of channel/VP K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 10/13] Drivers: hv: vmbus: document the VMBus sysfs files K. Y. Srinivasan
` (3 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: Dexuan Cui, K. Y. Srinivasan
From: Dexuan Cui <decui@microsoft.com>
By default lsvmbus lists all the devices in the VMBus.
With -v or -vv, more information is printed, including the VMBus
Rel_ID, class ID, device ID and which channel is bound to which
virtual processor, etc.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
tools/hv/lsvmbus | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 101 insertions(+), 0 deletions(-)
create mode 100644 tools/hv/lsvmbus
diff --git a/tools/hv/lsvmbus b/tools/hv/lsvmbus
new file mode 100644
index 0000000..162a378
--- /dev/null
+++ b/tools/hv/lsvmbus
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+
+import os
+from optparse import OptionParser
+
+parser = OptionParser()
+parser.add_option("-v", "--verbose", dest="verbose",
+ help="print verbose messages. Try -vv, -vvv for \
+ more verbose messages", action="count")
+
+(options, args) = parser.parse_args()
+
+verbose = 0
+if options.verbose is not None:
+ verbose = options.verbose
+
+vmbus_sys_path = '/sys/bus/vmbus/devices'
+if not os.path.isdir(vmbus_sys_path):
+ print "%s doesn't exist: exiting..." % vmbus_sys_path
+ exit(-1)
+
+vmbus_dev_dict = {
+ '{0e0b6031-5213-4934-818b-38d90ced39db}' : '[Operating system shutdown]',
+ '{9527e630-d0ae-497b-adce-e80ab0175caf}' : '[Time Synchronization]',
+ '{57164f39-9115-4e78-ab55-382f3bd5422d}' : '[Heartbeat]',
+ '{a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}' : '[Data Exchange]',
+ '{35fa2e29-ea23-4236-96ae-3a6ebacba440}' : '[Backup (volume checkpoint)]',
+ '{34d14be3-dee4-41c8-9ae7-6b174977c192}' : '[Guest services]',
+ '{525074dc-8985-46e2-8057-a307dc18a502}' : '[Dynamic Memory]',
+ '{cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}' : 'Synthetic mouse',
+ '{f912ad6d-2b17-48ea-bd65-f927a61c7684}' : 'Synthetic keyboard',
+ '{da0a7802-e377-4aac-8e77-0558eb1073f8}' : 'Synthetic framebuffer adapter',
+ '{f8615163-df3e-46c5-913f-f2d2f965ed0e}' : 'Synthetic network adapter',
+ '{32412632-86cb-44a2-9b5c-50d1417354f5}' : 'Synthetic IDE Controller',
+ '{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}' : 'Synthetic SCSI Controller',
+ '{2f9bcc4a-0069-4af3-b76b-6fd0be528cda}' : 'Synthetic fiber channel adapter',
+ '{8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}' : 'Synthetic RDMA adapter',
+ '{276aacf4-ac15-426c-98dd-7521ad3f01fe}' : '[Reserved system device]',
+ '{f8e65716-3cb3-4a06-9a60-1889c5cccab5}' : '[Reserved system device]',
+ '{3375baf4-9e15-4b30-b765-67acb10d607b}' : '[Reserved system device]',
+}
+
+def get_vmbus_dev_attr(dev_name, attr):
+ try:
+ f = open('%s/%s/%s' % (vmbus_sys_path, dev_name, attr), 'r')
+ lines = f.readlines()
+ f.close()
+ except IOError:
+ lines = []
+
+ return lines
+
+class VMBus_Dev:
+ pass
+
+
+vmbus_dev_list = []
+
+for f in os.listdir(vmbus_sys_path):
+ vmbus_id = get_vmbus_dev_attr(f, 'id')[0].strip()
+ class_id = get_vmbus_dev_attr(f, 'class_id')[0].strip()
+ device_id = get_vmbus_dev_attr(f, 'device_id')[0].strip()
+ dev_desc = vmbus_dev_dict.get(class_id, 'Unknown')
+
+ chn_vp_mapping = get_vmbus_dev_attr(f, 'channel_vp_mapping')
+ chn_vp_mapping = [c.strip() for c in chn_vp_mapping]
+ chn_vp_mapping = sorted(chn_vp_mapping,
+ key = lambda c : int(c.split(':')[0]))
+
+ chn_vp_mapping = ['\tRel_ID=%s, target_cpu=%s' %
+ (c.split(':')[0], c.split(':')[1])
+ for c in chn_vp_mapping]
+ d = VMBus_Dev()
+ d.sysfs_path = '%s/%s' % (vmbus_sys_path, f)
+ d.vmbus_id = vmbus_id
+ d.class_id = class_id
+ d.device_id = device_id
+ d.dev_desc = dev_desc
+ d.chn_vp_mapping = '\n'.join(chn_vp_mapping)
+ if d.chn_vp_mapping:
+ d.chn_vp_mapping += '\n'
+
+ vmbus_dev_list.append(d)
+
+
+vmbus_dev_list = sorted(vmbus_dev_list, key = lambda d : int(d.vmbus_id))
+
+format0 = '%2s: %s'
+format1 = '%2s: Class_ID = %s - %s\n%s'
+format2 = '%2s: Class_ID = %s - %s\n\tDevice_ID = %s\n\tSysfs path: %s\n%s'
+
+for d in vmbus_dev_list:
+ if verbose == 0:
+ print ('VMBUS ID ' + format0) % (d.vmbus_id, d.dev_desc)
+ elif verbose == 1:
+ print ('VMBUS ID ' + format1) % \
+ (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping)
+ else:
+ print ('VMBUS ID ' + format2) % \
+ (d.vmbus_id, d.class_id, d.dev_desc, \
+ d.device_id, d.sysfs_path, d.chn_vp_mapping)
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 10/13] Drivers: hv: vmbus: document the VMBus sysfs files
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
` (7 preceding siblings ...)
2015-08-05 7:52 ` [PATCH 09/13] tools: hv: add a python script lsvmbus to list VMBus devices K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 11/13] cpu-hotplug: convert cpu_hotplug_disabled to a counter K. Y. Srinivasan
` (2 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: Dexuan Cui, K. Y. Srinivasan
From: Dexuan Cui <decui@microsoft.com>
The 4 sysfs files should be stable ABIs to the user space.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
Documentation/ABI/stable/sysfs-bus-vmbus | 29 +++++++++++++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 30 insertions(+), 0 deletions(-)
create mode 100644 Documentation/ABI/stable/sysfs-bus-vmbus
diff --git a/Documentation/ABI/stable/sysfs-bus-vmbus b/Documentation/ABI/stable/sysfs-bus-vmbus
new file mode 100644
index 0000000..636e938
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-bus-vmbus
@@ -0,0 +1,29 @@
+What: /sys/bus/vmbus/devices/vmbus_*/id
+Date: Jul 2009
+KernelVersion: 2.6.31
+Contact: K. Y. Srinivasan <kys@microsoft.com>
+Description: The VMBus child_relid of the device's primary channel
+Users: tools/hv/lsvmbus
+
+What: /sys/bus/vmbus/devices/vmbus_*/class_id
+Date: Jul 2009
+KernelVersion: 2.6.31
+Contact: K. Y. Srinivasan <kys@microsoft.com>
+Description: The VMBus interface type GUID of the device
+Users: tools/hv/lsvmbus
+
+What: /sys/bus/vmbus/devices/vmbus_*/device_id
+Date: Jul 2009
+KernelVersion: 2.6.31
+Contact: K. Y. Srinivasan <kys@microsoft.com>
+Description: The VMBus interface instance GUID of the device
+Users: tools/hv/lsvmbus
+
+What: /sys/bus/vmbus/devices/vmbus_*/channel_vp_mapping
+Date: Jul 2015
+KernelVersion: 4.2.0
+Contact: K. Y. Srinivasan <kys@microsoft.com>
+Description: The mapping of which primary/sub channels are bound to which
+ Virtual Processors.
+ Format: <channel's child_relid:the bound cpu's number>
+Users: tools/hv/lsvmbus
diff --git a/MAINTAINERS b/MAINTAINERS
index fd60784..45ef1e1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4956,6 +4956,7 @@ F: drivers/scsi/storvsc_drv.c
F: drivers/video/fbdev/hyperv_fb.c
F: include/linux/hyperv.h
F: tools/hv/
+F: Documentation/ABI/stable/sysfs-bus-vmbus
I2C OVER PARALLEL PORT
M: Jean Delvare <jdelvare@suse.de>
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 11/13] cpu-hotplug: convert cpu_hotplug_disabled to a counter
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
` (8 preceding siblings ...)
2015-08-05 7:52 ` [PATCH 10/13] Drivers: hv: vmbus: document the VMBus sysfs files K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 12/13] cpu-hotplug: export cpu_hotplug_enable/cpu_hotplug_disable K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 13/13] Drivers: hv: vmbus: use cpu_hotplug_enable/disable K. Y. Srinivasan
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
From: Vitaly Kuznetsov <vkuznets@redhat.com>
As a prerequisite to exporting cpu_hotplug_enable/cpu_hotplug_disable
functions to modules we need to convert cpu_hotplug_disabled to a counter
to properly support disable -> disable -> enable call sequences. E.g.
after Hyper-V vmbus module (which is supposed to be the first user of
exported cpu_hotplug_enable/cpu_hotplug_disable) did cpu_hotplug_disable()
hibernate path calls disable_nonboot_cpus() and if we hit an error in
_cpu_down() enable_nonboot_cpus() will be called on the failure path (thus
making cpu_hotplug_disabled = 0 and leaving cpu hotplug in 'enabled'
state). Same problem is possible if more than 1 module use
cpu_hotplug_disable/cpu_hotplug_enable on their load/unload paths. When
one of these modules is been unloaded it is logical to leave cpu hotplug
in 'disabled' state.
To support the change we need to increse cpu_hotplug_disabled counter
in disable_nonboot_cpus() unconditionally as all users of
disable_nonboot_cpus() are supposed to do enable_nonboot_cpus() in case
an error was returned.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
Documentation/power/suspend-and-cpuhotplug.txt | 6 +++---
kernel/cpu.c | 21 +++++++++++++--------
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/Documentation/power/suspend-and-cpuhotplug.txt b/Documentation/power/suspend-and-cpuhotplug.txt
index 2850df3..2fc9095 100644
--- a/Documentation/power/suspend-and-cpuhotplug.txt
+++ b/Documentation/power/suspend-and-cpuhotplug.txt
@@ -72,7 +72,7 @@ More details follow:
|
v
Disable regular cpu hotplug
- by setting cpu_hotplug_disabled=1
+ by increasing cpu_hotplug_disabled
|
v
Release cpu_add_remove_lock
@@ -89,7 +89,7 @@ Resuming back is likewise, with the counterparts being (in the order of
execution during resume):
* enable_nonboot_cpus() which involves:
| Acquire cpu_add_remove_lock
- | Reset cpu_hotplug_disabled to 0, thereby enabling regular cpu hotplug
+ | Decrease cpu_hotplug_disabled, thereby enabling regular cpu hotplug
| Call _cpu_up() [for all those cpus in the frozen_cpus mask, in a loop]
| Release cpu_add_remove_lock
v
@@ -120,7 +120,7 @@ after the entire cycle is complete (i.e., suspend + resume).
Acquire cpu_add_remove_lock
|
v
- If cpu_hotplug_disabled is 1
+ If cpu_hotplug_disabled > 0
return gracefully
|
|
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 6a37454..1225fc2 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -191,14 +191,14 @@ void cpu_hotplug_done(void)
void cpu_hotplug_disable(void)
{
cpu_maps_update_begin();
- cpu_hotplug_disabled = 1;
+ cpu_hotplug_disabled++;
cpu_maps_update_done();
}
void cpu_hotplug_enable(void)
{
cpu_maps_update_begin();
- cpu_hotplug_disabled = 0;
+ WARN_ON(--cpu_hotplug_disabled < 0);
cpu_maps_update_done();
}
@@ -617,13 +617,18 @@ int disable_nonboot_cpus(void)
}
}
- if (!error) {
+ if (!error)
BUG_ON(num_online_cpus() > 1);
- /* Make sure the CPUs won't be enabled by someone else */
- cpu_hotplug_disabled = 1;
- } else {
+ else
pr_err("Non-boot CPUs are not disabled\n");
- }
+
+ /*
+ * Make sure the CPUs won't be enabled by someone else. We need to do
+ * this even in case of failure as all disable_nonboot_cpus() users are
+ * supposed to do enable_nonboot_cpus() on the failure path.
+ */
+ cpu_hotplug_disabled++;
+
cpu_maps_update_done();
return error;
}
@@ -642,7 +647,7 @@ void __ref enable_nonboot_cpus(void)
/* Allow everyone to use the CPU hotplug again */
cpu_maps_update_begin();
- cpu_hotplug_disabled = 0;
+ WARN_ON(--cpu_hotplug_disabled < 0);
if (cpumask_empty(frozen_cpus))
goto out;
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 12/13] cpu-hotplug: export cpu_hotplug_enable/cpu_hotplug_disable
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
` (9 preceding siblings ...)
2015-08-05 7:52 ` [PATCH 11/13] cpu-hotplug: convert cpu_hotplug_disabled to a counter K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 13/13] Drivers: hv: vmbus: use cpu_hotplug_enable/disable K. Y. Srinivasan
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
From: Vitaly Kuznetsov <vkuznets@redhat.com>
Hyper-V module needs to disable cpu hotplug (offlining) as there is no
support from hypervisor side to reassign already opened event channels
to a different CPU. Currently it is been done by altering
smp_ops.cpu_disable but it is hackish.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
kernel/cpu.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 1225fc2..18f00ae 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -194,6 +194,7 @@ void cpu_hotplug_disable(void)
cpu_hotplug_disabled++;
cpu_maps_update_done();
}
+EXPORT_SYMBOL_GPL(cpu_hotplug_disable);
void cpu_hotplug_enable(void)
{
@@ -201,7 +202,7 @@ void cpu_hotplug_enable(void)
WARN_ON(--cpu_hotplug_disabled < 0);
cpu_maps_update_done();
}
-
+EXPORT_SYMBOL_GPL(cpu_hotplug_enable);
#endif /* CONFIG_HOTPLUG_CPU */
/* Need to know about CPUs going up/down? */
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 13/13] Drivers: hv: vmbus: use cpu_hotplug_enable/disable
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
` (10 preceding siblings ...)
2015-08-05 7:52 ` [PATCH 12/13] cpu-hotplug: export cpu_hotplug_enable/cpu_hotplug_disable K. Y. Srinivasan
@ 2015-08-05 7:52 ` K. Y. Srinivasan
11 siblings, 0 replies; 15+ messages in thread
From: K. Y. Srinivasan @ 2015-08-05 7:52 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
From: Vitaly Kuznetsov <vkuznets@redhat.com>
Commit e513229b4c38 ("Drivers: hv: vmbus: prevent cpu offlining on newer
hypervisors") was altering smp_ops.cpu_disable to prevent CPU offlining.
We can bo better by using cpu_hotplug_enable/disable functions instead of
such hard-coding.
Reported-by: Radim Kr.má <rkrcmar@redhat.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/vmbus_drv.c | 38 ++++----------------------------------
1 files changed, 4 insertions(+), 34 deletions(-)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 50100ec..0a344fa 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -828,38 +828,6 @@ static void vmbus_isr(void)
}
}
-#ifdef CONFIG_HOTPLUG_CPU
-static int hyperv_cpu_disable(void)
-{
- return -ENOSYS;
-}
-
-static void hv_cpu_hotplug_quirk(bool vmbus_loaded)
-{
- static void *previous_cpu_disable;
-
- /*
- * Offlining a CPU when running on newer hypervisors (WS2012R2, Win8,
- * ...) is not supported at this moment as channel interrupts are
- * distributed across all of them.
- */
-
- if ((vmbus_proto_version == VERSION_WS2008) ||
- (vmbus_proto_version == VERSION_WIN7))
- return;
-
- if (vmbus_loaded) {
- previous_cpu_disable = smp_ops.cpu_disable;
- smp_ops.cpu_disable = hyperv_cpu_disable;
- pr_notice("CPU offlining is not supported by hypervisor\n");
- } else if (previous_cpu_disable)
- smp_ops.cpu_disable = previous_cpu_disable;
-}
-#else
-static void hv_cpu_hotplug_quirk(bool vmbus_loaded)
-{
-}
-#endif
/*
* vmbus_bus_init -Main vmbus driver initialization routine.
@@ -901,7 +869,8 @@ static int vmbus_bus_init(int irq)
if (ret)
goto err_alloc;
- hv_cpu_hotplug_quirk(true);
+ if (vmbus_proto_version > VERSION_WIN7)
+ cpu_hotplug_disable();
/*
* Only register if the crash MSRs are available
@@ -1364,7 +1333,8 @@ static void __exit vmbus_exit(void)
}
hv_synic_free();
acpi_bus_unregister_driver(&vmbus_acpi_driver);
- hv_cpu_hotplug_quirk(false);
+ if (vmbus_proto_version > VERSION_WIN7)
+ cpu_hotplug_enable();
}
--
1.7.4.1
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2015-08-05 6:52 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-05 7:52 [PATCH 00/13] Drivers: hv: vmbus: Miscellaneous fixes K. Y. Srinivasan
2015-08-05 6:29 ` KY Srinivasan
2015-08-05 7:52 ` [PATCH 01/13] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 02/13] drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 03/13] Drivers: hv: vmbus: Improve the CPU affiliation for channels K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 04/13] Drivers: hv: vmbus: Further improve CPU affiliation logic K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 05/13] Drivers: hv_vmbus: Fix signal to host condition K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 06/13] drivers/hv: Migrate to new 'set-state' interface K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 07/13] Drivers: hv: vmbus: Implement a clocksource based on the TSC page K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 08/13] Drivers: hv: vmbus: add a sysfs attr to show the binding of channel/VP K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 09/13] tools: hv: add a python script lsvmbus to list VMBus devices K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 10/13] Drivers: hv: vmbus: document the VMBus sysfs files K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 11/13] cpu-hotplug: convert cpu_hotplug_disabled to a counter K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 12/13] cpu-hotplug: export cpu_hotplug_enable/cpu_hotplug_disable K. Y. Srinivasan
2015-08-05 7:52 ` [PATCH 13/13] Drivers: hv: vmbus: use cpu_hotplug_enable/disable K. Y. Srinivasan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome