Commit bedc61a9 authored by Andrea Parri's avatar Andrea Parri Committed by Sasha Levin
Browse files

Drivers: hv: vmbus: Introduce table of VMBus protocol versions



The technique used to get the next VMBus version seems increasisly
clumsy as the number of VMBus versions increases.  Performance is
not a concern since this is only done once during system boot; it's
just that we'll end up with more lines of code than is really needed.

As an alternative, introduce a table with the version numbers listed
in order (from the most recent to the oldest).  vmbus_connect() loops
through the versions listed in the table until it gets an accepted
connection or gets to the end of the table (invalid version).

Suggested-by: default avatarMichael Kelley <mikelley@microsoft.com>
Signed-off-by: default avatarAndrea Parri <parri.andrea@gmail.com>
Reviewed-by: default avatarWei Liu <wei.liu@kernel.org>
Reviewed-by: default avatarMichael Kelley <mikelley@microsoft.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent a99d8080
Loading
Loading
Loading
Loading
+18 −32
Original line number Diff line number Diff line
@@ -40,29 +40,17 @@ EXPORT_SYMBOL_GPL(vmbus_connection);
__u32 vmbus_proto_version;
EXPORT_SYMBOL_GPL(vmbus_proto_version);

static __u32 vmbus_get_next_version(__u32 current_version)
{
	switch (current_version) {
	case (VERSION_WIN7):
		return VERSION_WS2008;

	case (VERSION_WIN8):
		return VERSION_WIN7;

	case (VERSION_WIN8_1):
		return VERSION_WIN8;

	case (VERSION_WIN10):
		return VERSION_WIN8_1;

	case (VERSION_WIN10_V5):
		return VERSION_WIN10;

	case (VERSION_WS2008):
	default:
		return VERSION_INVAL;
	}
}
/*
 * Table of VMBus versions listed from newest to oldest.
 */
static __u32 vmbus_versions[] = {
	VERSION_WIN10_V5,
	VERSION_WIN10,
	VERSION_WIN8_1,
	VERSION_WIN8,
	VERSION_WIN7,
	VERSION_WS2008
};

int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
{
@@ -169,8 +157,8 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
 */
int vmbus_connect(void)
{
	int ret = 0;
	struct vmbus_channel_msginfo *msginfo = NULL;
	int i, ret = 0;
	__u32 version;

	/* Initialize the vmbus connection */
@@ -244,21 +232,19 @@ int vmbus_connect(void)
	 * version.
	 */

	version = VERSION_CURRENT;
	for (i = 0; ; i++) {
		if (i == ARRAY_SIZE(vmbus_versions))
			goto cleanup;

		version = vmbus_versions[i];

	do {
		ret = vmbus_negotiate_version(msginfo, version);
		if (ret == -ETIMEDOUT)
			goto cleanup;

		if (vmbus_connection.conn_state == CONNECTED)
			break;

		version = vmbus_get_next_version(version);
	} while (version != VERSION_INVAL);

	if (version == VERSION_INVAL)
		goto cleanup;
	}

	vmbus_proto_version = version;
	pr_info("Vmbus version:%d.%d\n",
+1 −2
Original line number Diff line number Diff line
@@ -2220,8 +2220,7 @@ static int vmbus_bus_resume(struct device *dev)
	 * We only use the 'vmbus_proto_version', which was in use before
	 * hibernation, to re-negotiate with the host.
	 */
	if (vmbus_proto_version == VERSION_INVAL ||
	    vmbus_proto_version == 0) {
	if (!vmbus_proto_version) {
		pr_err("Invalid proto version = 0x%x\n", vmbus_proto_version);
		return -EINVAL;
	}
+0 −4
Original line number Diff line number Diff line
@@ -192,10 +192,6 @@ static inline u32 hv_get_avail_to_write_percent(
#define VERSION_WIN10	((4 << 16) | (0))
#define VERSION_WIN10_V5 ((5 << 16) | (0))

#define VERSION_INVAL -1

#define VERSION_CURRENT VERSION_WIN10_V5

/* Make maximum size of pipe payload of 16K */
#define MAX_PIPE_DATA_PAYLOAD		(sizeof(u8) * 16384)