david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[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>
This commit is contained in:
Michael Brown 2016-03-01 15:26:32 +00:00
parent fcf3b03544
commit 60e205a551
2 changed files with 45 additions and 35 deletions

View File

@ -79,6 +79,8 @@ struct ipoib_device {
struct net_device *netdev; struct net_device *netdev;
/** Underlying Infiniband device */ /** Underlying Infiniband device */
struct ib_device *ibdev; struct ib_device *ibdev;
/** List of IPoIB devices */
struct list_head list;
/** Completion queue */ /** Completion queue */
struct ib_completion_queue *cq; struct ib_completion_queue *cq;
/** Queue pair */ /** Queue pair */
@ -116,6 +118,9 @@ struct errortab ipoib_errors[] __errortab = {
__einfo_errortab ( EINFO_EINPROGRESS_JOINING ), __einfo_errortab ( EINFO_EINPROGRESS_JOINING ),
}; };
/** List of all IPoIB devices */
static LIST_HEAD ( ipoib_devices );
static struct net_device_operations ipoib_operations; 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 * Handle link status change
* *
* @v ibdev Infiniband device * @v ipoib IPoIB device
*/ */
static void ipoib_link_state_changed ( struct ib_device *ibdev ) { static void ipoib_link_state_changed ( struct ipoib_device *ipoib ) {
struct net_device *netdev = ib_get_ownerdata ( ibdev ); struct ib_device *ibdev = ipoib->ibdev;
struct ipoib_device *ipoib = netdev->priv; struct net_device *netdev = ipoib->netdev;
int rc; int rc;
/* Leave existing broadcast group */ /* Leave existing broadcast group */
@ -862,7 +867,7 @@ static int ipoib_open ( struct net_device *netdev ) {
ib_refill_recv ( ibdev, ipoib->qp ); ib_refill_recv ( ibdev, ipoib->qp );
/* Fake a link status change to join the broadcast group */ /* Fake a link status change to join the broadcast group */
ipoib_link_state_changed ( ibdev ); ipoib_link_state_changed ( ipoib );
return 0; return 0;
@ -928,7 +933,6 @@ static int ipoib_probe ( struct ib_device *ibdev ) {
return -ENOMEM; return -ENOMEM;
netdev_init ( netdev, &ipoib_operations ); netdev_init ( netdev, &ipoib_operations );
ipoib = netdev->priv; ipoib = netdev->priv;
ib_set_ownerdata ( ibdev, netdev );
netdev->dev = ibdev->dev; netdev->dev = ibdev->dev;
memset ( ipoib, 0, sizeof ( *ipoib ) ); memset ( ipoib, 0, sizeof ( *ipoib ) );
ipoib->netdev = netdev; ipoib->netdev = netdev;
@ -947,35 +951,65 @@ static int ipoib_probe ( struct ib_device *ibdev ) {
memcpy ( &ipoib->broadcast, &ipoib_broadcast, memcpy ( &ipoib->broadcast, &ipoib_broadcast,
sizeof ( ipoib->broadcast ) ); sizeof ( ipoib->broadcast ) );
/* Add to list of IPoIB devices */
list_add_tail ( &ipoib->list, &ipoib_devices );
/* Register network device */ /* Register network device */
if ( ( rc = register_netdev ( netdev ) ) != 0 ) if ( ( rc = register_netdev ( netdev ) ) != 0 )
goto err_register_netdev; goto err_register_netdev;
return 0; return 0;
unregister_netdev ( netdev );
err_register_netdev: err_register_netdev:
list_del ( &ipoib->list );
netdev_nullify ( netdev ); netdev_nullify ( netdev );
netdev_put ( netdev ); netdev_put ( netdev );
return rc; 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 * Remove IPoIB device
* *
* @v ibdev Infiniband device * @v ibdev Infiniband device
*/ */
static void ipoib_remove ( struct ib_device *ibdev ) { 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 ); /* Remove any attached IPoIB devices */
netdev_nullify ( netdev ); list_for_each_entry_safe ( ipoib, tmp, &ipoib_devices, list ) {
netdev_put ( netdev ); if ( ipoib->ibdev != ibdev )
continue;
netdev = ipoib->netdev;
unregister_netdev ( netdev );
list_del ( &ipoib->list );
netdev_nullify ( netdev );
netdev_put ( netdev );
}
} }
/** IPoIB driver */ /** IPoIB driver */
struct ib_driver ipoib_driver __ib_driver = { struct ib_driver ipoib_driver __ib_driver = {
.name = "IPoIB", .name = "IPoIB",
.probe = ipoib_probe, .probe = ipoib_probe,
.notify = ipoib_link_state_changed, .notify = ipoib_notify,
.remove = ipoib_remove, .remove = ipoib_remove,
}; };

View File

@ -450,8 +450,6 @@ struct ib_device {
/** Driver private data */ /** Driver private data */
void *drv_priv; void *drv_priv;
/** Owner private data */
void *owner_priv;
}; };
/** An Infiniband upper-layer driver */ /** An Infiniband upper-layer driver */
@ -695,26 +693,4 @@ ib_get_drvdata ( struct ib_device *ibdev ) {
return ibdev->drv_priv; 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 */ #endif /* _IPXE_INFINIBAND_H */