aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/hv/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/hv/connection.c')
-rw-r--r--drivers/staging/hv/connection.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
index e6b40392e08d..a88ad7072566 100644
--- a/drivers/staging/hv/connection.c
+++ b/drivers/staging/hv/connection.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/wait.h>
+#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
@@ -215,8 +216,6 @@ static void process_chn_event(u32 relid)
{
struct vmbus_channel *channel;
- /* ASSERT(relId > 0); */
-
/*
* Find the channel based on this relid and invokes the
* channel callback to process the event
@@ -270,10 +269,25 @@ void vmbus_on_event(unsigned long data)
int vmbus_post_msg(void *buffer, size_t buflen)
{
union hv_connection_id conn_id;
+ int ret = 0;
+ int retries = 0;
conn_id.asu32 = 0;
conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID;
- return hv_post_message(conn_id, 1, buffer, buflen);
+
+ /*
+ * hv_post_message() can have transient failures because of
+ * insufficient resources. Retry the operation a couple of
+ * times before giving up.
+ */
+ while (retries < 3) {
+ ret = hv_post_message(conn_id, 1, buffer, buflen);
+ if (ret != HV_STATUS_INSUFFICIENT_BUFFERS)
+ return ret;
+ retries++;
+ msleep(100);
+ }
+ return ret;
}
/*