Skip to content

Commit

Permalink
IB/hfi1: Rework AIP and VNIC dummy netdev usage
Browse files Browse the repository at this point in the history
All other users of the dummy netdevice embed the netdev in other
structures:

init_dummy_netdev(&mal->dummy_dev);
init_dummy_netdev(&eth->dummy_dev);
init_dummy_netdev(&ar->napi_dev);
init_dummy_netdev(&irq_grp->napi_ndev);
init_dummy_netdev(&wil->napi_ndev);
init_dummy_netdev(&trans_pcie->napi_dev);
init_dummy_netdev(&dev->napi_dev);
init_dummy_netdev(&bus->mux_dev);

The AIP and VNIC implementation turns that model inside out and used a
kfree() to free what appears to be a netdev struct when in reality, it is
a struct that enbodies the rx state as well as the dummy netdev used to
support napi_poll across disparate receive contexts.  The relationship is
infered by the odd allocation:

	const int netdev_size = sizeof(*dd->dummy_netdev) +
		sizeof(struct hfi1_netdev_priv);
	<snip>
	dd->dummy_netdev = kcalloc_node(1, netdev_size, GFP_KERNEL, dd->node);

Correct the issue by:
- Correctly naming the alloc and free functions
- Renaming hfi1_netdev_priv to hfi1_netdev_rx
- Replacing dd dummy_netdev with a netdev_rx pointer
- Embedding the net_device in hfi1_netdev_rx
- Moving the init_dummy_netdev to the alloc routine
- Adjusting wrappers to fit the new model

Fixes: 6991abc ("IB/hfi1: Add functions to receive accelerated ipoib packets")
Link: https://lore.kernel.org/r/1617026056-50483-11-git-send-email-dennis.dalessandro@cornelisnetworks.com
Reviewed-by: Kaike Wan <kaike.wan@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
  • Loading branch information
Mike Marciniszyn authored and Jason Gunthorpe committed Apr 13, 2021
1 parent 9c8823e commit 780278c
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 116 deletions.
6 changes: 3 additions & 3 deletions drivers/infiniband/hw/hfi1/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -15243,8 +15243,8 @@ int hfi1_init_dd(struct hfi1_devdata *dd)
(dd->revision >> CCE_REVISION_SW_SHIFT)
& CCE_REVISION_SW_MASK);

/* alloc netdev data */
ret = hfi1_netdev_alloc(dd);
/* alloc VNIC/AIP rx data */
ret = hfi1_alloc_rx(dd);
if (ret)
goto bail_cleanup;

Expand Down Expand Up @@ -15348,7 +15348,7 @@ int hfi1_init_dd(struct hfi1_devdata *dd)
hfi1_comp_vectors_clean_up(dd);
msix_clean_up_interrupts(dd);
bail_cleanup:
hfi1_netdev_free(dd);
hfi1_free_rx(dd);
hfi1_pcie_ddcleanup(dd);
bail_free:
hfi1_free_devdata(dd);
Expand Down
4 changes: 2 additions & 2 deletions drivers/infiniband/hw/hfi1/hfi.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
#include <rdma/ib_hdrs.h>
#include <rdma/opa_addr.h>
#include <linux/rhashtable.h>
#include <linux/netdevice.h>
#include <rdma/rdma_vt.h>

#include "chip_registers.h"
Expand Down Expand Up @@ -1060,6 +1059,7 @@ struct sdma_vl_map;
#define SERIAL_MAX 16 /* length of the serial number */

typedef int (*send_routine)(struct rvt_qp *, struct hfi1_pkt_state *, u64);
struct hfi1_netdev_rx;
struct hfi1_devdata {
struct hfi1_ibdev verbs_dev; /* must be first */
/* pointers to related structs for this device */
Expand Down Expand Up @@ -1402,7 +1402,7 @@ struct hfi1_devdata {
/* Lock to protect IRQ SRC register access */
spinlock_t irq_src_lock;
int vnic_num_vports;
struct net_device *dummy_netdev;
struct hfi1_netdev_rx *netdev_rx;

/* Keeps track of IPoIB RSM rule users */
atomic_t ipoib_rsm_usr_num;
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/hfi1/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1767,7 +1767,7 @@ static void remove_one(struct pci_dev *pdev)
hfi1_unregister_ib_device(dd);

/* free netdev data */
hfi1_netdev_free(dd);
hfi1_free_rx(dd);

/*
* Disable the IB link, disable interrupts on the device,
Expand Down
39 changes: 13 additions & 26 deletions drivers/infiniband/hw/hfi1/netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@

/**
* struct hfi1_netdev_rxq - Receive Queue for HFI
* dummy netdev. Both IPoIB and VNIC netdevices will be working on
* top of this device.
* Both IPoIB and VNIC netdevices will be working on the rx abstraction.
* @napi: napi object
* @priv: ptr to netdev_priv
* @rx: ptr to netdev_rx
* @rcd: ptr to receive context data
*/
struct hfi1_netdev_rxq {
struct napi_struct napi;
struct hfi1_netdev_priv *priv;
struct hfi1_netdev_rx *rx;
struct hfi1_ctxtdata *rcd;
};

Expand All @@ -36,7 +35,8 @@ struct hfi1_netdev_rxq {
#define NUM_NETDEV_MAP_ENTRIES HFI1_MAX_NETDEV_CTXTS

/**
* struct hfi1_netdev_priv: data required to setup and run HFI netdev.
* struct hfi1_netdev_rx: data required to setup and run HFI netdev.
* @rx_napi: the dummy netdevice to support "polling" the receive contexts
* @dd: hfi1_devdata
* @rxq: pointer to dummy netdev receive queues.
* @num_rx_q: number of receive queues
Expand All @@ -48,7 +48,8 @@ struct hfi1_netdev_rxq {
* @netdevs: atomic counter of netdevs using dummy netdev.
* When 0 receive queues will be freed.
*/
struct hfi1_netdev_priv {
struct hfi1_netdev_rx {
struct net_device rx_napi;
struct hfi1_devdata *dd;
struct hfi1_netdev_rxq *rxq;
int num_rx_q;
Expand All @@ -60,42 +61,28 @@ struct hfi1_netdev_priv {
atomic_t netdevs;
};

static inline
struct hfi1_netdev_priv *hfi1_netdev_priv(struct net_device *dev)
{
return (struct hfi1_netdev_priv *)&dev[1];
}

static inline
int hfi1_netdev_ctxt_count(struct hfi1_devdata *dd)
{
struct hfi1_netdev_priv *priv = hfi1_netdev_priv(dd->dummy_netdev);

return priv->num_rx_q;
return dd->netdev_rx->num_rx_q;
}

static inline
struct hfi1_ctxtdata *hfi1_netdev_get_ctxt(struct hfi1_devdata *dd, int ctxt)
{
struct hfi1_netdev_priv *priv = hfi1_netdev_priv(dd->dummy_netdev);

return priv->rxq[ctxt].rcd;
return dd->netdev_rx->rxq[ctxt].rcd;
}

static inline
int hfi1_netdev_get_free_rmt_idx(struct hfi1_devdata *dd)
{
struct hfi1_netdev_priv *priv = hfi1_netdev_priv(dd->dummy_netdev);

return priv->rmt_start;
return dd->netdev_rx->rmt_start;
}

static inline
void hfi1_netdev_set_free_rmt_idx(struct hfi1_devdata *dd, int rmt_idx)
{
struct hfi1_netdev_priv *priv = hfi1_netdev_priv(dd->dummy_netdev);

priv->rmt_start = rmt_idx;
dd->netdev_rx->rmt_start = rmt_idx;
}

u32 hfi1_num_netdev_contexts(struct hfi1_devdata *dd, u32 available_contexts,
Expand All @@ -105,8 +92,8 @@ void hfi1_netdev_enable_queues(struct hfi1_devdata *dd);
void hfi1_netdev_disable_queues(struct hfi1_devdata *dd);
int hfi1_netdev_rx_init(struct hfi1_devdata *dd);
int hfi1_netdev_rx_destroy(struct hfi1_devdata *dd);
int hfi1_netdev_alloc(struct hfi1_devdata *dd);
void hfi1_netdev_free(struct hfi1_devdata *dd);
int hfi1_alloc_rx(struct hfi1_devdata *dd);
void hfi1_free_rx(struct hfi1_devdata *dd);
int hfi1_netdev_add_data(struct hfi1_devdata *dd, int id, void *data);
void *hfi1_netdev_remove_data(struct hfi1_devdata *dd, int id);
void *hfi1_netdev_get_data(struct hfi1_devdata *dd, int id);
Expand Down
Loading

0 comments on commit 780278c

Please sign in to comment.