[PATCH RESEND 16/27] Drivers: hv: vmbus: serialize process_chn_event() and vmbus_close_internal()

2015-12-14 Thread K. Y. Srinivasan
From: Dexuan Cui 

process_chn_event(), running in the tasklet, can race with
vmbus_close_internal() in the case of SMP guest, e.g., when the former is
accessing channel->inbound.ring_buffer, the latter could be freeing the
ring_buffer pages.

To resolve the race, we can serialize them by disabling the tasklet when
the latter is running here.

Signed-off-by: Dexuan Cui 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel.c |   21 +++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index c4dcab0..f7f3d5c 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "hyperv_vmbus.h"
 
@@ -496,8 +497,21 @@ static void reset_channel_cb(void *arg)
 static int vmbus_close_internal(struct vmbus_channel *channel)
 {
struct vmbus_channel_close_channel *msg;
+   struct tasklet_struct *tasklet;
int ret;
 
+   /*
+* process_chn_event(), running in the tasklet, can race
+* with vmbus_close_internal() in the case of SMP guest, e.g., when
+* the former is accessing channel->inbound.ring_buffer, the latter
+* could be freeing the ring_buffer pages.
+*
+* To resolve the race, we can serialize them by disabling the
+* tasklet when the latter is running here.
+*/
+   tasklet = hv_context.event_dpc[channel->target_cpu];
+   tasklet_disable(tasklet);
+
channel->state = CHANNEL_OPEN_STATE;
channel->sc_creation_callback = NULL;
/* Stop callback and cancel the timer asap */
@@ -525,7 +539,7 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
 * If we failed to post the close msg,
 * it is perhaps better to leak memory.
 */
-   return ret;
+   goto out;
}
 
/* Tear down the gpadl for the channel's ring buffer */
@@ -538,7 +552,7 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
 * If we failed to teardown gpadl,
 * it is perhaps better to leak memory.
 */
-   return ret;
+   goto out;
}
}
 
@@ -555,6 +569,9 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
if (channel->rescind)
hv_process_channel_removal(channel,
   channel->offermsg.child_relid);
+out:
+   tasklet_enable(tasklet);
+
return ret;
 }
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND 16/27] Drivers: hv: vmbus: serialize process_chn_event() and vmbus_close_internal()

2015-12-14 Thread K. Y. Srinivasan
From: Dexuan Cui 

process_chn_event(), running in the tasklet, can race with
vmbus_close_internal() in the case of SMP guest, e.g., when the former is
accessing channel->inbound.ring_buffer, the latter could be freeing the
ring_buffer pages.

To resolve the race, we can serialize them by disabling the tasklet when
the latter is running here.

Signed-off-by: Dexuan Cui 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel.c |   21 +++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index c4dcab0..f7f3d5c 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "hyperv_vmbus.h"
 
@@ -496,8 +497,21 @@ static void reset_channel_cb(void *arg)
 static int vmbus_close_internal(struct vmbus_channel *channel)
 {
struct vmbus_channel_close_channel *msg;
+   struct tasklet_struct *tasklet;
int ret;
 
+   /*
+* process_chn_event(), running in the tasklet, can race
+* with vmbus_close_internal() in the case of SMP guest, e.g., when
+* the former is accessing channel->inbound.ring_buffer, the latter
+* could be freeing the ring_buffer pages.
+*
+* To resolve the race, we can serialize them by disabling the
+* tasklet when the latter is running here.
+*/
+   tasklet = hv_context.event_dpc[channel->target_cpu];
+   tasklet_disable(tasklet);
+
channel->state = CHANNEL_OPEN_STATE;
channel->sc_creation_callback = NULL;
/* Stop callback and cancel the timer asap */
@@ -525,7 +539,7 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
 * If we failed to post the close msg,
 * it is perhaps better to leak memory.
 */
-   return ret;
+   goto out;
}
 
/* Tear down the gpadl for the channel's ring buffer */
@@ -538,7 +552,7 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
 * If we failed to teardown gpadl,
 * it is perhaps better to leak memory.
 */
-   return ret;
+   goto out;
}
}
 
@@ -555,6 +569,9 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
if (channel->rescind)
hv_process_channel_removal(channel,
   channel->offermsg.child_relid);
+out:
+   tasklet_enable(tasklet);
+
return ret;
 }
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND 16/27] Drivers: hv: vmbus: serialize process_chn_event() and vmbus_close_internal()

2015-12-11 Thread K. Y. Srinivasan
From: Dexuan Cui 

process_chn_event(), running in the tasklet, can race with
vmbus_close_internal() in the case of SMP guest, e.g., when the former is
accessing channel->inbound.ring_buffer, the latter could be freeing the
ring_buffer pages.

To resolve the race, we can serialize them by disabling the tasklet when
the latter is running here.

Signed-off-by: Dexuan Cui 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel.c |   21 +++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index c4dcab0..f7f3d5c 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "hyperv_vmbus.h"
 
@@ -496,8 +497,21 @@ static void reset_channel_cb(void *arg)
 static int vmbus_close_internal(struct vmbus_channel *channel)
 {
struct vmbus_channel_close_channel *msg;
+   struct tasklet_struct *tasklet;
int ret;
 
+   /*
+* process_chn_event(), running in the tasklet, can race
+* with vmbus_close_internal() in the case of SMP guest, e.g., when
+* the former is accessing channel->inbound.ring_buffer, the latter
+* could be freeing the ring_buffer pages.
+*
+* To resolve the race, we can serialize them by disabling the
+* tasklet when the latter is running here.
+*/
+   tasklet = hv_context.event_dpc[channel->target_cpu];
+   tasklet_disable(tasklet);
+
channel->state = CHANNEL_OPEN_STATE;
channel->sc_creation_callback = NULL;
/* Stop callback and cancel the timer asap */
@@ -525,7 +539,7 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
 * If we failed to post the close msg,
 * it is perhaps better to leak memory.
 */
-   return ret;
+   goto out;
}
 
/* Tear down the gpadl for the channel's ring buffer */
@@ -538,7 +552,7 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
 * If we failed to teardown gpadl,
 * it is perhaps better to leak memory.
 */
-   return ret;
+   goto out;
}
}
 
@@ -555,6 +569,9 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
if (channel->rescind)
hv_process_channel_removal(channel,
   channel->offermsg.child_relid);
+out:
+   tasklet_enable(tasklet);
+
return ret;
 }
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND 16/27] Drivers: hv: vmbus: serialize process_chn_event() and vmbus_close_internal()

2015-12-11 Thread K. Y. Srinivasan
From: Dexuan Cui 

process_chn_event(), running in the tasklet, can race with
vmbus_close_internal() in the case of SMP guest, e.g., when the former is
accessing channel->inbound.ring_buffer, the latter could be freeing the
ring_buffer pages.

To resolve the race, we can serialize them by disabling the tasklet when
the latter is running here.

Signed-off-by: Dexuan Cui 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel.c |   21 +++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index c4dcab0..f7f3d5c 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "hyperv_vmbus.h"
 
@@ -496,8 +497,21 @@ static void reset_channel_cb(void *arg)
 static int vmbus_close_internal(struct vmbus_channel *channel)
 {
struct vmbus_channel_close_channel *msg;
+   struct tasklet_struct *tasklet;
int ret;
 
+   /*
+* process_chn_event(), running in the tasklet, can race
+* with vmbus_close_internal() in the case of SMP guest, e.g., when
+* the former is accessing channel->inbound.ring_buffer, the latter
+* could be freeing the ring_buffer pages.
+*
+* To resolve the race, we can serialize them by disabling the
+* tasklet when the latter is running here.
+*/
+   tasklet = hv_context.event_dpc[channel->target_cpu];
+   tasklet_disable(tasklet);
+
channel->state = CHANNEL_OPEN_STATE;
channel->sc_creation_callback = NULL;
/* Stop callback and cancel the timer asap */
@@ -525,7 +539,7 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
 * If we failed to post the close msg,
 * it is perhaps better to leak memory.
 */
-   return ret;
+   goto out;
}
 
/* Tear down the gpadl for the channel's ring buffer */
@@ -538,7 +552,7 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
 * If we failed to teardown gpadl,
 * it is perhaps better to leak memory.
 */
-   return ret;
+   goto out;
}
}
 
@@ -555,6 +569,9 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
if (channel->rescind)
hv_process_channel_removal(channel,
   channel->offermsg.child_relid);
+out:
+   tasklet_enable(tasklet);
+
return ret;
 }
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/