Skip to content

Commit

Permalink
Drivers: hv: vmbus: Introduce table of VMBus protocol versions
Browse files Browse the repository at this point in the history
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: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
Reviewed-by: Wei Liu <wei.liu@kernel.org>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Andrea Parri authored and Sasha Levin committed Oct 28, 2019
1 parent 54ecb8f commit 3bdea53
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 38 deletions.
50 changes: 18 additions & 32 deletions drivers/hv/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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",
Expand Down
3 changes: 1 addition & 2 deletions drivers/hv/vmbus_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2215,8 +2215,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;
}
Expand Down
4 changes: 0 additions & 4 deletions include/linux/hyperv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit 3bdea53

Please sign in to comment.