Commit a2aeea1c authored by David S. Miller's avatar David S. Miller

Merge branch 'hv_netvsc-Fix-shutdown-issues-on-older-Windows-hosts'

Mohammed Gamal says:

====================
hv_netvsc: Fix shutdown issues on older Windows hosts

Guests running on WS2012 hosts would not shutdown when changing network
interface setting (e.g. Number of channels, MTU ... etc).

This patch series addresses these shutdown issues we enecountered with WS2012
hosts. It's essentialy a rework of the series sent in
https://lkml.org/lkml/2018/1/23/111 on top of latest upstream
====================

Fixes: 0ef58b0a ("hv_netvsc: change GPAD teardown order on older versions")
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3d92f0b5 3f076eff
...@@ -109,11 +109,11 @@ static void free_netvsc_device_rcu(struct netvsc_device *nvdev) ...@@ -109,11 +109,11 @@ static void free_netvsc_device_rcu(struct netvsc_device *nvdev)
call_rcu(&nvdev->rcu, free_netvsc_device); call_rcu(&nvdev->rcu, free_netvsc_device);
} }
static void netvsc_revoke_buf(struct hv_device *device, static void netvsc_revoke_recv_buf(struct hv_device *device,
struct netvsc_device *net_device) struct netvsc_device *net_device,
struct net_device *ndev)
{ {
struct nvsp_message *revoke_packet; struct nvsp_message *revoke_packet;
struct net_device *ndev = hv_get_drvdata(device);
int ret; int ret;
/* /*
...@@ -157,6 +157,14 @@ static void netvsc_revoke_buf(struct hv_device *device, ...@@ -157,6 +157,14 @@ static void netvsc_revoke_buf(struct hv_device *device,
} }
net_device->recv_section_cnt = 0; net_device->recv_section_cnt = 0;
} }
}
static void netvsc_revoke_send_buf(struct hv_device *device,
struct netvsc_device *net_device,
struct net_device *ndev)
{
struct nvsp_message *revoke_packet;
int ret;
/* Deal with the send buffer we may have setup. /* Deal with the send buffer we may have setup.
* If we got a send section size, it means we received a * If we got a send section size, it means we received a
...@@ -202,10 +210,10 @@ static void netvsc_revoke_buf(struct hv_device *device, ...@@ -202,10 +210,10 @@ static void netvsc_revoke_buf(struct hv_device *device,
} }
} }
static void netvsc_teardown_gpadl(struct hv_device *device, static void netvsc_teardown_recv_gpadl(struct hv_device *device,
struct netvsc_device *net_device) struct netvsc_device *net_device,
struct net_device *ndev)
{ {
struct net_device *ndev = hv_get_drvdata(device);
int ret; int ret;
if (net_device->recv_buf_gpadl_handle) { if (net_device->recv_buf_gpadl_handle) {
...@@ -222,6 +230,13 @@ static void netvsc_teardown_gpadl(struct hv_device *device, ...@@ -222,6 +230,13 @@ static void netvsc_teardown_gpadl(struct hv_device *device,
} }
net_device->recv_buf_gpadl_handle = 0; net_device->recv_buf_gpadl_handle = 0;
} }
}
static void netvsc_teardown_send_gpadl(struct hv_device *device,
struct netvsc_device *net_device,
struct net_device *ndev)
{
int ret;
if (net_device->send_buf_gpadl_handle) { if (net_device->send_buf_gpadl_handle) {
ret = vmbus_teardown_gpadl(device->channel, ret = vmbus_teardown_gpadl(device->channel,
...@@ -437,8 +452,10 @@ static int netvsc_init_buf(struct hv_device *device, ...@@ -437,8 +452,10 @@ static int netvsc_init_buf(struct hv_device *device,
goto exit; goto exit;
cleanup: cleanup:
netvsc_revoke_buf(device, net_device); netvsc_revoke_recv_buf(device, net_device, ndev);
netvsc_teardown_gpadl(device, net_device); netvsc_revoke_send_buf(device, net_device, ndev);
netvsc_teardown_recv_gpadl(device, net_device, ndev);
netvsc_teardown_send_gpadl(device, net_device, ndev);
exit: exit:
return ret; return ret;
...@@ -457,7 +474,6 @@ static int negotiate_nvsp_ver(struct hv_device *device, ...@@ -457,7 +474,6 @@ static int negotiate_nvsp_ver(struct hv_device *device,
init_packet->hdr.msg_type = NVSP_MSG_TYPE_INIT; init_packet->hdr.msg_type = NVSP_MSG_TYPE_INIT;
init_packet->msg.init_msg.init.min_protocol_ver = nvsp_ver; init_packet->msg.init_msg.init.min_protocol_ver = nvsp_ver;
init_packet->msg.init_msg.init.max_protocol_ver = nvsp_ver; init_packet->msg.init_msg.init.max_protocol_ver = nvsp_ver;
trace_nvsp_send(ndev, init_packet); trace_nvsp_send(ndev, init_packet);
/* Send the init request */ /* Send the init request */
...@@ -575,7 +591,17 @@ void netvsc_device_remove(struct hv_device *device) ...@@ -575,7 +591,17 @@ void netvsc_device_remove(struct hv_device *device)
= rtnl_dereference(net_device_ctx->nvdev); = rtnl_dereference(net_device_ctx->nvdev);
int i; int i;
netvsc_revoke_buf(device, net_device); /*
* Revoke receive buffer. If host is pre-Win2016 then tear down
* receive buffer GPADL. Do the same for send buffer.
*/
netvsc_revoke_recv_buf(device, net_device, ndev);
if (vmbus_proto_version < VERSION_WIN10)
netvsc_teardown_recv_gpadl(device, net_device, ndev);
netvsc_revoke_send_buf(device, net_device, ndev);
if (vmbus_proto_version < VERSION_WIN10)
netvsc_teardown_send_gpadl(device, net_device, ndev);
RCU_INIT_POINTER(net_device_ctx->nvdev, NULL); RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
...@@ -589,15 +615,17 @@ void netvsc_device_remove(struct hv_device *device) ...@@ -589,15 +615,17 @@ void netvsc_device_remove(struct hv_device *device)
*/ */
netdev_dbg(ndev, "net device safe to remove\n"); netdev_dbg(ndev, "net device safe to remove\n");
/* older versions require that buffer be revoked before close */
if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_4)
netvsc_teardown_gpadl(device, net_device);
/* Now, we can close the channel safely */ /* Now, we can close the channel safely */
vmbus_close(device->channel); vmbus_close(device->channel);
if (net_device->nvsp_version >= NVSP_PROTOCOL_VERSION_4) /*
netvsc_teardown_gpadl(device, net_device); * If host is Win2016 or higher then we do the GPADL tear down
* here after VMBus is closed.
*/
if (vmbus_proto_version >= VERSION_WIN10) {
netvsc_teardown_recv_gpadl(device, net_device, ndev);
netvsc_teardown_send_gpadl(device, net_device, ndev);
}
/* Release all resources */ /* Release all resources */
free_netvsc_device_rcu(net_device); free_netvsc_device_rcu(net_device);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment