Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89f9f679 authored by Dexuan Cui's avatar Dexuan Cui Committed by Greg Kroah-Hartman
Browse files

hv: vmbus_post_msg: retry the hypercall on some transient errors



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" <kys@microsoft.com>
Reviewed-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarDexuan Cui <decui@microsoft.com>
Signed-off-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 18965663
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -225,6 +225,8 @@
#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 {
+9 −2
Original line number Diff line number Diff line
@@ -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;
}