diff options
Diffstat (limited to 'drivers/staging/hv/connection.c')
-rw-r--r-- | drivers/staging/hv/connection.c | 20 |
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; } /* |