diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2011-08-25 18:49:01 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-26 00:23:19 +0200 |
commit | 5289d3d160e8d5c63974502696ab5def71891f18 (patch) | |
tree | e420b755b62608b543cd5fa897a9bd5b1186bef4 | |
parent | Staging: hv: netvsc: Get rid of an unnecessary print statement in netvsc_probe() (diff) | |
download | linux-5289d3d160e8d5c63974502696ab5def71891f18.tar.xz linux-5289d3d160e8d5c63974502696ab5def71891f18.zip |
Staging: hv: vmbus: Retry vmbus_post_msg() before giving up
The function hv_post_msg() can fail because of transient resource
conditions. It may be useful to retry the operation.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | arch/x86/include/asm/hyperv.h | 1 | ||||
-rw-r--r-- | drivers/staging/hv/connection.c | 18 |
2 files changed, 18 insertions, 1 deletions
diff --git a/arch/x86/include/asm/hyperv.h b/arch/x86/include/asm/hyperv.h index 5df477ac3af7..b80420bcd09d 100644 --- a/arch/x86/include/asm/hyperv.h +++ b/arch/x86/include/asm/hyperv.h @@ -189,5 +189,6 @@ #define HV_STATUS_INVALID_HYPERCALL_CODE 2 #define HV_STATUS_INVALID_HYPERCALL_INPUT 3 #define HV_STATUS_INVALID_ALIGNMENT 4 +#define HV_STATUS_INSUFFICIENT_BUFFERS 19 #endif diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index 0e7efce31282..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> @@ -268,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; } /* |