Message ID | 20190117204117.30826.2346.stgit@scvm10.sc.intel.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Jason Gunthorpe |
Headers | show |
Series | hfi1 and qib patches for rc | expand |
On Thu, Jan 17, 2019 at 12:41:22PM -0800, Dennis Dalessandro wrote: > From: Andrzej Witkowski <andrzej.witkowski@intel.com> > > VNIC uses the old deprecated path for freeing netdev private device > information. This will lead to a memory leak (of netdev devices) > and possibly incorrect cleanup behavior. > Fix by using the new API in the VNIC code path. > > Fixes: 9f49a5b5c21d ("RDMA/netdev: Use priv_destructor for netdev cleanup") ? vnic's flow didn't change at all in that patch, specifically to not create new bugs in it. I think it was already broken mind you.. What did that patch break, why is it listed as Fixes ? You need a better commit message for -rc patches, what is the exact flow that leaks a netdev? > Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com> > Signed-off-by: Andrzej Witkowski <andrzej.witkowski@intel.com> > Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> > drivers/infiniband/hw/hfi1/vnic_main.c | 4 ++-- > drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c | 5 ++--- > include/rdma/ib_verbs.h | 7 ------- > 3 files changed, 4 insertions(+), 12 deletions(-) > > diff --git a/drivers/infiniband/hw/hfi1/vnic_main.c b/drivers/infiniband/hw/hfi1/vnic_main.c > index a922db5..1d66c43 100644 > +++ b/drivers/infiniband/hw/hfi1/vnic_main.c > @@ -789,7 +789,6 @@ static void hfi1_vnic_free_rn(struct net_device *netdev) > > hfi1_vnic_deinit(vinfo); > mutex_destroy(&vinfo->lock); > - free_netdev(netdev); > } > > struct net_device *hfi1_vnic_alloc_rn(struct ib_device *device, > @@ -826,7 +825,6 @@ struct net_device *hfi1_vnic_alloc_rn(struct ib_device *device, > vinfo->num_tx_q = dd->num_sdma; > vinfo->num_rx_q = dd->num_vnic_contexts; > vinfo->netdev = netdev; > - rn->free_rdma_netdev = hfi1_vnic_free_rn; > rn->set_id = hfi1_vnic_set_vesw_id; > > netdev->features = NETIF_F_HIGHDMA | NETIF_F_SG; > @@ -834,6 +832,8 @@ struct net_device *hfi1_vnic_alloc_rn(struct ib_device *device, > netdev->vlan_features = netdev->features; > netdev->watchdog_timeo = msecs_to_jiffies(HFI_TX_TIMEOUT_MS); > netdev->netdev_ops = &hfi1_netdev_ops; > + netdev->priv_destructor = hfi1_vnic_free_rn; > + netdev->needs_free_netdev = true; > mutex_init(&vinfo->lock); > > for (i = 0; i < vinfo->num_rx_q; i++) { > diff --git a/drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c b/drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c > index ae70cd1..e21dc73 100644 > +++ b/drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c > @@ -382,7 +382,8 @@ struct opa_vnic_adapter *opa_vnic_add_netdev(struct ib_device *ibdev, > mutex_destroy(&adapter->mactbl_lock); > kfree(adapter); > adapter_err: > - rn->free_rdma_netdev(netdev); > + netdev->priv_destructor(netdev); > + free_netdev(netdev); register_netdev sometimes calls the priv_destructor, and sometimes doesn't, so this is a double free on error paths. Look at how ipoib works for guidance.. Jason
On 1/17/2019 4:09 PM, Jason Gunthorpe wrote: > On Thu, Jan 17, 2019 at 12:41:22PM -0800, Dennis Dalessandro wrote: >> From: Andrzej Witkowski <andrzej.witkowski@intel.com> >> >> VNIC uses the old deprecated path for freeing netdev private device >> information. This will lead to a memory leak (of netdev devices) >> and possibly incorrect cleanup behavior. > >> Fix by using the new API in the VNIC code path. >> >> Fixes: 9f49a5b5c21d ("RDMA/netdev: Use priv_destructor for netdev cleanup") > > ? vnic's flow didn't change at all in that patch, specifically to not > create new bugs in it. I think it was already broken mind you.. Quite possible. Will look into it. > register_netdev sometimes calls the priv_destructor, and sometimes > doesn't, so this is a double free on error paths. Look at how ipoib > works for guidance.. Will work with the patch author internally and revise. -Denny
diff --git a/drivers/infiniband/hw/hfi1/vnic_main.c b/drivers/infiniband/hw/hfi1/vnic_main.c index a922db5..1d66c43 100644 --- a/drivers/infiniband/hw/hfi1/vnic_main.c +++ b/drivers/infiniband/hw/hfi1/vnic_main.c @@ -789,7 +789,6 @@ static void hfi1_vnic_free_rn(struct net_device *netdev) hfi1_vnic_deinit(vinfo); mutex_destroy(&vinfo->lock); - free_netdev(netdev); } struct net_device *hfi1_vnic_alloc_rn(struct ib_device *device, @@ -826,7 +825,6 @@ struct net_device *hfi1_vnic_alloc_rn(struct ib_device *device, vinfo->num_tx_q = dd->num_sdma; vinfo->num_rx_q = dd->num_vnic_contexts; vinfo->netdev = netdev; - rn->free_rdma_netdev = hfi1_vnic_free_rn; rn->set_id = hfi1_vnic_set_vesw_id; netdev->features = NETIF_F_HIGHDMA | NETIF_F_SG; @@ -834,6 +832,8 @@ struct net_device *hfi1_vnic_alloc_rn(struct ib_device *device, netdev->vlan_features = netdev->features; netdev->watchdog_timeo = msecs_to_jiffies(HFI_TX_TIMEOUT_MS); netdev->netdev_ops = &hfi1_netdev_ops; + netdev->priv_destructor = hfi1_vnic_free_rn; + netdev->needs_free_netdev = true; mutex_init(&vinfo->lock); for (i = 0; i < vinfo->num_rx_q; i++) { diff --git a/drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c b/drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c index ae70cd1..e21dc73 100644 --- a/drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c +++ b/drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c @@ -382,7 +382,8 @@ struct opa_vnic_adapter *opa_vnic_add_netdev(struct ib_device *ibdev, mutex_destroy(&adapter->mactbl_lock); kfree(adapter); adapter_err: - rn->free_rdma_netdev(netdev); + netdev->priv_destructor(netdev); + free_netdev(netdev); return ERR_PTR(rc); } @@ -391,7 +392,6 @@ struct opa_vnic_adapter *opa_vnic_add_netdev(struct ib_device *ibdev, void opa_vnic_rem_netdev(struct opa_vnic_adapter *adapter) { struct net_device *netdev = adapter->netdev; - struct rdma_netdev *rn = netdev_priv(netdev); v_info("removing\n"); unregister_netdev(netdev); @@ -399,5 +399,4 @@ void opa_vnic_rem_netdev(struct opa_vnic_adapter *adapter) mutex_destroy(&adapter->lock); mutex_destroy(&adapter->mactbl_lock); kfree(adapter); - rn->free_rdma_netdev(netdev); } diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index a3ceed3..7539030 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -2213,13 +2213,6 @@ struct rdma_netdev { struct ib_device *hca; u8 port_num; - /* - * cleanup function must be specified. - * FIXME: This is only used for OPA_VNIC and that usage should be - * removed too. - */ - void (*free_rdma_netdev)(struct net_device *netdev); - /* control functions */ void (*set_id)(struct net_device *netdev, int id); /* send packet */