Skip to content

Commit bcdaa2b

Browse files
committed
Merge branch 'netvsc-bug-fixes'
Stephen Hemminger says: ==================== netvsc: bug fixes These are bugfixes for netvsc driver in 4.12. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 8397ed3 + 4f19c0d commit bcdaa2b

File tree

3 files changed

+50
-39
lines changed

3 files changed

+50
-39
lines changed

drivers/net/hyperv/hyperv_net.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ struct rndis_device {
171171
spinlock_t request_lock;
172172
struct list_head req_list;
173173

174+
struct work_struct mcast_work;
175+
174176
u8 hw_mac_adr[ETH_ALEN];
175177
u8 rss_key[NETVSC_HASH_KEYLEN];
176178
u16 ind_table[ITAB_NUM];
@@ -201,6 +203,7 @@ int rndis_filter_open(struct netvsc_device *nvdev);
201203
int rndis_filter_close(struct netvsc_device *nvdev);
202204
int rndis_filter_device_add(struct hv_device *dev,
203205
struct netvsc_device_info *info);
206+
void rndis_filter_update(struct netvsc_device *nvdev);
204207
void rndis_filter_device_remove(struct hv_device *dev,
205208
struct netvsc_device *nvdev);
206209
int rndis_filter_set_rss_param(struct rndis_device *rdev,
@@ -211,7 +214,6 @@ int rndis_filter_receive(struct net_device *ndev,
211214
struct vmbus_channel *channel,
212215
void *data, u32 buflen);
213216

214-
int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
215217
int rndis_filter_set_device_mac(struct net_device *ndev, char *mac);
216218

217219
void netvsc_switch_datapath(struct net_device *nv_dev, bool vf);
@@ -696,7 +698,6 @@ struct net_device_context {
696698
/* list protection */
697699
spinlock_t lock;
698700

699-
struct work_struct work;
700701
u32 msg_enable; /* debug level */
701702

702703
u32 tx_checksum_mask;

drivers/net/hyperv/netvsc_drv.c

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -56,37 +56,12 @@ static int debug = -1;
5656
module_param(debug, int, S_IRUGO);
5757
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
5858

59-
static void do_set_multicast(struct work_struct *w)
60-
{
61-
struct net_device_context *ndevctx =
62-
container_of(w, struct net_device_context, work);
63-
struct hv_device *device_obj = ndevctx->device_ctx;
64-
struct net_device *ndev = hv_get_drvdata(device_obj);
65-
struct netvsc_device *nvdev = rcu_dereference(ndevctx->nvdev);
66-
struct rndis_device *rdev;
67-
68-
if (!nvdev)
69-
return;
70-
71-
rdev = nvdev->extension;
72-
if (rdev == NULL)
73-
return;
74-
75-
if (ndev->flags & IFF_PROMISC)
76-
rndis_filter_set_packet_filter(rdev,
77-
NDIS_PACKET_TYPE_PROMISCUOUS);
78-
else
79-
rndis_filter_set_packet_filter(rdev,
80-
NDIS_PACKET_TYPE_BROADCAST |
81-
NDIS_PACKET_TYPE_ALL_MULTICAST |
82-
NDIS_PACKET_TYPE_DIRECTED);
83-
}
84-
8559
static void netvsc_set_multicast_list(struct net_device *net)
8660
{
8761
struct net_device_context *net_device_ctx = netdev_priv(net);
62+
struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
8863

89-
schedule_work(&net_device_ctx->work);
64+
rndis_filter_update(nvdev);
9065
}
9166

9267
static int netvsc_open(struct net_device *net)
@@ -123,8 +98,6 @@ static int netvsc_close(struct net_device *net)
12398

12499
netif_tx_disable(net);
125100

126-
/* Make sure netvsc_set_multicast_list doesn't re-enable filter! */
127-
cancel_work_sync(&net_device_ctx->work);
128101
ret = rndis_filter_close(nvdev);
129102
if (ret != 0) {
130103
netdev_err(net, "unable to close device (ret %d).\n", ret);
@@ -1028,7 +1001,7 @@ static const struct {
10281001
static int netvsc_get_sset_count(struct net_device *dev, int string_set)
10291002
{
10301003
struct net_device_context *ndc = netdev_priv(dev);
1031-
struct netvsc_device *nvdev = rcu_dereference(ndc->nvdev);
1004+
struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev);
10321005

10331006
if (!nvdev)
10341007
return -ENODEV;
@@ -1158,11 +1131,22 @@ netvsc_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
11581131
}
11591132

11601133
#ifdef CONFIG_NET_POLL_CONTROLLER
1161-
static void netvsc_poll_controller(struct net_device *net)
1134+
static void netvsc_poll_controller(struct net_device *dev)
11621135
{
1163-
/* As netvsc_start_xmit() works synchronous we don't have to
1164-
* trigger anything here.
1165-
*/
1136+
struct net_device_context *ndc = netdev_priv(dev);
1137+
struct netvsc_device *ndev;
1138+
int i;
1139+
1140+
rcu_read_lock();
1141+
ndev = rcu_dereference(ndc->nvdev);
1142+
if (ndev) {
1143+
for (i = 0; i < ndev->num_chn; i++) {
1144+
struct netvsc_channel *nvchan = &ndev->chan_table[i];
1145+
1146+
napi_schedule(&nvchan->napi);
1147+
}
1148+
}
1149+
rcu_read_unlock();
11661150
}
11671151
#endif
11681152

@@ -1552,7 +1536,6 @@ static int netvsc_probe(struct hv_device *dev,
15521536
hv_set_drvdata(dev, net);
15531537

15541538
INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change);
1555-
INIT_WORK(&net_device_ctx->work, do_set_multicast);
15561539

15571540
spin_lock_init(&net_device_ctx->lock);
15581541
INIT_LIST_HEAD(&net_device_ctx->reconfig_events);
@@ -1622,7 +1605,6 @@ static int netvsc_remove(struct hv_device *dev)
16221605
netif_device_detach(net);
16231606

16241607
cancel_delayed_work_sync(&ndev_ctx->dwork);
1625-
cancel_work_sync(&ndev_ctx->work);
16261608

16271609
/*
16281610
* Call to the vsc driver to let it know that the device is being

drivers/net/hyperv/rndis_filter.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include "hyperv_net.h"
3333

34+
static void rndis_set_multicast(struct work_struct *w);
3435

3536
#define RNDIS_EXT_LEN PAGE_SIZE
3637
struct rndis_request {
@@ -76,6 +77,7 @@ static struct rndis_device *get_rndis_device(void)
7677
spin_lock_init(&device->request_lock);
7778

7879
INIT_LIST_HEAD(&device->req_list);
80+
INIT_WORK(&device->mcast_work, rndis_set_multicast);
7981

8082
device->state = RNDIS_DEV_UNINITIALIZED;
8183

@@ -815,7 +817,8 @@ static int rndis_filter_query_link_speed(struct rndis_device *dev)
815817
return ret;
816818
}
817819

818-
int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
820+
static int rndis_filter_set_packet_filter(struct rndis_device *dev,
821+
u32 new_filter)
819822
{
820823
struct rndis_request *request;
821824
struct rndis_set_request *set;
@@ -846,6 +849,28 @@ int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
846849
return ret;
847850
}
848851

852+
static void rndis_set_multicast(struct work_struct *w)
853+
{
854+
struct rndis_device *rdev
855+
= container_of(w, struct rndis_device, mcast_work);
856+
857+
if (rdev->ndev->flags & IFF_PROMISC)
858+
rndis_filter_set_packet_filter(rdev,
859+
NDIS_PACKET_TYPE_PROMISCUOUS);
860+
else
861+
rndis_filter_set_packet_filter(rdev,
862+
NDIS_PACKET_TYPE_BROADCAST |
863+
NDIS_PACKET_TYPE_ALL_MULTICAST |
864+
NDIS_PACKET_TYPE_DIRECTED);
865+
}
866+
867+
void rndis_filter_update(struct netvsc_device *nvdev)
868+
{
869+
struct rndis_device *rdev = nvdev->extension;
870+
871+
schedule_work(&rdev->mcast_work);
872+
}
873+
849874
static int rndis_filter_init_device(struct rndis_device *dev)
850875
{
851876
struct rndis_request *request;
@@ -973,6 +998,9 @@ static int rndis_filter_close_device(struct rndis_device *dev)
973998
if (dev->state != RNDIS_DEV_DATAINITIALIZED)
974999
return 0;
9751000

1001+
/* Make sure rndis_set_multicast doesn't re-enable filter! */
1002+
cancel_work_sync(&dev->mcast_work);
1003+
9761004
ret = rndis_filter_set_packet_filter(dev, 0);
9771005
if (ret == -ENODEV)
9781006
ret = 0;

0 commit comments

Comments
 (0)