Skip to content

Commit a7f0fb1

Browse files
committed
Merge branch 'hv_netvsc-minor-fixes'
Stephen Hemminger says: ==================== hv_netvsc: minor fixes These are improvements to netvsc driver. They aren't functionality changes so not targeting net-next; and they are not show stopper bugs that need to go to stable either. v2 - drop the irq flags patch, defer it to net-next - split the multicast filter flag patch out - change propogate rx mode patch to handle startup of vf ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 3cc81a9 + bee9d41 commit a7f0fb1

File tree

3 files changed

+79
-39
lines changed

3 files changed

+79
-39
lines changed

drivers/net/hyperv/netvsc.c

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -852,24 +852,15 @@ int netvsc_send(struct net_device *ndev,
852852
if (unlikely(!net_device || net_device->destroy))
853853
return -ENODEV;
854854

855-
/* We may race with netvsc_connect_vsp()/netvsc_init_buf() and get
856-
* here before the negotiation with the host is finished and
857-
* send_section_map may not be allocated yet.
858-
*/
859-
if (unlikely(!net_device->send_section_map))
860-
return -EAGAIN;
861-
862855
nvchan = &net_device->chan_table[packet->q_idx];
863856
packet->send_buf_index = NETVSC_INVALID_INDEX;
864857
packet->cp_partial = false;
865858

866859
/* Send control message directly without accessing msd (Multi-Send
867860
* Data) field which may be changed during data packet processing.
868861
*/
869-
if (!skb) {
870-
cur_send = packet;
871-
goto send_now;
872-
}
862+
if (!skb)
863+
return netvsc_send_pkt(device, packet, net_device, pb, skb);
873864

874865
/* batch packets in send buffer if possible */
875866
msdp = &nvchan->msd;
@@ -953,7 +944,6 @@ int netvsc_send(struct net_device *ndev,
953944
}
954945
}
955946

956-
send_now:
957947
if (cur_send)
958948
ret = netvsc_send_pkt(device, cur_send, net_device, pb, skb);
959949

@@ -1217,9 +1207,10 @@ int netvsc_poll(struct napi_struct *napi, int budget)
12171207
if (send_recv_completions(ndev, net_device, nvchan) == 0 &&
12181208
work_done < budget &&
12191209
napi_complete_done(napi, work_done) &&
1220-
hv_end_read(&channel->inbound)) {
1210+
hv_end_read(&channel->inbound) &&
1211+
napi_schedule_prep(napi)) {
12211212
hv_begin_read(&channel->inbound);
1222-
napi_reschedule(napi);
1213+
__napi_schedule(napi);
12231214
}
12241215

12251216
/* Driver may overshoot since multiple packets per descriptor */
@@ -1242,7 +1233,7 @@ void netvsc_channel_cb(void *context)
12421233
/* disable interupts from host */
12431234
hv_begin_read(rbi);
12441235

1245-
__napi_schedule(&nvchan->napi);
1236+
__napi_schedule_irqoff(&nvchan->napi);
12461237
}
12471238
}
12481239

@@ -1296,7 +1287,6 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
12961287
netvsc_channel_cb, net_device->chan_table);
12971288

12981289
if (ret != 0) {
1299-
netif_napi_del(&net_device->chan_table[0].napi);
13001290
netdev_err(ndev, "unable to open channel: %d\n", ret);
13011291
goto cleanup;
13021292
}
@@ -1306,11 +1296,6 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
13061296

13071297
napi_enable(&net_device->chan_table[0].napi);
13081298

1309-
/* Writing nvdev pointer unlocks netvsc_send(), make sure chn_table is
1310-
* populated.
1311-
*/
1312-
rcu_assign_pointer(net_device_ctx->nvdev, net_device);
1313-
13141299
/* Connect with the NetVsp */
13151300
ret = netvsc_connect_vsp(device, net_device, device_info);
13161301
if (ret != 0) {
@@ -1319,6 +1304,11 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
13191304
goto close;
13201305
}
13211306

1307+
/* Writing nvdev pointer unlocks netvsc_send(), make sure chn_table is
1308+
* populated.
1309+
*/
1310+
rcu_assign_pointer(net_device_ctx->nvdev, net_device);
1311+
13221312
return net_device;
13231313

13241314
close:
@@ -1329,6 +1319,7 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
13291319
vmbus_close(device->channel);
13301320

13311321
cleanup:
1322+
netif_napi_del(&net_device->chan_table[0].napi);
13321323
free_netvsc_device(&net_device->rcu);
13331324

13341325
return ERR_PTR(ret);

drivers/net/hyperv/netvsc_drv.c

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,36 @@ static int debug = -1;
6666
module_param(debug, int, S_IRUGO);
6767
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
6868

69-
static void netvsc_set_multicast_list(struct net_device *net)
69+
static void netvsc_change_rx_flags(struct net_device *net, int change)
7070
{
71-
struct net_device_context *net_device_ctx = netdev_priv(net);
72-
struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
71+
struct net_device_context *ndev_ctx = netdev_priv(net);
72+
struct net_device *vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
73+
int inc;
74+
75+
if (!vf_netdev)
76+
return;
77+
78+
if (change & IFF_PROMISC) {
79+
inc = (net->flags & IFF_PROMISC) ? 1 : -1;
80+
dev_set_promiscuity(vf_netdev, inc);
81+
}
82+
83+
if (change & IFF_ALLMULTI) {
84+
inc = (net->flags & IFF_ALLMULTI) ? 1 : -1;
85+
dev_set_allmulti(vf_netdev, inc);
86+
}
87+
}
88+
89+
static void netvsc_set_rx_mode(struct net_device *net)
90+
{
91+
struct net_device_context *ndev_ctx = netdev_priv(net);
92+
struct net_device *vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
93+
struct netvsc_device *nvdev = rtnl_dereference(ndev_ctx->nvdev);
94+
95+
if (vf_netdev) {
96+
dev_uc_sync(vf_netdev, net);
97+
dev_mc_sync(vf_netdev, net);
98+
}
7399

74100
rndis_filter_update(nvdev);
75101
}
@@ -91,12 +117,11 @@ static int netvsc_open(struct net_device *net)
91117
return ret;
92118
}
93119

94-
netif_tx_wake_all_queues(net);
95-
96120
rdev = nvdev->extension;
97-
98-
if (!rdev->link_state)
121+
if (!rdev->link_state) {
99122
netif_carrier_on(net);
123+
netif_tx_wake_all_queues(net);
124+
}
100125

101126
if (vf_netdev) {
102127
/* Setting synthetic device up transparently sets
@@ -299,8 +324,19 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
299324
rcu_read_lock();
300325
vf_netdev = rcu_dereference(ndc->vf_netdev);
301326
if (vf_netdev) {
302-
txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
303-
qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
327+
const struct net_device_ops *vf_ops = vf_netdev->netdev_ops;
328+
329+
if (vf_ops->ndo_select_queue)
330+
txq = vf_ops->ndo_select_queue(vf_netdev, skb,
331+
accel_priv, fallback);
332+
else
333+
txq = fallback(vf_netdev, skb);
334+
335+
/* Record the queue selected by VF so that it can be
336+
* used for common case where VF has more queues than
337+
* the synthetic device.
338+
*/
339+
qdisc_skb_cb(skb)->slave_dev_queue_mapping = txq;
304340
} else {
305341
txq = netvsc_pick_tx(ndev, skb);
306342
}
@@ -1576,7 +1612,8 @@ static const struct net_device_ops device_ops = {
15761612
.ndo_open = netvsc_open,
15771613
.ndo_stop = netvsc_close,
15781614
.ndo_start_xmit = netvsc_start_xmit,
1579-
.ndo_set_rx_mode = netvsc_set_multicast_list,
1615+
.ndo_change_rx_flags = netvsc_change_rx_flags,
1616+
.ndo_set_rx_mode = netvsc_set_rx_mode,
15801617
.ndo_change_mtu = netvsc_change_mtu,
15811618
.ndo_validate_addr = eth_validate_addr,
15821619
.ndo_set_mac_address = netvsc_set_mac_addr,
@@ -1807,6 +1844,11 @@ static void __netvsc_vf_setup(struct net_device *ndev,
18071844
netdev_warn(vf_netdev,
18081845
"unable to change mtu to %u\n", ndev->mtu);
18091846

1847+
/* set multicast etc flags on VF */
1848+
dev_change_flags(vf_netdev, ndev->flags | IFF_SLAVE);
1849+
dev_uc_sync(vf_netdev, ndev);
1850+
dev_mc_sync(vf_netdev, ndev);
1851+
18101852
if (netif_running(ndev)) {
18111853
ret = dev_open(vf_netdev);
18121854
if (ret)

drivers/net/hyperv/rndis_filter.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -854,15 +854,19 @@ static void rndis_set_multicast(struct work_struct *w)
854854
{
855855
struct rndis_device *rdev
856856
= container_of(w, struct rndis_device, mcast_work);
857+
u32 filter = NDIS_PACKET_TYPE_DIRECTED;
858+
unsigned int flags = rdev->ndev->flags;
857859

858-
if (rdev->ndev->flags & IFF_PROMISC)
859-
rndis_filter_set_packet_filter(rdev,
860-
NDIS_PACKET_TYPE_PROMISCUOUS);
861-
else
862-
rndis_filter_set_packet_filter(rdev,
863-
NDIS_PACKET_TYPE_BROADCAST |
864-
NDIS_PACKET_TYPE_ALL_MULTICAST |
865-
NDIS_PACKET_TYPE_DIRECTED);
860+
if (flags & IFF_PROMISC) {
861+
filter = NDIS_PACKET_TYPE_PROMISCUOUS;
862+
} else {
863+
if (flags & IFF_ALLMULTI)
864+
flags |= NDIS_PACKET_TYPE_ALL_MULTICAST;
865+
if (flags & IFF_BROADCAST)
866+
flags |= NDIS_PACKET_TYPE_BROADCAST;
867+
}
868+
869+
rndis_filter_set_packet_filter(rdev, filter);
866870
}
867871

868872
void rndis_filter_update(struct netvsc_device *nvdev)
@@ -1340,6 +1344,9 @@ void rndis_filter_device_remove(struct hv_device *dev,
13401344
{
13411345
struct rndis_device *rndis_dev = net_dev->extension;
13421346

1347+
/* Don't try and setup sub channels if about to halt */
1348+
cancel_work_sync(&net_dev->subchan_work);
1349+
13431350
/* Halt and release the rndis device */
13441351
rndis_filter_halt_device(rndis_dev);
13451352

0 commit comments

Comments
 (0)