Skip to content

Commit 88f3481

Browse files
committed
Merge branch 'netvsc-lockdep-and-related-fixes'
Stephen Hemminger says: ==================== netvsc: lockdep and related fixes These fix sparse and lockdep warnings from netvsc driver. Targeting these at net-next since no actual related failures have been observed in non-debug kernels. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 9492f42 + 3962981 commit 88f3481

File tree

4 files changed

+107
-97
lines changed

4 files changed

+107
-97
lines changed

drivers/net/hyperv/hyperv_net.h

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,12 @@ struct rndis_device {
183183
/* Interface */
184184
struct rndis_message;
185185
struct netvsc_device;
186-
int netvsc_device_add(struct hv_device *device,
187-
const struct netvsc_device_info *info);
186+
struct net_device_context;
187+
188+
struct netvsc_device *netvsc_device_add(struct hv_device *device,
189+
const struct netvsc_device_info *info);
188190
void netvsc_device_remove(struct hv_device *device);
189-
int netvsc_send(struct hv_device *device,
191+
int netvsc_send(struct net_device_context *ndc,
190192
struct hv_netvsc_packet *packet,
191193
struct rndis_message *rndis_msg,
192194
struct hv_page_buffer **page_buffer,
@@ -200,10 +202,11 @@ int netvsc_recv_callback(struct net_device *net,
200202
const struct ndis_pkt_8021q_info *vlan);
201203
void netvsc_channel_cb(void *context);
202204
int netvsc_poll(struct napi_struct *napi, int budget);
205+
bool rndis_filter_opened(const struct netvsc_device *nvdev);
203206
int rndis_filter_open(struct netvsc_device *nvdev);
204207
int rndis_filter_close(struct netvsc_device *nvdev);
205-
int rndis_filter_device_add(struct hv_device *dev,
206-
struct netvsc_device_info *info);
208+
struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
209+
struct netvsc_device_info *info);
207210
void rndis_filter_update(struct netvsc_device *nvdev);
208211
void rndis_filter_device_remove(struct hv_device *dev,
209212
struct netvsc_device *nvdev);
@@ -724,6 +727,7 @@ struct net_device_context {
724727
/* Per channel data */
725728
struct netvsc_channel {
726729
struct vmbus_channel *channel;
730+
struct netvsc_device *net_device;
727731
const struct vmpacket_descriptor *desc;
728732
struct napi_struct napi;
729733
struct multi_send_data msd;
@@ -783,18 +787,6 @@ struct netvsc_device {
783787
struct rcu_head rcu;
784788
};
785789

786-
static inline struct netvsc_device *
787-
net_device_to_netvsc_device(struct net_device *ndev)
788-
{
789-
return ((struct net_device_context *)netdev_priv(ndev))->nvdev;
790-
}
791-
792-
static inline struct netvsc_device *
793-
hv_device_to_netvsc_device(struct hv_device *device)
794-
{
795-
return net_device_to_netvsc_device(hv_get_drvdata(device));
796-
}
797-
798790
/* NdisInitialize message */
799791
struct rndis_initialize_request {
800792
u32 req_id;

drivers/net/hyperv/netvsc.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include <linux/netdevice.h>
3030
#include <linux/if_ether.h>
3131
#include <linux/vmalloc.h>
32+
#include <linux/rtnetlink.h>
33+
3234
#include <asm/sync_bitops.h>
3335

3436
#include "hyperv_net.h"
@@ -41,7 +43,7 @@ void netvsc_switch_datapath(struct net_device *ndev, bool vf)
4143
{
4244
struct net_device_context *net_device_ctx = netdev_priv(ndev);
4345
struct hv_device *dev = net_device_ctx->device_ctx;
44-
struct netvsc_device *nv_dev = net_device_ctx->nvdev;
46+
struct netvsc_device *nv_dev = rtnl_dereference(net_device_ctx->nvdev);
4547
struct nvsp_message *init_pkt = &nv_dev->channel_init_pkt;
4648

4749
memset(init_pkt, 0, sizeof(struct nvsp_message));
@@ -103,7 +105,8 @@ static void netvsc_destroy_buf(struct hv_device *device)
103105
{
104106
struct nvsp_message *revoke_packet;
105107
struct net_device *ndev = hv_get_drvdata(device);
106-
struct netvsc_device *net_device = net_device_to_netvsc_device(ndev);
108+
struct net_device_context *ndc = netdev_priv(ndev);
109+
struct netvsc_device *net_device = rtnl_dereference(ndc->nvdev);
107110
int ret;
108111

109112
/*
@@ -549,7 +552,8 @@ void netvsc_device_remove(struct hv_device *device)
549552
{
550553
struct net_device *ndev = hv_get_drvdata(device);
551554
struct net_device_context *net_device_ctx = netdev_priv(ndev);
552-
struct netvsc_device *net_device = net_device_ctx->nvdev;
555+
struct netvsc_device *net_device
556+
= rtnl_dereference(net_device_ctx->nvdev);
553557
int i;
554558

555559
netvsc_disconnect_vsp(device);
@@ -819,13 +823,16 @@ static inline void move_pkt_msd(struct hv_netvsc_packet **msd_send,
819823
msdp->count = 0;
820824
}
821825

822-
int netvsc_send(struct hv_device *device,
826+
/* RCU already held by caller */
827+
int netvsc_send(struct net_device_context *ndev_ctx,
823828
struct hv_netvsc_packet *packet,
824829
struct rndis_message *rndis_msg,
825830
struct hv_page_buffer **pb,
826831
struct sk_buff *skb)
827832
{
828-
struct netvsc_device *net_device = hv_device_to_netvsc_device(device);
833+
struct netvsc_device *net_device
834+
= rcu_dereference_rtnl(ndev_ctx->nvdev);
835+
struct hv_device *device = ndev_ctx->device_ctx;
829836
int ret = 0;
830837
struct netvsc_channel *nvchan;
831838
u32 pktlen = packet->total_data_buflen, msd_len = 0;
@@ -837,7 +844,7 @@ int netvsc_send(struct hv_device *device,
837844
bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
838845

839846
/* If device is rescinded, return error and packet will get dropped. */
840-
if (unlikely(net_device->destroy))
847+
if (unlikely(!net_device || net_device->destroy))
841848
return -ENODEV;
842849

843850
/* We may race with netvsc_connect_vsp()/netvsc_init_buf() and get
@@ -1219,11 +1226,11 @@ int netvsc_poll(struct napi_struct *napi, int budget)
12191226
{
12201227
struct netvsc_channel *nvchan
12211228
= container_of(napi, struct netvsc_channel, napi);
1229+
struct netvsc_device *net_device = nvchan->net_device;
12221230
struct vmbus_channel *channel = nvchan->channel;
12231231
struct hv_device *device = netvsc_channel_to_device(channel);
12241232
u16 q_idx = channel->offermsg.offer.sub_channel_index;
12251233
struct net_device *ndev = hv_get_drvdata(device);
1226-
struct netvsc_device *net_device = net_device_to_netvsc_device(ndev);
12271234
int work_done = 0;
12281235

12291236
/* If starting a new interval */
@@ -1271,8 +1278,8 @@ void netvsc_channel_cb(void *context)
12711278
* netvsc_device_add - Callback when the device belonging to this
12721279
* driver is added
12731280
*/
1274-
int netvsc_device_add(struct hv_device *device,
1275-
const struct netvsc_device_info *device_info)
1281+
struct netvsc_device *netvsc_device_add(struct hv_device *device,
1282+
const struct netvsc_device_info *device_info)
12761283
{
12771284
int i, ret = 0;
12781285
int ring_size = device_info->ring_size;
@@ -1282,7 +1289,7 @@ int netvsc_device_add(struct hv_device *device,
12821289

12831290
net_device = alloc_net_device();
12841291
if (!net_device)
1285-
return -ENOMEM;
1292+
return ERR_PTR(-ENOMEM);
12861293

12871294
net_device->ring_size = ring_size;
12881295

@@ -1302,6 +1309,7 @@ int netvsc_device_add(struct hv_device *device,
13021309
struct netvsc_channel *nvchan = &net_device->chan_table[i];
13031310

13041311
nvchan->channel = device->channel;
1312+
nvchan->net_device = net_device;
13051313
}
13061314

13071315
/* Enable NAPI handler before init callbacks */
@@ -1338,7 +1346,7 @@ int netvsc_device_add(struct hv_device *device,
13381346
goto close;
13391347
}
13401348

1341-
return ret;
1349+
return net_device;
13421350

13431351
close:
13441352
netif_napi_del(&net_device->chan_table[0].napi);
@@ -1349,6 +1357,5 @@ int netvsc_device_add(struct hv_device *device,
13491357
cleanup:
13501358
free_netvsc_device(&net_device->rcu);
13511359

1352-
return ret;
1353-
1360+
return ERR_PTR(ret);
13541361
}

drivers/net/hyperv/netvsc_drv.c

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static void netvsc_set_multicast_list(struct net_device *net)
6969
static int netvsc_open(struct net_device *net)
7070
{
7171
struct net_device_context *ndev_ctx = netdev_priv(net);
72-
struct netvsc_device *nvdev = ndev_ctx->nvdev;
72+
struct netvsc_device *nvdev = rtnl_dereference(ndev_ctx->nvdev);
7373
struct rndis_device *rdev;
7474
int ret = 0;
7575

@@ -505,8 +505,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
505505

506506
/* timestamp packet in software */
507507
skb_tx_timestamp(skb);
508-
ret = netvsc_send(net_device_ctx->device_ctx, packet,
509-
rndis_msg, &pb, skb);
508+
509+
ret = netvsc_send(net_device_ctx, packet, rndis_msg, &pb, skb);
510510
if (likely(ret == 0))
511511
return NETDEV_TX_OK;
512512

@@ -717,24 +717,24 @@ static int netvsc_set_queues(struct net_device *net, struct hv_device *dev,
717717
u32 num_chn)
718718
{
719719
struct netvsc_device_info device_info;
720+
struct netvsc_device *net_device;
720721
int ret;
721722

722723
memset(&device_info, 0, sizeof(device_info));
723724
device_info.num_chn = num_chn;
724725
device_info.ring_size = ring_size;
725726
device_info.max_num_vrss_chns = num_chn;
726727

727-
ret = rndis_filter_device_add(dev, &device_info);
728-
if (ret)
729-
return ret;
730-
731728
ret = netif_set_real_num_tx_queues(net, num_chn);
732729
if (ret)
733730
return ret;
734731

735732
ret = netif_set_real_num_rx_queues(net, num_chn);
733+
if (ret)
734+
return ret;
736735

737-
return ret;
736+
net_device = rndis_filter_device_add(dev, &device_info);
737+
return IS_ERR(net_device) ? PTR_ERR(net_device) : 0;
738738
}
739739

740740
static int netvsc_set_channels(struct net_device *net,
@@ -744,7 +744,7 @@ static int netvsc_set_channels(struct net_device *net,
744744
struct hv_device *dev = net_device_ctx->device_ctx;
745745
struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
746746
unsigned int count = channels->combined_count;
747-
bool was_running;
747+
bool was_opened;
748748
int ret;
749749

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

767-
was_running = netif_running(net);
768-
if (was_running) {
769-
ret = netvsc_close(net);
770-
if (ret)
771-
return ret;
772-
}
767+
was_opened = rndis_filter_opened(nvdev);
768+
if (was_opened)
769+
rndis_filter_close(nvdev);
773770

774771
rndis_filter_device_remove(dev, nvdev);
775772

@@ -779,10 +776,12 @@ static int netvsc_set_channels(struct net_device *net,
779776
else
780777
netvsc_set_queues(net, dev, nvdev->num_chn);
781778

782-
if (was_running)
783-
ret = netvsc_open(net);
779+
nvdev = rtnl_dereference(net_device_ctx->nvdev);
780+
if (was_opened)
781+
rndis_filter_open(nvdev);
784782

785783
/* We may have missed link change notifications */
784+
net_device_ctx->last_reconfig = 0;
786785
schedule_delayed_work(&net_device_ctx->dwork, 0);
787786

788787
return ret;
@@ -848,19 +847,18 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
848847
struct net_device_context *ndevctx = netdev_priv(ndev);
849848
struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
850849
struct hv_device *hdev = ndevctx->device_ctx;
850+
int orig_mtu = ndev->mtu;
851851
struct netvsc_device_info device_info;
852-
bool was_running;
852+
bool was_opened;
853853
int ret = 0;
854854

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

858-
was_running = netif_running(ndev);
859-
if (was_running) {
860-
ret = netvsc_close(ndev);
861-
if (ret)
862-
return ret;
863-
}
858+
netif_device_detach(ndev);
859+
was_opened = rndis_filter_opened(nvdev);
860+
if (was_opened)
861+
rndis_filter_close(nvdev);
864862

865863
memset(&device_info, 0, sizeof(device_info));
866864
device_info.ring_size = ring_size;
@@ -869,18 +867,21 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
869867

870868
rndis_filter_device_remove(hdev, nvdev);
871869

872-
/* 'nvdev' has been freed in rndis_filter_device_remove() ->
873-
* netvsc_device_remove () -> free_netvsc_device().
874-
* We mustn't access it before it's re-created in
875-
* rndis_filter_device_add() -> netvsc_device_add().
876-
*/
877-
878870
ndev->mtu = mtu;
879871

880-
rndis_filter_device_add(hdev, &device_info);
872+
nvdev = rndis_filter_device_add(hdev, &device_info);
873+
if (IS_ERR(nvdev)) {
874+
ret = PTR_ERR(nvdev);
875+
876+
/* Attempt rollback to original MTU */
877+
ndev->mtu = orig_mtu;
878+
rndis_filter_device_add(hdev, &device_info);
879+
}
880+
881+
if (was_opened)
882+
rndis_filter_open(nvdev);
881883

882-
if (was_running)
883-
ret = netvsc_open(ndev);
884+
netif_device_attach(ndev);
884885

885886
/* We may have missed link change notifications */
886887
schedule_delayed_work(&ndevctx->dwork, 0);
@@ -1363,7 +1364,7 @@ static struct net_device *get_netvsc_byref(struct net_device *vf_netdev)
13631364
continue; /* not a netvsc device */
13641365

13651366
net_device_ctx = netdev_priv(dev);
1366-
if (net_device_ctx->nvdev == NULL)
1367+
if (!rtnl_dereference(net_device_ctx->nvdev))
13671368
continue; /* device is removed */
13681369

13691370
if (rtnl_dereference(net_device_ctx->vf_netdev) == vf_netdev)
@@ -1528,8 +1529,10 @@ static int netvsc_probe(struct hv_device *dev,
15281529
memset(&device_info, 0, sizeof(device_info));
15291530
device_info.ring_size = ring_size;
15301531
device_info.num_chn = VRSS_CHANNEL_DEFAULT;
1531-
ret = rndis_filter_device_add(dev, &device_info);
1532-
if (ret != 0) {
1532+
1533+
nvdev = rndis_filter_device_add(dev, &device_info);
1534+
if (IS_ERR(nvdev)) {
1535+
ret = PTR_ERR(nvdev);
15331536
netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
15341537
free_netdev(net);
15351538
hv_set_drvdata(dev, NULL);
@@ -1543,10 +1546,11 @@ static int netvsc_probe(struct hv_device *dev,
15431546
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
15441547
net->vlan_features = net->features;
15451548

1546-
/* RCU not necessary here, device not registered */
1547-
nvdev = net_device_ctx->nvdev;
15481549
netif_set_real_num_tx_queues(net, nvdev->num_chn);
15491550
netif_set_real_num_rx_queues(net, nvdev->num_chn);
1551+
rtnl_unlock();
1552+
1553+
netdev_lockdep_set_classes(net);
15501554

15511555
/* MTU range: 68 - 1500 or 65521 */
15521556
net->min_mtu = NETVSC_MTU_MIN;
@@ -1588,7 +1592,8 @@ static int netvsc_remove(struct hv_device *dev)
15881592
* removed. Also blocks mtu and channel changes.
15891593
*/
15901594
rtnl_lock();
1591-
rndis_filter_device_remove(dev, ndev_ctx->nvdev);
1595+
rndis_filter_device_remove(dev,
1596+
rtnl_dereference(ndev_ctx->nvdev));
15921597
rtnl_unlock();
15931598

15941599
unregister_netdev(net);

0 commit comments

Comments
 (0)