From 4baa994dc93287321c1b712d98cb6f721652891b Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 3 Jun 2016 17:50:58 +0200 Subject: [PATCH 1/5] hv_netvsc: remove redundant assignment in netvsc_recv_callback() net_device_ctx is assigned in the very beginning of the function and 'net' pointer doesn't change. Signed-off-by: Vitaly Kuznetsov Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 5ac1267b393f..58cb5fedb41f 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -701,7 +701,6 @@ int netvsc_recv_callback(struct hv_device *device_obj, } vf_injection_done: - net_device_ctx = netdev_priv(net); rx_stats = this_cpu_ptr(net_device_ctx->rx_stats); /* Allocate a skb - TODO direct I/O to pages? */ From 2625466d6d92f056da970bee990c862c54188819 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 3 Jun 2016 17:50:59 +0200 Subject: [PATCH 2/5] hv_netvsc: introduce {net, hv}_device_to_netvsc_device() helpers Make it easier to get 'struct netvsc_device' from 'struct net_device' and 'struct hv_device' by introducing inline helpers. Signed-off-by: Vitaly Kuznetsov Signed-off-by: David S. Miller --- drivers/net/hyperv/hyperv_net.h | 12 ++++++++++++ drivers/net/hyperv/netvsc.c | 11 +++-------- drivers/net/hyperv/rndis_filter.c | 24 +++++++----------------- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index c270c5a54f3a..952cbc860676 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -743,6 +743,18 @@ struct netvsc_device { atomic_t vf_use_cnt; }; +static inline struct netvsc_device * +net_device_to_netvsc_device(struct net_device *ndev) +{ + return ((struct net_device_context *)netdev_priv(ndev))->nvdev; +} + +static inline struct netvsc_device * +hv_device_to_netvsc_device(struct hv_device *device) +{ + return net_device_to_netvsc_device(hv_get_drvdata(device)); +} + /* NdisInitialize message */ struct rndis_initialize_request { u32 req_id; diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 719cb3578e55..96f00c0261fa 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -95,9 +95,7 @@ static void free_netvsc_device(struct netvsc_device *nvdev) static struct netvsc_device *get_outbound_net_device(struct hv_device *device) { - struct net_device *ndev = hv_get_drvdata(device); - struct net_device_context *net_device_ctx = netdev_priv(ndev); - struct netvsc_device *net_device = net_device_ctx->nvdev; + struct netvsc_device *net_device = hv_device_to_netvsc_device(device); if (net_device && net_device->destroy) net_device = NULL; @@ -107,9 +105,7 @@ static struct netvsc_device *get_outbound_net_device(struct hv_device *device) static struct netvsc_device *get_inbound_net_device(struct hv_device *device) { - struct net_device *ndev = hv_get_drvdata(device); - struct net_device_context *net_device_ctx = netdev_priv(ndev); - struct netvsc_device *net_device = net_device_ctx->nvdev; + struct netvsc_device *net_device = hv_device_to_netvsc_device(device); if (!net_device) goto get_in_err; @@ -128,8 +124,7 @@ static int netvsc_destroy_buf(struct hv_device *device) struct nvsp_message *revoke_packet; int ret = 0; struct net_device *ndev = hv_get_drvdata(device); - struct net_device_context *net_device_ctx = netdev_priv(ndev); - struct netvsc_device *net_device = net_device_ctx->nvdev; + struct netvsc_device *net_device = net_device_to_netvsc_device(ndev); /* * If we got a section count, it means we received a diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 97c292b7dbea..42c652e0cdc7 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -546,8 +546,7 @@ static int rndis_filter_query_device_mac(struct rndis_device *dev) int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac) { struct net_device *ndev = hv_get_drvdata(hdev); - struct net_device_context *net_device_ctx = netdev_priv(ndev); - struct netvsc_device *nvdev = net_device_ctx->nvdev; + struct netvsc_device *nvdev = net_device_to_netvsc_device(ndev); struct rndis_device *rdev = nvdev->extension; struct rndis_request *request; struct rndis_set_request *set; @@ -626,8 +625,7 @@ rndis_filter_set_offload_params(struct hv_device *hdev, struct ndis_offload_params *req_offloads) { struct net_device *ndev = hv_get_drvdata(hdev); - struct net_device_context *net_device_ctx = netdev_priv(ndev); - struct netvsc_device *nvdev = net_device_ctx->nvdev; + struct netvsc_device *nvdev = net_device_to_netvsc_device(ndev); struct rndis_device *rdev = nvdev->extension; struct rndis_request *request; struct rndis_set_request *set; @@ -851,8 +849,7 @@ static int rndis_filter_init_device(struct rndis_device *dev) u32 status; int ret; unsigned long t; - struct net_device_context *net_device_ctx = netdev_priv(dev->ndev); - struct netvsc_device *nvdev = net_device_ctx->nvdev; + struct netvsc_device *nvdev = net_device_to_netvsc_device(dev->ndev); request = get_rndis_request(dev, RNDIS_MSG_INIT, RNDIS_MESSAGE_SIZE(struct rndis_initialize_request)); @@ -977,8 +974,7 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc) { struct net_device *ndev = hv_get_drvdata(new_sc->primary_channel->device_obj); - struct net_device_context *net_device_ctx = netdev_priv(ndev); - struct netvsc_device *nvscdev = net_device_ctx->nvdev; + struct netvsc_device *nvscdev = net_device_to_netvsc_device(ndev); u16 chn_index = new_sc->offermsg.offer.sub_channel_index; int ret; unsigned long flags; @@ -1196,9 +1192,7 @@ int rndis_filter_device_add(struct hv_device *dev, void rndis_filter_device_remove(struct hv_device *dev) { - struct net_device *ndev = hv_get_drvdata(dev); - struct net_device_context *net_device_ctx = netdev_priv(ndev); - struct netvsc_device *net_dev = net_device_ctx->nvdev; + struct netvsc_device *net_dev = hv_device_to_netvsc_device(dev); struct rndis_device *rndis_dev = net_dev->extension; unsigned long t; @@ -1224,9 +1218,7 @@ void rndis_filter_device_remove(struct hv_device *dev) int rndis_filter_open(struct hv_device *dev) { - struct net_device *ndev = hv_get_drvdata(dev); - struct net_device_context *net_device_ctx = netdev_priv(ndev); - struct netvsc_device *net_device = net_device_ctx->nvdev; + struct netvsc_device *net_device = hv_device_to_netvsc_device(dev); if (!net_device) return -EINVAL; @@ -1239,9 +1231,7 @@ int rndis_filter_open(struct hv_device *dev) int rndis_filter_close(struct hv_device *dev) { - struct net_device *ndev = hv_get_drvdata(dev); - struct net_device_context *net_device_ctx = netdev_priv(ndev); - struct netvsc_device *nvdev = net_device_ctx->nvdev; + struct netvsc_device *nvdev = hv_device_to_netvsc_device(dev); if (!nvdev) return -EINVAL; From 2f5fa6c869e8f8c340dd05a2817eecbcea382c35 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 3 Jun 2016 17:51:00 +0200 Subject: [PATCH 3/5] hv_netvsc: pass struct netvsc_device to rndis_filter_{open, close}() Both rndis_filter_open()/rndis_filter_close() use struct hv_device to reach to struct netvsc_device only and all callers have it already. While on it, rename net_device to nvdev in rndis_filter_open() as net_device is misleading. Signed-off-by: Vitaly Kuznetsov Signed-off-by: David S. Miller --- drivers/net/hyperv/hyperv_net.h | 5 +++-- drivers/net/hyperv/netvsc_drv.c | 13 +++++-------- drivers/net/hyperv/rndis_filter.c | 14 +++++--------- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 952cbc860676..f650ec14c7cd 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -173,6 +173,7 @@ struct rndis_device { /* Interface */ struct rndis_message; +struct netvsc_device; int netvsc_device_add(struct hv_device *device, void *additional_info); int netvsc_device_remove(struct hv_device *device); int netvsc_send(struct hv_device *device, @@ -189,8 +190,8 @@ int netvsc_recv_callback(struct hv_device *device_obj, struct vmbus_channel *channel, u16 vlan_tci); void netvsc_channel_cb(void *context); -int rndis_filter_open(struct hv_device *dev); -int rndis_filter_close(struct hv_device *dev); +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, void *additional_info); void rndis_filter_device_remove(struct hv_device *dev); diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 58cb5fedb41f..2492f83d2bd5 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -98,16 +98,14 @@ static void netvsc_set_multicast_list(struct net_device *net) static int netvsc_open(struct net_device *net) { - struct net_device_context *net_device_ctx = netdev_priv(net); - struct hv_device *device_obj = net_device_ctx->device_ctx; - struct netvsc_device *nvdev = net_device_ctx->nvdev; + struct netvsc_device *nvdev = net_device_to_netvsc_device(net); struct rndis_device *rdev; int ret = 0; netif_carrier_off(net); /* Open up the device */ - ret = rndis_filter_open(device_obj); + ret = rndis_filter_open(nvdev); if (ret != 0) { netdev_err(net, "unable to open device (ret %d).\n", ret); return ret; @@ -125,7 +123,6 @@ static int netvsc_open(struct net_device *net) static int netvsc_close(struct net_device *net) { struct net_device_context *net_device_ctx = netdev_priv(net); - struct hv_device *device_obj = net_device_ctx->device_ctx; struct netvsc_device *nvdev = net_device_ctx->nvdev; int ret; u32 aread, awrite, i, msec = 10, retry = 0, retry_max = 20; @@ -135,7 +132,7 @@ static int netvsc_close(struct net_device *net) /* Make sure netvsc_set_multicast_list doesn't re-enable filter! */ cancel_work_sync(&net_device_ctx->work); - ret = rndis_filter_close(device_obj); + ret = rndis_filter_close(nvdev); if (ret != 0) { netdev_err(net, "unable to close device (ret %d).\n", ret); return ret; @@ -1247,7 +1244,7 @@ static int netvsc_vf_up(struct net_device *vf_netdev) /* * Open the device before switching data path. */ - rndis_filter_open(net_device_ctx->device_ctx); + rndis_filter_open(netvsc_dev); /* * notify the host to switch the data path. @@ -1302,7 +1299,7 @@ static int netvsc_vf_down(struct net_device *vf_netdev) udelay(50); netvsc_switch_datapath(ndev, false); netdev_info(ndev, "Data path switched from VF: %s\n", vf_netdev->name); - rndis_filter_close(net_device_ctx->device_ctx); + rndis_filter_close(netvsc_dev); netif_carrier_on(ndev); /* * Notify peers. diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 42c652e0cdc7..2c2f3b92cc4a 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -1216,23 +1216,19 @@ void rndis_filter_device_remove(struct hv_device *dev) } -int rndis_filter_open(struct hv_device *dev) +int rndis_filter_open(struct netvsc_device *nvdev) { - struct netvsc_device *net_device = hv_device_to_netvsc_device(dev); - - if (!net_device) + if (!nvdev) return -EINVAL; - if (atomic_inc_return(&net_device->open_cnt) != 1) + if (atomic_inc_return(&nvdev->open_cnt) != 1) return 0; - return rndis_filter_open_device(net_device->extension); + return rndis_filter_open_device(nvdev->extension); } -int rndis_filter_close(struct hv_device *dev) +int rndis_filter_close(struct netvsc_device *nvdev) { - struct netvsc_device *nvdev = hv_device_to_netvsc_device(dev); - if (!nvdev) return -EINVAL; From e834da9a40edd3117ef0a9b2a73d845fe6b622a8 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 3 Jun 2016 17:51:01 +0200 Subject: [PATCH 4/5] hv_netvsc: pass struct net_device to rndis_filter_set_device_mac() We unpack 'struct net_device' in netvsc_set_mac_addr() to get to 'struct hv_device' pointer which we use in rndis_filter_set_device_mac() to get back to 'struct net_device'. Signed-off-by: Vitaly Kuznetsov Signed-off-by: David S. Miller --- drivers/net/hyperv/hyperv_net.h | 2 +- drivers/net/hyperv/netvsc_drv.c | 4 +--- drivers/net/hyperv/rndis_filter.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index f650ec14c7cd..467fb8b4d083 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -201,7 +201,7 @@ int rndis_filter_receive(struct hv_device *dev, struct vmbus_channel *channel); int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter); -int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac); +int rndis_filter_set_device_mac(struct net_device *ndev, char *mac); void netvsc_switch_datapath(struct net_device *nv_dev, bool vf); diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 2492f83d2bd5..787a20235e5c 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -982,8 +982,6 @@ static struct rtnl_link_stats64 *netvsc_get_stats64(struct net_device *net, static int netvsc_set_mac_addr(struct net_device *ndev, void *p) { - struct net_device_context *ndevctx = netdev_priv(ndev); - struct hv_device *hdev = ndevctx->device_ctx; struct sockaddr *addr = p; char save_adr[ETH_ALEN]; unsigned char save_aatype; @@ -996,7 +994,7 @@ static int netvsc_set_mac_addr(struct net_device *ndev, void *p) if (err != 0) return err; - err = rndis_filter_set_device_mac(hdev, addr->sa_data); + err = rndis_filter_set_device_mac(ndev, addr->sa_data); if (err != 0) { /* roll back to saved MAC */ memcpy(ndev->dev_addr, save_adr, ETH_ALEN); diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 2c2f3b92cc4a..f1692bcd19be 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -543,9 +543,8 @@ static int rndis_filter_query_device_mac(struct rndis_device *dev) #define NWADR_STR "NetworkAddress" #define NWADR_STRLEN 14 -int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac) +int rndis_filter_set_device_mac(struct net_device *ndev, char *mac) { - struct net_device *ndev = hv_get_drvdata(hdev); struct netvsc_device *nvdev = net_device_to_netvsc_device(ndev); struct rndis_device *rdev = nvdev->extension; struct rndis_request *request; From 426d95417eebc0698e878708a8a44980e8b7570d Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 3 Jun 2016 17:51:02 +0200 Subject: [PATCH 5/5] hv_netvsc: pass struct net_device to rndis_filter_set_offload_params() The only caller rndis_filter_device_add() has 'struct net_device' pointer already. Signed-off-by: Vitaly Kuznetsov Signed-off-by: David S. Miller --- drivers/net/hyperv/rndis_filter.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index f1692bcd19be..979fa4455f72 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -620,10 +620,9 @@ int rndis_filter_set_device_mac(struct net_device *ndev, char *mac) } static int -rndis_filter_set_offload_params(struct hv_device *hdev, +rndis_filter_set_offload_params(struct net_device *ndev, struct ndis_offload_params *req_offloads) { - struct net_device *ndev = hv_get_drvdata(hdev); struct netvsc_device *nvdev = net_device_to_netvsc_device(ndev); struct rndis_device *rdev = nvdev->extension; struct rndis_request *request; @@ -1083,7 +1082,7 @@ int rndis_filter_device_add(struct hv_device *dev, offloads.lso_v2_ipv4 = NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED; - ret = rndis_filter_set_offload_params(dev, &offloads); + ret = rndis_filter_set_offload_params(net, &offloads); if (ret) goto err_dev_remv;