diff options
author | Michael Brown <mcb30@ipxe.org> | 2016-03-01 15:26:32 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2016-03-07 21:04:40 +0000 |
commit | 60e205a551f07882ed18a33fa192ad7cefe548a0 (patch) | |
tree | 89dce4b91d85dc435aca2047262e10c18a3e3ef2 | |
parent | fcf3b0354428df2e8237b7d0fca2457ff7d87fac (diff) | |
download | ipxe-60e205a551f07882ed18a33fa192ad7cefe548a0.zip ipxe-60e205a551f07882ed18a33fa192ad7cefe548a0.tar.gz ipxe-60e205a551f07882ed18a33fa192ad7cefe548a0.tar.bz2 |
[infiniband] Remove concept of whole-device owner data
Remove the implicit assumption that the IPoIB protocol owns the whole
Infiniband device.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/drivers/net/ipoib.c | 56 | ||||
-rw-r--r-- | src/include/ipxe/infiniband.h | 24 |
2 files changed, 45 insertions, 35 deletions
diff --git a/src/drivers/net/ipoib.c b/src/drivers/net/ipoib.c index 6552d76..e54f8df 100644 --- a/src/drivers/net/ipoib.c +++ b/src/drivers/net/ipoib.c @@ -79,6 +79,8 @@ struct ipoib_device { struct net_device *netdev; /** Underlying Infiniband device */ struct ib_device *ibdev; + /** List of IPoIB devices */ + struct list_head list; /** Completion queue */ struct ib_completion_queue *cq; /** Queue pair */ @@ -116,6 +118,9 @@ struct errortab ipoib_errors[] __errortab = { __einfo_errortab ( EINFO_EINPROGRESS_JOINING ), }; +/** List of all IPoIB devices */ +static LIST_HEAD ( ipoib_devices ); + static struct net_device_operations ipoib_operations; /**************************************************************************** @@ -783,11 +788,11 @@ static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) { /** * Handle link status change * - * @v ibdev Infiniband device + * @v ipoib IPoIB device */ -static void ipoib_link_state_changed ( struct ib_device *ibdev ) { - struct net_device *netdev = ib_get_ownerdata ( ibdev ); - struct ipoib_device *ipoib = netdev->priv; +static void ipoib_link_state_changed ( struct ipoib_device *ipoib ) { + struct ib_device *ibdev = ipoib->ibdev; + struct net_device *netdev = ipoib->netdev; int rc; /* Leave existing broadcast group */ @@ -862,7 +867,7 @@ static int ipoib_open ( struct net_device *netdev ) { ib_refill_recv ( ibdev, ipoib->qp ); /* Fake a link status change to join the broadcast group */ - ipoib_link_state_changed ( ibdev ); + ipoib_link_state_changed ( ipoib ); return 0; @@ -928,7 +933,6 @@ static int ipoib_probe ( struct ib_device *ibdev ) { return -ENOMEM; netdev_init ( netdev, &ipoib_operations ); ipoib = netdev->priv; - ib_set_ownerdata ( ibdev, netdev ); netdev->dev = ibdev->dev; memset ( ipoib, 0, sizeof ( *ipoib ) ); ipoib->netdev = netdev; @@ -947,35 +951,65 @@ static int ipoib_probe ( struct ib_device *ibdev ) { memcpy ( &ipoib->broadcast, &ipoib_broadcast, sizeof ( ipoib->broadcast ) ); + /* Add to list of IPoIB devices */ + list_add_tail ( &ipoib->list, &ipoib_devices ); + /* Register network device */ if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err_register_netdev; return 0; + unregister_netdev ( netdev ); err_register_netdev: + list_del ( &ipoib->list ); netdev_nullify ( netdev ); netdev_put ( netdev ); return rc; } /** + * Handle device or link status change + * + * @v ibdev Infiniband device + */ +static void ipoib_notify ( struct ib_device *ibdev ) { + struct ipoib_device *ipoib; + + /* Handle link status change for any attached IPoIB devices */ + list_for_each_entry ( ipoib, &ipoib_devices, list ) { + if ( ipoib->ibdev != ibdev ) + continue; + ipoib_link_state_changed ( ipoib ); + } +} + +/** * Remove IPoIB device * * @v ibdev Infiniband device */ static void ipoib_remove ( struct ib_device *ibdev ) { - struct net_device *netdev = ib_get_ownerdata ( ibdev ); + struct ipoib_device *ipoib; + struct ipoib_device *tmp; + struct net_device *netdev; - unregister_netdev ( netdev ); - netdev_nullify ( netdev ); - netdev_put ( netdev ); + /* Remove any attached IPoIB devices */ + list_for_each_entry_safe ( ipoib, tmp, &ipoib_devices, list ) { + if ( ipoib->ibdev != ibdev ) + continue; + netdev = ipoib->netdev; + unregister_netdev ( netdev ); + list_del ( &ipoib->list ); + netdev_nullify ( netdev ); + netdev_put ( netdev ); + } } /** IPoIB driver */ struct ib_driver ipoib_driver __ib_driver = { .name = "IPoIB", .probe = ipoib_probe, - .notify = ipoib_link_state_changed, + .notify = ipoib_notify, .remove = ipoib_remove, }; diff --git a/src/include/ipxe/infiniband.h b/src/include/ipxe/infiniband.h index 87cfe50..6a99865 100644 --- a/src/include/ipxe/infiniband.h +++ b/src/include/ipxe/infiniband.h @@ -450,8 +450,6 @@ struct ib_device { /** Driver private data */ void *drv_priv; - /** Owner private data */ - void *owner_priv; }; /** An Infiniband upper-layer driver */ @@ -695,26 +693,4 @@ ib_get_drvdata ( struct ib_device *ibdev ) { return ibdev->drv_priv; } -/** - * Set Infiniband device owner-private data - * - * @v ibdev Infiniband device - * @v priv Private data - */ -static inline __always_inline void -ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) { - ibdev->owner_priv = priv; -} - -/** - * Get Infiniband device owner-private data - * - * @v ibdev Infiniband device - * @ret priv Private data - */ -static inline __always_inline void * -ib_get_ownerdata ( struct ib_device *ibdev ) { - return ibdev->owner_priv; -} - #endif /* _IPXE_INFINIBAND_H */ |