]> Git Repo - linux.git/commitdiff
hv: vmbus_post_msg: retry the hypercall on some transient errors
authorDexuan Cui <[email protected]>
Fri, 27 Feb 2015 19:25:59 +0000 (11:25 -0800)
committerGreg Kroah-Hartman <[email protected]>
Mon, 2 Mar 2015 03:30:07 +0000 (19:30 -0800)
I got HV_STATUS_INVALID_CONNECTION_ID on Hyper-V 2008 R2 when keeping running
"rmmod hv_netvsc; modprobe hv_netvsc; rmmod hv_utils; modprobe hv_utils"
in a Linux guest. Looks the host has some kind of throttling mechanism if
some kinds of hypercalls are sent too frequently.
Without the patch, the driver can occasionally fail to load.

Also let's retry HV_STATUS_INSUFFICIENT_MEMORY, though we didn't get it
before.

Removed 'case -ENOMEM', since the hypervisor doesn't return this.

CC: "K. Y. Srinivasan" <[email protected]>
Reviewed-by: Jason Wang <[email protected]>
Signed-off-by: Dexuan Cui <[email protected]>
Signed-off-by: K. Y. Srinivasan <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
arch/x86/include/uapi/asm/hyperv.h
drivers/hv/connection.c

index 90c458e66e13332b847f2a5fb1f0772d3f70e39f..ce6068dbcfbc6e84c76b43239d80f5d020d431ee 100644 (file)
 #define HV_STATUS_INVALID_HYPERCALL_CODE       2
 #define HV_STATUS_INVALID_HYPERCALL_INPUT      3
 #define HV_STATUS_INVALID_ALIGNMENT            4
+#define HV_STATUS_INSUFFICIENT_MEMORY          11
+#define HV_STATUS_INVALID_CONNECTION_ID                18
 #define HV_STATUS_INSUFFICIENT_BUFFERS         19
 
 typedef struct _HV_REFERENCE_TSC_PAGE {
index c4acd1ce7c0c21852a61f37605804b7a74276407..af2388fdc6b9238802396ac4cac1204c219ee707 100644 (file)
@@ -440,9 +440,16 @@ int vmbus_post_msg(void *buffer, size_t buflen)
                ret = hv_post_message(conn_id, 1, buffer, buflen);
 
                switch (ret) {
+               case HV_STATUS_INVALID_CONNECTION_ID:
+                       /*
+                        * We could get this if we send messages too
+                        * frequently.
+                        */
+                       ret = -EAGAIN;
+                       break;
+               case HV_STATUS_INSUFFICIENT_MEMORY:
                case HV_STATUS_INSUFFICIENT_BUFFERS:
                        ret = -ENOMEM;
-               case -ENOMEM:
                        break;
                case HV_STATUS_SUCCESS:
                        return ret;
@@ -452,7 +459,7 @@ int vmbus_post_msg(void *buffer, size_t buflen)
                }
 
                retries++;
-               msleep(100);
+               msleep(1000);
        }
        return ret;
 }
This page took 0.060068 seconds and 4 git commands to generate.