[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1FB5E1D5CA062146B38059374562DF7266B8C4AC@TK5EX14MBXC128.redmond.corp.microsoft.com>
Date: Wed, 26 May 2010 16:54:39 +0000
From: Haiyang Zhang <haiyangz@...rosoft.com>
To: "'linux-kernel@...r.kernel.org'" <linux-kernel@...r.kernel.org>,
"'devel@...verdev.osuosl.org'" <devel@...verdev.osuosl.org>,
"'virtualization@...ts.osdl.org'" <virtualization@...ts.osdl.org>,
"'gregkh@...e.de'" <gregkh@...e.de>
CC: Hank Janssen <hjanssen@...rosoft.com>
Subject: [PATCH 1/1] staging: hv: Fix race condition on IC channel
initialization (modified)
From: Haiyang Zhang <haiyangz@...rosoft.com>
Subject: [PATCH] staging: hv: Fix race condition on IC channel initialization
There is a possible race condition when hv_utils starts to load immediately
after hv_vmbus is loading - null pointer error could happen.
This patch added an event waiting to ensure all channels are ready before
vmbus_init() returns. So another module won't have any uninitialized channel.
Signed-off-by: Haiyang Zhang <haiyangz@...rosoft.com>
Signed-off-by: Hank Janssen <hjanssen@...rosoft.com>
---
drivers/staging/hv/channel_mgmt.c | 23 +++++++++++++----------
drivers/staging/hv/vmbus_drv.c | 10 ++++++++++
drivers/staging/hv/vmbus_private.h | 1 +
3 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c
index 3f53b4d..f99db1b 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -305,6 +305,7 @@ static void VmbusChannelProcessOffer(void *context)
int ret;
int cnt;
unsigned long flags;
+ static atomic_t ic_channel_initcnt = ATOMIC_INIT(0);
DPRINT_ENTER(VMBUS);
@@ -373,22 +374,24 @@ static void VmbusChannelProcessOffer(void *context)
* can cleanup properly
*/
newChannel->State = CHANNEL_OPEN_STATE;
- cnt = 0;
- while (cnt != MAX_MSG_TYPES) {
+ /* Open IC channels */
+ for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
if (memcmp(&newChannel->OfferMsg.Offer.InterfaceType,
&hv_cb_utils[cnt].data,
- sizeof(struct hv_guid)) == 0) {
+ sizeof(struct hv_guid)) == 0 &&
+ VmbusChannelOpen(newChannel, 2 * PAGE_SIZE,
+ 2 * PAGE_SIZE, NULL, 0,
+ hv_cb_utils[cnt].callback,
+ newChannel) == 0) {
+ hv_cb_utils[cnt].channel = newChannel;
+ mb();
DPRINT_INFO(VMBUS, "%s",
hv_cb_utils[cnt].log_msg);
-
- if (VmbusChannelOpen(newChannel, 2 * PAGE_SIZE,
- 2 * PAGE_SIZE, NULL, 0,
- hv_cb_utils[cnt].callback,
- newChannel) == 0)
- hv_cb_utils[cnt].channel = newChannel;
+ if (atomic_inc_return(&ic_channel_initcnt) ==
+ MAX_MSG_TYPES)
+ osd_WaitEventSet(ic_channel_ready);
}
- cnt++;
}
}
DPRINT_EXIT(VMBUS);
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index c21731a..3ae8981 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -989,6 +989,8 @@ static struct dmi_system_id __initdata microsoft_hv_dmi_table[] = {
};
MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table);
+struct osd_waitevent *ic_channel_ready;
+
static int __init vmbus_init(void)
{
int ret = 0;
@@ -1003,8 +1005,16 @@ static int __init vmbus_init(void)
if (!dmi_check_system(microsoft_hv_dmi_table))
return -ENODEV;
+ ic_channel_ready = osd_WaitEventCreate();
+ if (ic_channel_ready == NULL)
+ return -ENOMEM;
+
ret = vmbus_bus_init(VmbusInitialize);
+ /* Wait until all IC channels are initialized */
+ osd_WaitEventWait(ic_channel_ready);
+
+ kfree(ic_channel_ready);
DPRINT_EXIT(VMBUS_DRV);
return ret;
}
diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h
index 588c667..3fb8dad 100644
--- a/drivers/staging/hv/vmbus_private.h
+++ b/drivers/staging/hv/vmbus_private.h
@@ -130,5 +130,6 @@ int VmbusSetEvent(u32 childRelId);
void VmbusOnEvents(void);
+extern struct osd_waitevent *ic_channel_ready;
#endif /* _VMBUS_PRIVATE_H_ */
--
1.6.3.2
Download attachment "0525-Fix-race-condition-on-IC-channel-initialization.patch" of type "application/octet-stream" (3454 bytes)
Powered by blists - more mailing lists