]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[infiniband] Remove concept of whole-device owner data
authorMichael Brown <mcb30@ipxe.org>
Tue, 1 Mar 2016 15:26:32 +0000 (15:26 +0000)
committerMichael Brown <mcb30@ipxe.org>
Mon, 7 Mar 2016 21:04:40 +0000 (21:04 +0000)
Remove the implicit assumption that the IPoIB protocol owns the whole
Infiniband device.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/net/ipoib.c
src/include/ipxe/infiniband.h

index 6552d764e312ecd487a92143ab4b52ece84242e4..e54f8df401570fe21429281254791fd1fa1aaf7e 100644 (file)
@@ -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,
 };
index 87cfe50827450c7c6ea07587e8b8332f2cbb9c33..6a99865f26bb4be663e4d357485efaa915075bf8 100644 (file)
@@ -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 */