hv_netvsc: fix multicast flags and sync
Subsystems (3)
v2 cover hv_netvsc: fix multicast flags and sync
This set of patches deals with the handling of multicast flags and addresses in transparent VF mode. The recent set of patches (in linux-net) had a couple of bugs.
Stephen Hemminger (4):
hv_netvsc: fix filter flags
hv_netvsc: avoid repeated updates of packet filter
hv_netvsc: fix locking for rx_mode
hv_netvsc: fix locking during VF setup
drivers/net/hyperv/hyperv_net.h | 1 + drivers/net/hyperv/netvsc_drv.c | 15 ++++++++++++--- drivers/net/hyperv/rndis_filter.c | 12 ++++++++---- 3 files changed, 21 insertions(+), 7 deletions(-)
Signature · 1 line
2.16.1
PATCH v2 1/4 hv_netvsc: fix filter flags
The recent change to nto always enable all multicast and broadcast was broken; meant to set filter, not change flags.
--- drivers/net/hyperv/rndis_filter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/hyperv/rndis_filter.c +2 -2
@@ -861,9 +861,9 @@ static void rndis_set_multicast(struct work_struct *w) filter =NDIS_PACKET_TYPE_PROMISCUOUS ; }else {if (flags &IFF_ALLMULTI ) - flags |=NDIS_PACKET_TYPE_ALL_MULTICAST ; + filter |=NDIS_PACKET_TYPE_ALL_MULTICAST ;if (flags &IFF_BROADCAST ) - flags |=NDIS_PACKET_TYPE_BROADCAST ; + filter |=NDIS_PACKET_TYPE_BROADCAST ; }rndis_filter_set_packet_filter (rdev, filter);
Signature · 1 line
2.16.1
PATCH v2 2/4 hv_netvsc: avoid repeated updates of packet filter
In reply to Stephen HemmingerThe netvsc driver can get repeated calls to netvsc_rx_mode during network setup; each of these calls ends up scheduling the lower layers to update tha packet filter. This update requires an request/response to the host. So avoid doing this if we already know that the correct packet filter value is set.
--- drivers/net/hyperv/hyperv_net.h | 1 + drivers/net/hyperv/rndis_filter.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-)
drivers/net/hyperv/hyperv_net.h +1 -0
@@ -173,6 +173,7 @@ struct rndis_device {struct list_head req_list;struct work_struct mcast_work; +u32 filter;bool link_state;/* 0 - link up, 1 - link down */
drivers/net/hyperv/rndis_filter.c +6 -2
@@ -825,13 +825,15 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev,struct rndis_set_request *set;int ret; +if (dev->filter == new_filter) +return 0 ; + request =get_rndis_request (dev,RNDIS_MSG_SET , RNDIS_MESSAGE_SIZE(struct rndis_set_request) +sizeof (u32));if (!request)return -ENOMEM ; -/* Setup the rndis set */ set = &request->request_msg.msg.set_req; set->oid =RNDIS_OID_GEN_CURRENT_PACKET_FILTER ;
@@ -842,8 +844,10 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, &new_filter, sizeof(u32)); ret =rndis_filter_send_request (dev, request); -if (ret ==0 ) +if (ret ==0 ) {wait_for_completion (&request->wait_event); + dev->filter = new_filter; + }put_rndis_request (dev, request);
Signature · 1 line
2.16.1
PATCH v2 3/4 hv_netvsc: fix locking for rx_mode
In reply to Stephen HemmingerThe rx_mode operation handler is different than other callbacks in that is not always called with rtnl held. Therefore use RCU to ensure that references are valid.
--- drivers/net/hyperv/netvsc_drv.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/net/hyperv/netvsc_drv.c +8 -3
@@ -89,15 +89,20 @@ static void netvsc_change_rx_flags(struct net_device *net, int change)static void netvsc_set_rx_mode (struct net_device *net) {struct net_device_context *ndev_ctx =netdev_priv (net); -struct net_device *vf_netdev =rtnl_dereference (ndev_ctx->vf_netdev); -struct netvsc_device *nvdev =rtnl_dereference (ndev_ctx->nvdev); +struct net_device *vf_netdev; +struct netvsc_device *nvdev; +rcu_read_lock (); + vf_netdev =rcu_dereference (ndev_ctx->vf_netdev);if (vf_netdev) {dev_uc_sync (vf_netdev, net);dev_mc_sync (vf_netdev, net); } -rndis_filter_update (nvdev); + nvdev =rcu_dereference (ndev_ctx->nvdev); +if (nvdev) +rndis_filter_update (nvdev); +rcu_read_unlock (); }static int netvsc_open (struct net_device *net)
Signature · 1 line
2.16.1
PATCH v2 4/4 hv_netvsc: fix locking during VF setup
In reply to Stephen HemmingerThe dev_uc/mc_sync calls need to have the device address list locked. This was spotted by running with lockdep enabled.
--- drivers/net/hyperv/netvsc_drv.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/hyperv/netvsc_drv.c +4 -0
@@ -1851,8 +1851,12 @@ static void __netvsc_vf_setup(struct net_device *ndev,/* set multicast etc flags on VF */ dev_change_flags (vf_netdev, ndev->flags |IFF_SLAVE ); + +/* sync address list from ndev to VF */ +netif_addr_lock_bh (ndev);dev_uc_sync (vf_netdev, ndev);dev_mc_sync (vf_netdev, ndev); +netif_addr_unlock_bh (ndev);if (netif_running (ndev)) { ret =dev_open (vf_netdev);
Signature · 1 line
2.16.1
David Miller
maintainerFrom: Stephen Hemminger <[email protected]>
Date: Wed, 7 Mar 2018 13:49:08 -0800
Quoted 3 lines
This set of patches deals with the handling of multicast flags and addresses in transparent VF mode. The recent set of patches (in linux-net) had a couple of bugs.
Series applied, thanks Stephen.