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

Commit ea383bf1 authored by stephen hemminger's avatar stephen hemminger Committed by David S. Miller
Browse files

netvsc: change logic for change mtu and set_queues



Use device detach/attach to ensure that no packets are handed
to device during state changes. Call rndis_filter_open/close
directly as part of later VF related changes.

Signed-off-by: default avatarStephen Hemminger <sthemmin@microsoft.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a5e1ec38
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -200,6 +200,7 @@ int netvsc_recv_callback(struct net_device *net,
			 const struct ndis_pkt_8021q_info *vlan);
void netvsc_channel_cb(void *context);
int netvsc_poll(struct napi_struct *napi, int budget);
bool rndis_filter_opened(const struct netvsc_device *nvdev);
int rndis_filter_open(struct netvsc_device *nvdev);
int rndis_filter_close(struct netvsc_device *nvdev);
int rndis_filter_device_add(struct hv_device *dev,
+18 −20
Original line number Diff line number Diff line
@@ -742,7 +742,7 @@ static int netvsc_set_channels(struct net_device *net,
	struct hv_device *dev = net_device_ctx->device_ctx;
	struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
	unsigned int count = channels->combined_count;
	bool was_running;
	bool was_opened;
	int ret;

	/* We do not support separate count for rx, tx, or other */
@@ -762,12 +762,9 @@ static int netvsc_set_channels(struct net_device *net,
	if (count > nvdev->max_chn)
		return -EINVAL;

	was_running = netif_running(net);
	if (was_running) {
		ret = netvsc_close(net);
		if (ret)
			return ret;
	}
	was_opened = rndis_filter_opened(nvdev);
	if (was_opened)
		rndis_filter_close(nvdev);

	rndis_filter_device_remove(dev, nvdev);

@@ -777,8 +774,9 @@ static int netvsc_set_channels(struct net_device *net,
	else
		netvsc_set_queues(net, dev, nvdev->num_chn);

	if (was_running)
		ret = netvsc_open(net);
	nvdev = rtnl_dereference(net_device_ctx->nvdev);
	if (was_opened)
		rndis_filter_open(nvdev);

	/* We may have missed link change notifications */
	net_device_ctx->last_reconfig = 0;
@@ -848,18 +846,15 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
	struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
	struct hv_device *hdev = ndevctx->device_ctx;
	struct netvsc_device_info device_info;
	bool was_running;
	int ret = 0;
	bool was_opened;

	if (!nvdev || nvdev->destroy)
		return -ENODEV;

	was_running = netif_running(ndev);
	if (was_running) {
		ret = netvsc_close(ndev);
		if (ret)
			return ret;
	}
	netif_device_detach(ndev);
	was_opened = rndis_filter_opened(nvdev);
	if (was_opened)
		rndis_filter_close(nvdev);

	memset(&device_info, 0, sizeof(device_info));
	device_info.ring_size = ring_size;
@@ -877,14 +872,17 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
	ndev->mtu = mtu;

	rndis_filter_device_add(hdev, &device_info);
	nvdev = rtnl_dereference(ndevctx->nvdev);

	if (was_opened)
		rndis_filter_open(nvdev);

	if (was_running)
		ret = netvsc_open(ndev);
	netif_device_attach(ndev);

	/* We may have missed link change notifications */
	schedule_delayed_work(&ndevctx->dwork, 0);

	return ret;
	return 0;
}

static void netvsc_get_stats64(struct net_device *net,
+5 −0
Original line number Diff line number Diff line
@@ -1302,3 +1302,8 @@ int rndis_filter_close(struct netvsc_device *nvdev)

	return rndis_filter_close_device(nvdev->extension);
}

bool rndis_filter_opened(const struct netvsc_device *nvdev)
{
	return atomic_read(&nvdev->open_cnt) > 0;
}