* [PATCH 0/7] Drivers: hv: Collection fixes and enhancements
@ 2015-02-28 19:38 K. Y. Srinivasan
2015-02-28 19:38 ` [PATCH 1/7] Drivers: hv: hv_balloon: eliminate the trylock path in acquire/release_region_mutex K. Y. Srinivasan
0 siblings, 1 reply; 8+ messages in thread
From: K. Y. Srinivasan @ 2015-02-28 19:38 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets; +Cc: K. Y. Srinivasan
This patch-set has a collection of fixes to the balloon driver as well
as some enhancements to the vmbus driver. Nick has implemented
a feature for notifying the host in the event of a guest panic.
I have implemented a couple of APIs for sending messages over the
VMBUS that gives more control to the users. This will help enable
batching of messages over VMBUS.
K. Y. Srinivasan (3):
Drivers: hv: vmbus: Use a round-robin algorithm for picking the
outgoing channel
Drivers: hv: vmbus: Suport an API to send pagebuffers with additional
control
Drivers: hv: vmbus: Suport an API to send packet with additional
control
Nick Meier (1):
Drivers: hv: vmbus: Add support for VMBus panic notifier handler
Vitaly Kuznetsov (3):
Drivers: hv: hv_balloon: eliminate the trylock path in
acquire/release_region_mutex
Drivers: hv: hv_balloon: report offline pages as being used
Drivers: hv: hv_balloon: refuse to balloon below the floor
drivers/hv/channel.c | 76 ++++++++++++++++++++++++++++++-------------
drivers/hv/channel_mgmt.c | 30 ++++++++--------
drivers/hv/hv_balloon.c | 79 +++++++++++++++++++++++---------------------
drivers/hv/hyperv_vmbus.h | 11 ++++++
drivers/hv/vmbus_drv.c | 36 ++++++++++++++++++++
include/linux/hyperv.h | 20 +++++++++++
6 files changed, 176 insertions(+), 76 deletions(-)
--
1.7.4.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/7] Drivers: hv: hv_balloon: eliminate the trylock path in acquire/release_region_mutex
2015-02-28 19:38 [PATCH 0/7] Drivers: hv: Collection fixes and enhancements K. Y. Srinivasan
@ 2015-02-28 19:38 ` K. Y. Srinivasan
2015-02-28 19:38 ` [PATCH 2/7] Drivers: hv: hv_balloon: report offline pages as being used K. Y. Srinivasan
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: K. Y. Srinivasan @ 2015-02-28 19:38 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets; +Cc: K. Y. Srinivasan
From: Vitaly Kuznetsov <vkuznets@redhat.com>
When many memory regions are being added and automatically onlined the
following lockup is sometimes observed:
INFO: task udevd:1872 blocked for more than 120 seconds.
...
Call Trace:
[<ffffffff816ec0bc>] schedule_timeout+0x22c/0x350
[<ffffffff816eb98f>] wait_for_common+0x10f/0x160
[<ffffffff81067650>] ? default_wake_function+0x0/0x20
[<ffffffff816eb9fd>] wait_for_completion+0x1d/0x20
[<ffffffff8144cb9c>] hv_memory_notifier+0xdc/0x120
[<ffffffff816f298c>] notifier_call_chain+0x4c/0x70
...
When several memory blocks are going online simultaneously we got several
hv_memory_notifier() trying to acquire the ha_region_mutex. When this mutex is
being held by hot_add_req() all these competing acquire_region_mutex() do
mutex_trylock, fail, and queue themselves into wait_for_completion(..). However
when we do complete() from release_region_mutex() only one of them wakes up.
This could be solved by changing complete() -> complete_all() memory onlining
can be delayed as well, in that case we can still get several
hv_memory_notifier() runners at the same time trying to grab the mutex.
Only one of them will succeed and the others will hang for forever as
complete() is not being called. We don't see this issue often because we have
5sec onlining timeout in hv_mem_hot_add() and usually all udev events arrive
in this time frame.
Get rid of the trylock path, waiting on the mutex is supposed to provide the
required serialization.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/hv_balloon.c | 35 ++++++-----------------------------
1 files changed, 6 insertions(+), 29 deletions(-)
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 965c37a..ea3d33c 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -534,7 +534,6 @@ struct hv_dynmem_device {
struct task_struct *thread;
struct mutex ha_region_mutex;
- struct completion waiter_event;
/*
* A list of hot-add regions.
@@ -554,38 +553,17 @@ static struct hv_dynmem_device dm_device;
static void post_status(struct hv_dynmem_device *dm);
#ifdef CONFIG_MEMORY_HOTPLUG
-static void acquire_region_mutex(bool trylock)
-{
- if (trylock) {
- reinit_completion(&dm_device.waiter_event);
- while (!mutex_trylock(&dm_device.ha_region_mutex))
- wait_for_completion(&dm_device.waiter_event);
- } else {
- mutex_lock(&dm_device.ha_region_mutex);
- }
-}
-
-static void release_region_mutex(bool trylock)
-{
- if (trylock) {
- mutex_unlock(&dm_device.ha_region_mutex);
- } else {
- mutex_unlock(&dm_device.ha_region_mutex);
- complete(&dm_device.waiter_event);
- }
-}
-
static int hv_memory_notifier(struct notifier_block *nb, unsigned long val,
void *v)
{
switch (val) {
case MEM_GOING_ONLINE:
- acquire_region_mutex(true);
+ mutex_lock(&dm_device.ha_region_mutex);
break;
case MEM_ONLINE:
case MEM_CANCEL_ONLINE:
- release_region_mutex(true);
+ mutex_unlock(&dm_device.ha_region_mutex);
if (dm_device.ha_waiting) {
dm_device.ha_waiting = false;
complete(&dm_device.ol_waitevent);
@@ -646,7 +624,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size,
init_completion(&dm_device.ol_waitevent);
dm_device.ha_waiting = true;
- release_region_mutex(false);
+ mutex_unlock(&dm_device.ha_region_mutex);
nid = memory_add_physaddr_to_nid(PFN_PHYS(start_pfn));
ret = add_memory(nid, PFN_PHYS((start_pfn)),
(HA_CHUNK << PAGE_SHIFT));
@@ -675,7 +653,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size,
* have not been "onlined" within the allowed time.
*/
wait_for_completion_timeout(&dm_device.ol_waitevent, 5*HZ);
- acquire_region_mutex(false);
+ mutex_lock(&dm_device.ha_region_mutex);
post_status(&dm_device);
}
@@ -886,7 +864,7 @@ static void hot_add_req(struct work_struct *dummy)
resp.hdr.size = sizeof(struct dm_hot_add_response);
#ifdef CONFIG_MEMORY_HOTPLUG
- acquire_region_mutex(false);
+ mutex_lock(&dm_device.ha_region_mutex);
pg_start = dm->ha_wrk.ha_page_range.finfo.start_page;
pfn_cnt = dm->ha_wrk.ha_page_range.finfo.page_cnt;
@@ -918,7 +896,7 @@ static void hot_add_req(struct work_struct *dummy)
if (do_hot_add)
resp.page_count = process_hot_add(pg_start, pfn_cnt,
rg_start, rg_sz);
- release_region_mutex(false);
+ mutex_unlock(&dm_device.ha_region_mutex);
#endif
/*
* The result field of the response structure has the
@@ -1440,7 +1418,6 @@ static int balloon_probe(struct hv_device *dev,
dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7;
init_completion(&dm_device.host_event);
init_completion(&dm_device.config_event);
- init_completion(&dm_device.waiter_event);
INIT_LIST_HEAD(&dm_device.ha_region_list);
mutex_init(&dm_device.ha_region_mutex);
INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/7] Drivers: hv: hv_balloon: report offline pages as being used
2015-02-28 19:38 ` [PATCH 1/7] Drivers: hv: hv_balloon: eliminate the trylock path in acquire/release_region_mutex K. Y. Srinivasan
@ 2015-02-28 19:38 ` K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 3/7] Drivers: hv: hv_balloon: refuse to balloon below the floor K. Y. Srinivasan
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: K. Y. Srinivasan @ 2015-02-28 19:38 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets; +Cc: K. Y. Srinivasan
From: Vitaly Kuznetsov <vkuznets@redhat.com>
When hot-added memory pages are not brought online or when some memory blocks
are sent offline the subsequent ballooning process kills the guest with OOM
killer. This happens as we don't report these pages as neither used nor free
and apparently host algorithm considers them as being unused. Keep track of
all online/offline operations and report all currently offline pages as being
used so host won't try to balloon them out.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/hv_balloon.c | 33 ++++++++++++++++++++++++---------
1 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index ea3d33c..53932b3 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -503,6 +503,8 @@ struct hv_dynmem_device {
* Number of pages we have currently ballooned out.
*/
unsigned int num_pages_ballooned;
+ unsigned int num_pages_onlined;
+ unsigned int num_pages_added;
/*
* State to manage the ballooning (up) operation.
@@ -556,12 +558,15 @@ static void post_status(struct hv_dynmem_device *dm);
static int hv_memory_notifier(struct notifier_block *nb, unsigned long val,
void *v)
{
+ struct memory_notify *mem = (struct memory_notify *)v;
+
switch (val) {
case MEM_GOING_ONLINE:
mutex_lock(&dm_device.ha_region_mutex);
break;
case MEM_ONLINE:
+ dm_device.num_pages_onlined += mem->nr_pages;
case MEM_CANCEL_ONLINE:
mutex_unlock(&dm_device.ha_region_mutex);
if (dm_device.ha_waiting) {
@@ -570,8 +575,12 @@ static int hv_memory_notifier(struct notifier_block *nb, unsigned long val,
}
break;
- case MEM_GOING_OFFLINE:
case MEM_OFFLINE:
+ mutex_lock(&dm_device.ha_region_mutex);
+ dm_device.num_pages_onlined -= mem->nr_pages;
+ mutex_unlock(&dm_device.ha_region_mutex);
+ break;
+ case MEM_GOING_OFFLINE:
case MEM_CANCEL_OFFLINE:
break;
}
@@ -896,6 +905,8 @@ static void hot_add_req(struct work_struct *dummy)
if (do_hot_add)
resp.page_count = process_hot_add(pg_start, pfn_cnt,
rg_start, rg_sz);
+
+ dm->num_pages_added += resp.page_count;
mutex_unlock(&dm_device.ha_region_mutex);
#endif
/*
@@ -1009,17 +1020,21 @@ static void post_status(struct hv_dynmem_device *dm)
status.hdr.trans_id = atomic_inc_return(&trans_id);
/*
- * The host expects the guest to report free memory.
- * Further, the host expects the pressure information to
- * include the ballooned out pages.
- * For a given amount of memory that we are managing, we
- * need to compute a floor below which we should not balloon.
- * Compute this and add it to the pressure report.
+ * The host expects the guest to report free and committed memory.
+ * Furthermore, the host expects the pressure information to include
+ * the ballooned out pages. For a given amount of memory that we are
+ * managing we need to compute a floor below which we should not
+ * balloon. Compute this and add it to the pressure report.
+ * We also need to report all offline pages (num_pages_added -
+ * num_pages_onlined) as committed to the host, otherwise it can try
+ * asking us to balloon them out.
*/
status.num_avail = val.freeram;
status.num_committed = vm_memory_committed() +
- dm->num_pages_ballooned +
- compute_balloon_floor();
+ dm->num_pages_ballooned +
+ (dm->num_pages_added > dm->num_pages_onlined ?
+ dm->num_pages_added - dm->num_pages_onlined : 0) +
+ compute_balloon_floor();
/*
* If our transaction ID is no longer current, just don't
--
1.7.4.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/7] Drivers: hv: hv_balloon: refuse to balloon below the floor
2015-02-28 19:38 ` [PATCH 1/7] Drivers: hv: hv_balloon: eliminate the trylock path in acquire/release_region_mutex K. Y. Srinivasan
2015-02-28 19:38 ` [PATCH 2/7] Drivers: hv: hv_balloon: report offline pages as being used K. Y. Srinivasan
@ 2015-02-28 19:39 ` K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 4/7] Drivers: hv: vmbus: Add support for VMBus panic notifier handler K. Y. Srinivasan
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: K. Y. Srinivasan @ 2015-02-28 19:39 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets; +Cc: K. Y. Srinivasan
From: Vitaly Kuznetsov <vkuznets@redhat.com>
When host asks us to balloon up we need to be sure we're not committing suicide
by overballooning. Use already existent 'floor' metric as our lowest possible
value for free ram.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/hv_balloon.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 53932b3..c5bb872 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -1138,6 +1138,8 @@ static void balloon_up(struct work_struct *dummy)
bool alloc_error;
bool done = false;
int i;
+ struct sysinfo val;
+ unsigned long floor;
/* The host balloons pages in 2M granularity. */
WARN_ON_ONCE(num_pages % PAGES_IN_2M != 0);
@@ -1148,6 +1150,15 @@ static void balloon_up(struct work_struct *dummy)
*/
alloc_unit = 512;
+ si_meminfo(&val);
+ floor = compute_balloon_floor();
+
+ /* Refuse to balloon below the floor, keep the 2M granularity. */
+ if (val.freeram - num_pages < floor) {
+ num_pages = val.freeram > floor ? (val.freeram - floor) : 0;
+ num_pages -= num_pages % PAGES_IN_2M;
+ }
+
while (!done) {
bl_resp = (struct dm_balloon_response *)send_buffer;
memset(send_buffer, 0, PAGE_SIZE);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/7] Drivers: hv: vmbus: Add support for VMBus panic notifier handler
2015-02-28 19:38 ` [PATCH 1/7] Drivers: hv: hv_balloon: eliminate the trylock path in acquire/release_region_mutex K. Y. Srinivasan
2015-02-28 19:38 ` [PATCH 2/7] Drivers: hv: hv_balloon: report offline pages as being used K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 3/7] Drivers: hv: hv_balloon: refuse to balloon below the floor K. Y. Srinivasan
@ 2015-02-28 19:39 ` K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 5/7] Drivers: hv: vmbus: Use a round-robin algorithm for picking the outgoing channel K. Y. Srinivasan
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: K. Y. Srinivasan @ 2015-02-28 19:39 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets
Cc: Nick Meier, K. Y. Srinivasan
From: Nick Meier <nmeier@microsoft.com>
Hyper-V allows a guest to notify the Hyper-V host that a panic
condition occured. This notification can include up to five 64
bit values. These 64 bit values are written into crash MSRs.
Once the data has been written into the crash MSRs, the host is
then notified by writing into a Crash Control MSR. On the Hyper-V
host, the panic notification data is captured in the Windows Event
log as a 18590 event.
Crash MSRs are defined in appendix H of the Hypervisor Top Level
Functional Specification. At the time of this patch, v4.0 is the
current functional spec. The URL for the v4.0 document is:
http://download.microsoft.com/download/A/B/4/AB43A34E-BDD0-4FA6-BDEF-79EEF16E880B/Hypervisor Top Level Functional Specification v4.0.docx
Signed-off-by: Nick Meier <nmeier@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/hyperv_vmbus.h | 11 +++++++++++
drivers/hv/vmbus_drv.c | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index b055e53..88af4ec 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -49,6 +49,17 @@ enum hv_cpuid_function {
HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005,
};
+#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE 0x400
+
+#define HV_X64_MSR_CRASH_P0 0x40000100
+#define HV_X64_MSR_CRASH_P1 0x40000101
+#define HV_X64_MSR_CRASH_P2 0x40000102
+#define HV_X64_MSR_CRASH_P3 0x40000103
+#define HV_X64_MSR_CRASH_P4 0x40000104
+#define HV_X64_MSR_CRASH_CTL 0x40000105
+
+#define HV_CRASH_CTL_CRASH_NOTIFY 0x8000000000000000
+
/* Define version of the synthetic interrupt controller. */
#define HV_SYNIC_VERSION (1)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f84ce5e..6cac44c 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -37,6 +37,8 @@
#include <asm/hyperv.h>
#include <asm/hypervisor.h>
#include <asm/mshyperv.h>
+#include <linux/notifier.h>
+#include <linux/ptrace.h>
#include "hyperv_vmbus.h"
static struct acpi_device *hv_acpi_dev;
@@ -45,6 +47,31 @@ static struct tasklet_struct msg_dpc;
static struct completion probe_event;
static int irq;
+
+int hyperv_panic_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct pt_regs *regs;
+
+ regs = current_pt_regs();
+
+ wrmsrl(HV_X64_MSR_CRASH_P0, regs->ip);
+ wrmsrl(HV_X64_MSR_CRASH_P1, regs->ax);
+ wrmsrl(HV_X64_MSR_CRASH_P2, regs->bx);
+ wrmsrl(HV_X64_MSR_CRASH_P3, regs->cx);
+ wrmsrl(HV_X64_MSR_CRASH_P4, regs->dx);
+
+ /*
+ * Let Hyper-V know there is crash data available
+ */
+ wrmsrl(HV_X64_MSR_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block hyperv_panic_block = {
+ .notifier_call = hyperv_panic_event,
+};
+
struct resource hyperv_mmio = {
.name = "hyperv mmio",
.flags = IORESOURCE_MEM,
@@ -795,6 +822,15 @@ static int vmbus_bus_init(int irq)
goto err_alloc;
hv_cpu_hotplug_quirk(true);
+
+ /*
+ * Only register if the crash MSRs are available
+ */
+ if (ms_hyperv.features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &hyperv_panic_block);
+ }
+
vmbus_request_offers();
return 0;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/7] Drivers: hv: vmbus: Use a round-robin algorithm for picking the outgoing channel
2015-02-28 19:38 ` [PATCH 1/7] Drivers: hv: hv_balloon: eliminate the trylock path in acquire/release_region_mutex K. Y. Srinivasan
` (2 preceding siblings ...)
2015-02-28 19:39 ` [PATCH 4/7] Drivers: hv: vmbus: Add support for VMBus panic notifier handler K. Y. Srinivasan
@ 2015-02-28 19:39 ` K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 6/7] Drivers: hv: vmbus: Suport an API to send pagebuffers with additional control K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 7/7] Drivers: hv: vmbus: Suport an API to send packet " K. Y. Srinivasan
5 siblings, 0 replies; 8+ messages in thread
From: K. Y. Srinivasan @ 2015-02-28 19:39 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets; +Cc: K. Y. Srinivasan
The current algorithm for picking an outgoing channel was not distributing
the load well. Implement a simple round-robin scheme to ensure good
distribution of the outgoing traffic.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
---
drivers/hv/channel_mgmt.c | 30 +++++++++++++++---------------
include/linux/hyperv.h | 3 +++
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index b1e5a5f..6117891 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -350,6 +350,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
}
newchannel->state = CHANNEL_OPEN_STATE;
+ channel->num_sc++;
if (channel->sc_creation_callback != NULL)
/*
* We need to invoke the sub-channel creation
@@ -862,9 +863,8 @@ cleanup:
/*
* Retrieve the (sub) channel on which to send an outgoing request.
- * When a primary channel has multiple sub-channels, we choose a
- * channel whose VCPU binding is closest to the VCPU on which
- * this call is being made.
+ * When a primary channel has multiple sub-channels, we try to
+ * distribute the load equally amongst all available channels.
*/
struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
{
@@ -872,11 +872,19 @@ struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
int cur_cpu;
struct vmbus_channel *cur_channel;
struct vmbus_channel *outgoing_channel = primary;
- int cpu_distance, new_cpu_distance;
+ int next_channel;
+ int i = 1;
if (list_empty(&primary->sc_list))
return outgoing_channel;
+ next_channel = primary->next_oc++;
+
+ if (next_channel > (primary->num_sc)) {
+ primary->next_oc = 0;
+ return outgoing_channel;
+ }
+
cur_cpu = hv_context.vp_index[get_cpu()];
put_cpu();
list_for_each_safe(cur, tmp, &primary->sc_list) {
@@ -887,18 +895,10 @@ struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
if (cur_channel->target_vp == cur_cpu)
return cur_channel;
- cpu_distance = ((outgoing_channel->target_vp > cur_cpu) ?
- (outgoing_channel->target_vp - cur_cpu) :
- (cur_cpu - outgoing_channel->target_vp));
-
- new_cpu_distance = ((cur_channel->target_vp > cur_cpu) ?
- (cur_channel->target_vp - cur_cpu) :
- (cur_cpu - cur_channel->target_vp));
-
- if (cpu_distance < new_cpu_distance)
- continue;
+ if (i == next_channel)
+ return cur_channel;
- outgoing_channel = cur_channel;
+ i++;
}
return outgoing_channel;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index dd92a85..1ca5824 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -761,6 +761,9 @@ struct vmbus_channel {
* link up channels based on their CPU affinity.
*/
struct list_head percpu_list;
+
+ int num_sc;
+ int next_oc;
};
static inline void set_channel_read_state(struct vmbus_channel *c, bool state)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/7] Drivers: hv: vmbus: Suport an API to send pagebuffers with additional control
2015-02-28 19:38 ` [PATCH 1/7] Drivers: hv: hv_balloon: eliminate the trylock path in acquire/release_region_mutex K. Y. Srinivasan
` (3 preceding siblings ...)
2015-02-28 19:39 ` [PATCH 5/7] Drivers: hv: vmbus: Use a round-robin algorithm for picking the outgoing channel K. Y. Srinivasan
@ 2015-02-28 19:39 ` K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 7/7] Drivers: hv: vmbus: Suport an API to send packet " K. Y. Srinivasan
5 siblings, 0 replies; 8+ messages in thread
From: K. Y. Srinivasan @ 2015-02-28 19:39 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets; +Cc: K. Y. Srinivasan
Implement an API for sending pagebuffers that gives more control to the client
in terms of setting the vmbus flags as well as deciding when to
notify the host. This will be useful for enabling batch processing.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/channel.c | 33 +++++++++++++++++++++++++++------
include/linux/hyperv.h | 9 +++++++++
2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 9b79aca..f060d1f 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -636,13 +636,18 @@ int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
EXPORT_SYMBOL(vmbus_sendpacket);
/*
- * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
- * packets using a GPADL Direct packet type.
+ * vmbus_sendpacket_pagebuffer_ctl - Send a range of single-page buffer
+ * packets using a GPADL Direct packet type. This interface allows you
+ * to control notifying the host. This will be useful for sending
+ * batched data. Also the sender can control the send flags
+ * explicitly.
*/
-int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
+int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
struct hv_page_buffer pagebuffers[],
u32 pagecount, void *buffer, u32 bufferlen,
- u64 requestid)
+ u64 requestid,
+ u32 flags,
+ bool kick_q)
{
int ret;
int i;
@@ -670,7 +675,7 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
/* Setup the descriptor */
desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
- desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
+ desc.flags = flags;
desc.dataoffset8 = descsize >> 3; /* in 8-bytes grandularity */
desc.length8 = (u16)(packetlen_aligned >> 3);
desc.transactionid = requestid;
@@ -691,11 +696,27 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
- if (ret == 0 && signal)
+ if ((ret == 0) && kick_q && signal)
vmbus_setevent(channel);
return ret;
}
+
+/*
+ * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
+ * packets using a GPADL Direct packet type.
+ */
+int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
+ struct hv_page_buffer pagebuffers[],
+ u32 pagecount, void *buffer, u32 bufferlen,
+ u64 requestid)
+{
+ u32 flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
+ return vmbus_sendpacket_pagebuffer_ctl(channel, pagebuffers, pagecount,
+ buffer, bufferlen, requestid,
+ flags, true);
+
+}
EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
/*
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 1ca5824..86e1a7a 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -874,6 +874,15 @@ extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
u32 bufferlen,
u64 requestid);
+extern int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
+ struct hv_page_buffer pagebuffers[],
+ u32 pagecount,
+ void *buffer,
+ u32 bufferlen,
+ u64 requestid,
+ u32 flags,
+ bool kick_q);
+
extern int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
struct hv_multipage_buffer *mpb,
void *buffer,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 7/7] Drivers: hv: vmbus: Suport an API to send packet with additional control
2015-02-28 19:38 ` [PATCH 1/7] Drivers: hv: hv_balloon: eliminate the trylock path in acquire/release_region_mutex K. Y. Srinivasan
` (4 preceding siblings ...)
2015-02-28 19:39 ` [PATCH 6/7] Drivers: hv: vmbus: Suport an API to send pagebuffers with additional control K. Y. Srinivasan
@ 2015-02-28 19:39 ` K. Y. Srinivasan
5 siblings, 0 replies; 8+ messages in thread
From: K. Y. Srinivasan @ 2015-02-28 19:39 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets; +Cc: K. Y. Srinivasan
Implement an API that gives additional control on the what VMBUS flags will be
set as well as if the host needs to be signalled. This API will be
useful for clients that want to batch up requests to the host.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/channel.c | 43 ++++++++++++++++++++++++++-----------------
include/linux/hyperv.h | 8 ++++++++
2 files changed, 34 insertions(+), 17 deletions(-)
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index f060d1f..da53180 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -584,23 +584,9 @@ void vmbus_close(struct vmbus_channel *channel)
}
EXPORT_SYMBOL_GPL(vmbus_close);
-/**
- * vmbus_sendpacket() - Send the specified buffer on the given channel
- * @channel: Pointer to vmbus_channel structure.
- * @buffer: Pointer to the buffer you want to receive the data into.
- * @bufferlen: Maximum size of what the the buffer will hold
- * @requestid: Identifier of the request
- * @type: Type of packet that is being send e.g. negotiate, time
- * packet etc.
- *
- * Sends data in @buffer directly to hyper-v via the vmbus
- * This will send the data unparsed to hyper-v.
- *
- * Mainly used by Hyper-V drivers.
- */
-int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
+int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
u32 bufferlen, u64 requestid,
- enum vmbus_packet_type type, u32 flags)
+ enum vmbus_packet_type type, u32 flags, bool kick_q)
{
struct vmpacket_descriptor desc;
u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen;
@@ -628,11 +614,34 @@ int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
- if (ret == 0 && signal)
+ if ((ret == 0) && kick_q && signal)
vmbus_setevent(channel);
return ret;
}
+EXPORT_SYMBOL(vmbus_sendpacket_ctl);
+
+/**
+ * vmbus_sendpacket() - Send the specified buffer on the given channel
+ * @channel: Pointer to vmbus_channel structure.
+ * @buffer: Pointer to the buffer you want to receive the data into.
+ * @bufferlen: Maximum size of what the the buffer will hold
+ * @requestid: Identifier of the request
+ * @type: Type of packet that is being send e.g. negotiate, time
+ * packet etc.
+ *
+ * Sends data in @buffer directly to hyper-v via the vmbus
+ * This will send the data unparsed to hyper-v.
+ *
+ * Mainly used by Hyper-V drivers.
+ */
+int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
+ u32 bufferlen, u64 requestid,
+ enum vmbus_packet_type type, u32 flags)
+{
+ return vmbus_sendpacket_ctl(channel, buffer, bufferlen, requestid,
+ type, flags, true);
+}
EXPORT_SYMBOL(vmbus_sendpacket);
/*
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 86e1a7a..80e444b 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -867,6 +867,14 @@ extern int vmbus_sendpacket(struct vmbus_channel *channel,
enum vmbus_packet_type type,
u32 flags);
+extern int vmbus_sendpacket_ctl(struct vmbus_channel *channel,
+ void *buffer,
+ u32 bufferLen,
+ u64 requestid,
+ enum vmbus_packet_type type,
+ u32 flags,
+ bool kick_q);
+
extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
struct hv_page_buffer pagebuffers[],
u32 pagecount,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-02-28 18:25 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-28 19:38 [PATCH 0/7] Drivers: hv: Collection fixes and enhancements K. Y. Srinivasan
2015-02-28 19:38 ` [PATCH 1/7] Drivers: hv: hv_balloon: eliminate the trylock path in acquire/release_region_mutex K. Y. Srinivasan
2015-02-28 19:38 ` [PATCH 2/7] Drivers: hv: hv_balloon: report offline pages as being used K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 3/7] Drivers: hv: hv_balloon: refuse to balloon below the floor K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 4/7] Drivers: hv: vmbus: Add support for VMBus panic notifier handler K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 5/7] Drivers: hv: vmbus: Use a round-robin algorithm for picking the outgoing channel K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 6/7] Drivers: hv: vmbus: Suport an API to send pagebuffers with additional control K. Y. Srinivasan
2015-02-28 19:39 ` [PATCH 7/7] Drivers: hv: vmbus: Suport an API to send packet " 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