aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hv/connection.c')
-rw-r--r--drivers/hv/connection.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 6ce8b874e833..9b72ebcd37bc 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -111,7 +111,8 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
ret = vmbus_post_msg(msg,
- sizeof(struct vmbus_channel_initiate_contact));
+ sizeof(struct vmbus_channel_initiate_contact),
+ true);
if (ret != 0) {
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
list_del(&msginfo->msglistentry);
@@ -435,7 +436,7 @@ void vmbus_on_event(unsigned long data)
/*
* vmbus_post_msg - Send a msg on the vmbus's message connection
*/
-int vmbus_post_msg(void *buffer, size_t buflen)
+int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep)
{
union hv_connection_id conn_id;
int ret = 0;
@@ -450,7 +451,7 @@ int vmbus_post_msg(void *buffer, size_t buflen)
* insufficient resources. Retry the operation a couple of
* times before giving up.
*/
- while (retries < 20) {
+ while (retries < 100) {
ret = hv_post_message(conn_id, 1, buffer, buflen);
switch (ret) {
@@ -473,8 +474,14 @@ int vmbus_post_msg(void *buffer, size_t buflen)
}
retries++;
- udelay(usec);
- if (usec < 2048)
+ if (can_sleep && usec > 1000)
+ msleep(usec / 1000);
+ else if (usec < MAX_UDELAY_MS * 1000)
+ udelay(usec);
+ else
+ mdelay(usec / 1000);
+
+ if (usec < 256000)
usec *= 2;
}
return ret;