All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] vmbus: fix missed ring events on boot
@ 2017-03-18  0:19 Stephen Hemminger
  2017-03-18  7:46 ` Dexuan Cui
  0 siblings, 1 reply; 3+ messages in thread
From: Stephen Hemminger @ 2017-03-18  0:19 UTC (permalink / raw)
  To: gregkh, kys, haiyangz; +Cc: stable, devel, Stephen Hemminger

During initialization, the channel initialization code schedules the
tasklet to scan the VMBUS receive event page (i.e. simulates an
interrupt). The problem was that it invokes the tasklet on a different
CPU from where it normally runs and therefore if an event is present,
it will clear the bit but not find the associated channel.

This can lead to missed events, typically stuck tasks, during bootup
when sub channels are being initialized. Typically seen as stuck
boot with 8 or more CPU's.

This patch is not necessary for upstream (4.11 and later) since
commit 631e63a9f346 ("vmbus: change to per channel tasklet").
This changed vmbus code to get rid of common tasklet which
caused the problem.

Cc: stable@vger.kernel.org
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
 drivers/hv/channel.c      | 10 +++++++++-
 drivers/hv/channel_mgmt.c | 26 +++++++++++++++-----------
 2 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index be34547cdb68..a8790498ba2b 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -609,7 +609,15 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
 		get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
 
 out:
-	hv_event_tasklet_enable(channel);
+	if (channel->target_cpu != get_cpu()) {
+		smp_call_function_single(channel->target_cpu,
+					 (smp_call_func_t)hv_event_tasklet_enable,
+					 channel, true);
+		put_cpu();
+	} else {
+		put_cpu();
+		hv_event_tasklet_enable(channel);
+	}
 
 	return ret;
 }
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 0af7e39006c8..021f6da1968d 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -321,12 +321,24 @@ static void free_channel(struct vmbus_channel *channel)
 	kfree(channel);
 }
 
-static void percpu_channel_enq(void *arg)
+static void percpu_channel_enable(void *arg)
 {
 	struct vmbus_channel *channel = arg;
 	int cpu = smp_processor_id();
+	struct tasklet_struct *tasklet
+		= hv_context.event_dpc[cpu];
+
+	/*
+	 * This state is used to indicate a successful open
+	 * so that when we do close the channel normally, we
+	 * can cleanup properly
+	 */
+	channel->state = CHANNEL_OPEN_STATE;
 
 	list_add_tail(&channel->percpu_list, &hv_context.percpu_list[cpu]);
+
+	tasklet_enable(tasklet);
+	tasklet_schedule(tasklet);
 }
 
 static void percpu_channel_deq(void *arg)
@@ -480,20 +492,12 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
 	if (newchannel->target_cpu != get_cpu()) {
 		put_cpu();
 		smp_call_function_single(newchannel->target_cpu,
-					 percpu_channel_enq,
+					 percpu_channel_enable,
 					 newchannel, true);
 	} else {
-		percpu_channel_enq(newchannel);
+		percpu_channel_enable(newchannel);
 		put_cpu();
 	}
-	hv_event_tasklet_enable(newchannel);
-
-	/*
-	 * This state is used to indicate a successful open
-	 * so that when we do close the channel normally, we
-	 * can cleanup properly
-	 */
-	newchannel->state = CHANNEL_OPEN_STATE;
 
 	if (!fnew) {
 		if (channel->sc_creation_callback != NULL)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* RE: [PATCH] vmbus: fix missed ring events on boot
  2017-03-18  0:19 [PATCH] vmbus: fix missed ring events on boot Stephen Hemminger
@ 2017-03-18  7:46 ` Dexuan Cui
  2017-03-18 16:03   ` Stephen Hemminger
  0 siblings, 1 reply; 3+ messages in thread
From: Dexuan Cui @ 2017-03-18  7:46 UTC (permalink / raw)
  To: Stephen Hemminger, gregkh, KY Srinivasan, Haiyang Zhang
  Cc: devel, Stephen Hemminger, stable

> From: devel [mailto:driverdev-devel-bounces@linuxdriverproject.org] On
> Behalf Of Stephen Hemminger
> @@ -609,7 +609,15 @@ static int vmbus_close_internal(struct
> @@ -480,20 +492,12 @@ static void vmbus_process_offer(struct

Hi Stephen,
Thanks for the patch!

hv_event_tasklet_enable() is called in 4 places in 4.10:

vmbus_close_internal, hv_process_channel_removal and 
vmbus_process_offer (twice).

The patch only fixes 2 of the 4 ones.
Should we fix all of them?

Thanks,
-- Dexuan

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] vmbus: fix missed ring events on boot
  2017-03-18  7:46 ` Dexuan Cui
@ 2017-03-18 16:03   ` Stephen Hemminger
  0 siblings, 0 replies; 3+ messages in thread
From: Stephen Hemminger @ 2017-03-18 16:03 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: gregkh, KY Srinivasan, Haiyang Zhang, devel, Stephen Hemminger, stable

On Sat, 18 Mar 2017 07:46:21 +0000
Dexuan Cui <decui@microsoft.com> wrote:

> > From: devel [mailto:driverdev-devel-bounces@linuxdriverproject.org] On
> > Behalf Of Stephen Hemminger
> > @@ -609,7 +609,15 @@ static int vmbus_close_internal(struct
> > @@ -480,20 +492,12 @@ static void vmbus_process_offer(struct  
> 
> Hi Stephen,
> Thanks for the patch!
> 
> hv_event_tasklet_enable() is called in 4 places in 4.10:
> 
> vmbus_close_internal, hv_process_channel_removal and 
> vmbus_process_offer (twice).
> 
> The patch only fixes 2 of the 4 ones.
> Should we fix all of them?
> 
> Thanks,
> -- Dexuan

I am testing a simpler patch that just fixes hv_event_tasklet_enable

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-03-18 16:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-18  0:19 [PATCH] vmbus: fix missed ring events on boot Stephen Hemminger
2017-03-18  7:46 ` Dexuan Cui
2017-03-18 16:03   ` Stephen Hemminger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.