Browse Source

[infiniband] Add the concept of an Infiniband upper-layer driver

Replace the explicit calls from the Infiniband core to the IPoIB layer
with the general concept of an Infiniband upper-layer driver
(analogous to a PCI driver) which can create arbitrary devices on top
of Infiniband devices.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
35b19d8848
4 changed files with 169 additions and 80 deletions
  1. 46
    38
      src/drivers/net/ipoib.c
  2. 41
    1
      src/include/ipxe/infiniband.h
  3. 0
    3
      src/include/ipxe/ipoib.h
  4. 82
    38
      src/net/infiniband.c

+ 46
- 38
src/drivers/net/ipoib.c View File

597
 	}
597
 	}
598
 }
598
 }
599
 
599
 
600
+/**
601
+ * Handle link status change
602
+ *
603
+ * @v ibdev		Infiniband device
604
+ */
605
+static void ipoib_link_state_changed ( struct ib_device *ibdev ) {
606
+	struct net_device *netdev = ib_get_ownerdata ( ibdev );
607
+	struct ipoib_device *ipoib = netdev->priv;
608
+	struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
609
+	int rc;
610
+
611
+	/* Leave existing broadcast group */
612
+	ipoib_leave_broadcast_group ( ipoib );
613
+
614
+	/* Update MAC address based on potentially-new GID prefix */
615
+	memcpy ( &mac->gid.u.half[0], &ibdev->gid.u.half[0],
616
+		 sizeof ( mac->gid.u.half[0] ) );
617
+
618
+	/* Update broadcast GID based on potentially-new partition key */
619
+	ipoib->broadcast.gid.u.words[2] =
620
+		htons ( ibdev->pkey | IB_PKEY_FULL );
621
+
622
+	/* Set net device link state to reflect Infiniband link state */
623
+	rc = ib_link_rc ( ibdev );
624
+	netdev_link_err ( netdev, ( rc ? rc : -EINPROGRESS_JOINING ) );
625
+
626
+	/* Join new broadcast group */
627
+	if ( ib_is_open ( ibdev ) && ib_link_ok ( ibdev ) &&
628
+	     ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) ) {
629
+		DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: "
630
+		       "%s\n", ipoib, strerror ( rc ) );
631
+		netdev_link_err ( netdev, rc );
632
+		return;
633
+	}
634
+}
635
+
600
 /**
636
 /**
601
  * Open IPoIB network device
637
  * Open IPoIB network device
602
  *
638
  *
690
 	.irq		= ipoib_irq,
726
 	.irq		= ipoib_irq,
691
 };
727
 };
692
 
728
 
693
-/**
694
- * Handle link status change
695
- *
696
- * @v ibdev		Infiniband device
697
- */
698
-void ipoib_link_state_changed ( struct ib_device *ibdev ) {
699
-	struct net_device *netdev = ib_get_ownerdata ( ibdev );
700
-	struct ipoib_device *ipoib = netdev->priv;
701
-	struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
702
-	int rc;
703
-
704
-	/* Leave existing broadcast group */
705
-	ipoib_leave_broadcast_group ( ipoib );
706
-
707
-	/* Update MAC address based on potentially-new GID prefix */
708
-	memcpy ( &mac->gid.u.half[0], &ibdev->gid.u.half[0],
709
-		 sizeof ( mac->gid.u.half[0] ) );
710
-
711
-	/* Update broadcast GID based on potentially-new partition key */
712
-	ipoib->broadcast.gid.u.words[2] =
713
-		htons ( ibdev->pkey | IB_PKEY_FULL );
714
-
715
-	/* Set net device link state to reflect Infiniband link state */
716
-	rc = ib_link_rc ( ibdev );
717
-	netdev_link_err ( netdev, ( rc ? rc : -EINPROGRESS_JOINING ) );
718
-
719
-	/* Join new broadcast group */
720
-	if ( ib_link_ok ( ibdev ) &&
721
-	     ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) ) {
722
-		DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: "
723
-		       "%s\n", ipoib, strerror ( rc ) );
724
-		netdev_link_err ( netdev, rc );
725
-		return;
726
-	}
727
-}
728
-
729
 /**
729
 /**
730
  * Probe IPoIB device
730
  * Probe IPoIB device
731
  *
731
  *
732
  * @v ibdev		Infiniband device
732
  * @v ibdev		Infiniband device
733
  * @ret rc		Return status code
733
  * @ret rc		Return status code
734
  */
734
  */
735
-int ipoib_probe ( struct ib_device *ibdev ) {
735
+static int ipoib_probe ( struct ib_device *ibdev ) {
736
 	struct net_device *netdev;
736
 	struct net_device *netdev;
737
 	struct ipoib_device *ipoib;
737
 	struct ipoib_device *ipoib;
738
 	int rc;
738
 	int rc;
775
  *
775
  *
776
  * @v ibdev		Infiniband device
776
  * @v ibdev		Infiniband device
777
  */
777
  */
778
-void ipoib_remove ( struct ib_device *ibdev ) {
778
+static void ipoib_remove ( struct ib_device *ibdev ) {
779
 	struct net_device *netdev = ib_get_ownerdata ( ibdev );
779
 	struct net_device *netdev = ib_get_ownerdata ( ibdev );
780
 
780
 
781
 	unregister_netdev ( netdev );
781
 	unregister_netdev ( netdev );
782
 	netdev_nullify ( netdev );
782
 	netdev_nullify ( netdev );
783
 	netdev_put ( netdev );
783
 	netdev_put ( netdev );
784
 }
784
 }
785
+
786
+/** IPoIB driver */
787
+struct ib_driver ipoib_driver __ib_driver = {
788
+	.name = "IPoIB",
789
+	.probe = ipoib_probe,
790
+	.notify = ipoib_link_state_changed,
791
+	.remove = ipoib_remove,
792
+};

+ 41
- 1
src/include/ipxe/infiniband.h View File

12
 #include <stdint.h>
12
 #include <stdint.h>
13
 #include <ipxe/refcnt.h>
13
 #include <ipxe/refcnt.h>
14
 #include <ipxe/device.h>
14
 #include <ipxe/device.h>
15
+#include <ipxe/tables.h>
15
 #include <ipxe/ib_packet.h>
16
 #include <ipxe/ib_packet.h>
16
 #include <ipxe/ib_mad.h>
17
 #include <ipxe/ib_mad.h>
17
 
18
 
432
 	void *owner_priv;
433
 	void *owner_priv;
433
 };
434
 };
434
 
435
 
436
+/** An Infiniband upper-layer driver */
437
+struct ib_driver {
438
+	/** Name */
439
+	const char *name;
440
+	/** Probe device
441
+	 *
442
+	 * @v ibdev		Infiniband device
443
+	 * @ret rc		Return status code
444
+	 */
445
+	int ( * probe ) ( struct ib_device *ibdev );
446
+	/** Notify of device or link state change
447
+	 *
448
+	 * @v ibdev		Infiniband device
449
+	 */
450
+	void ( * notify ) ( struct ib_device *ibdev );
451
+	/** Remove device
452
+	 *
453
+	 * @v ibdev		Infiniband device
454
+	 */
455
+	void ( * remove ) ( struct ib_device *ibdev );
456
+};
457
+
458
+/** Infiniband driver table */
459
+#define IB_DRIVERS __table ( struct ib_driver, "ib_drivers" )
460
+
461
+/** Declare an Infiniband driver */
462
+#define __ib_driver __table_entry ( IB_DRIVERS, 01 )
463
+
435
 extern struct ib_completion_queue *
464
 extern struct ib_completion_queue *
436
 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
465
 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
437
 	       struct ib_completion_queue_operations *op );
466
 	       struct ib_completion_queue_operations *op );
492
 	list_for_each_entry ( (ibdev), &ib_devices, list )
521
 	list_for_each_entry ( (ibdev), &ib_devices, list )
493
 
522
 
494
 /**
523
 /**
495
- * Check link state
524
+ * Check link state of Infiniband device
496
  *
525
  *
497
  * @v ibdev		Infiniband device
526
  * @v ibdev		Infiniband device
498
  * @ret link_up		Link is up
527
  * @ret link_up		Link is up
502
 	return ( ibdev->port_state == IB_PORT_STATE_ACTIVE );
531
 	return ( ibdev->port_state == IB_PORT_STATE_ACTIVE );
503
 }
532
 }
504
 
533
 
534
+/**
535
+ * Check whether or not Infiniband device is open
536
+ *
537
+ * @v ibdev		Infiniband device
538
+ * @v is_open		Infiniband device is open
539
+ */
540
+static inline __attribute__ (( always_inline )) int
541
+ib_is_open ( struct ib_device *ibdev ) {
542
+	return ( ibdev->open_count > 0 );
543
+}
544
+
505
 /**
545
 /**
506
  * Get reference to Infiniband device
546
  * Get reference to Infiniband device
507
  *
547
  *

+ 0
- 3
src/include/ipxe/ipoib.h View File

53
 } __attribute__ (( packed ));
53
 } __attribute__ (( packed ));
54
 
54
 
55
 extern const char * ipoib_ntoa ( const void *ll_addr );
55
 extern const char * ipoib_ntoa ( const void *ll_addr );
56
-extern void ipoib_link_state_changed ( struct ib_device *ibdev );
57
-extern int ipoib_probe ( struct ib_device *ibdev );
58
-extern void ipoib_remove ( struct ib_device *ibdev );
59
 extern struct net_device * alloc_ipoibdev ( size_t priv_size );
56
 extern struct net_device * alloc_ipoibdev ( size_t priv_size );
60
 
57
 
61
 #endif /* _IPXE_IPOIB_H */
58
 #endif /* _IPXE_IPOIB_H */

+ 82
- 38
src/net/infiniband.c View File

31
 #include <ipxe/if_arp.h>
31
 #include <ipxe/if_arp.h>
32
 #include <ipxe/netdevice.h>
32
 #include <ipxe/netdevice.h>
33
 #include <ipxe/iobuf.h>
33
 #include <ipxe/iobuf.h>
34
-#include <ipxe/ipoib.h>
35
 #include <ipxe/process.h>
34
 #include <ipxe/process.h>
36
 #include <ipxe/infiniband.h>
35
 #include <ipxe/infiniband.h>
37
 #include <ipxe/ib_mi.h>
36
 #include <ipxe/ib_mi.h>
538
  ***************************************************************************
537
  ***************************************************************************
539
  */
538
  */
540
 
539
 
540
+/**
541
+ * Get link state
542
+ *
543
+ * @v ibdev		Infiniband device
544
+ * @ret rc		Link status code
545
+ */
546
+int ib_link_rc ( struct ib_device *ibdev ) {
547
+	switch ( ibdev->port_state ) {
548
+	case IB_PORT_STATE_DOWN:	return -ENOTCONN;
549
+	case IB_PORT_STATE_INIT:	return -EINPROGRESS_INIT;
550
+	case IB_PORT_STATE_ARMED:	return -EINPROGRESS_ARMED;
551
+	case IB_PORT_STATE_ACTIVE:	return 0;
552
+	default:			return -EINVAL;
553
+	}
554
+}
555
+
556
+/**
557
+ * Textual representation of Infiniband link state
558
+ *
559
+ * @v ibdev		Infiniband device
560
+ * @ret link_text	Link state text
561
+ */
562
+static const char * ib_link_state_text ( struct ib_device *ibdev ) {
563
+	switch ( ibdev->port_state ) {
564
+	case IB_PORT_STATE_DOWN:	return "DOWN";
565
+	case IB_PORT_STATE_INIT:	return "INIT";
566
+	case IB_PORT_STATE_ARMED:	return "ARMED";
567
+	case IB_PORT_STATE_ACTIVE:	return "ACTIVE";
568
+	default:			return "UNKNOWN";
569
+	}
570
+}
571
+
572
+/**
573
+ * Notify drivers of Infiniband device or link state change
574
+ *
575
+ * @v ibdev		Infiniband device
576
+ */
577
+static void ib_notify ( struct ib_device *ibdev ) {
578
+	struct ib_driver *driver;
579
+
580
+	for_each_table_entry ( driver, IB_DRIVERS )
581
+		driver->notify ( ibdev );
582
+}
583
+
584
+/**
585
+ * Notify of Infiniband link state change
586
+ *
587
+ * @v ibdev		Infiniband device
588
+ */
589
+void ib_link_state_changed ( struct ib_device *ibdev ) {
590
+
591
+	DBGC ( ibdev, "IBDEV %p link state is %s\n",
592
+	       ibdev, ib_link_state_text ( ibdev ) );
593
+
594
+	/* Notify drivers of link state change */
595
+	ib_notify ( ibdev );
596
+}
597
+
541
 /**
598
 /**
542
  * Open port
599
  * Open port
543
  *
600
  *
586
 	/* Add to head of open devices list */
643
 	/* Add to head of open devices list */
587
 	list_add ( &ibdev->open_list, &open_ib_devices );
644
 	list_add ( &ibdev->open_list, &open_ib_devices );
588
 
645
 
646
+	/* Notify drivers of device state change */
647
+	ib_notify ( ibdev );
648
+
589
 	assert ( ibdev->open_count == 1 );
649
 	assert ( ibdev->open_count == 1 );
590
 	return 0;
650
 	return 0;
591
 
651
 
614
 
674
 
615
 	/* Close device if this was the last remaining requested opening */
675
 	/* Close device if this was the last remaining requested opening */
616
 	if ( ibdev->open_count == 0 ) {
676
 	if ( ibdev->open_count == 0 ) {
677
+		ib_notify ( ibdev );
617
 		list_del ( &ibdev->open_list );
678
 		list_del ( &ibdev->open_list );
618
 		ib_destroy_mi ( ibdev, ibdev->gsi );
679
 		ib_destroy_mi ( ibdev, ibdev->gsi );
619
 		ib_destroy_sma ( ibdev, ibdev->smi );
680
 		ib_destroy_sma ( ibdev, ibdev->smi );
622
 	}
683
 	}
623
 }
684
 }
624
 
685
 
625
-/**
626
- * Get link state
627
- *
628
- * @v ibdev		Infiniband device
629
- * @ret rc		Link status code
630
- */
631
-int ib_link_rc ( struct ib_device *ibdev ) {
632
-	switch ( ibdev->port_state ) {
633
-	case IB_PORT_STATE_DOWN:	return -ENOTCONN;
634
-	case IB_PORT_STATE_INIT:	return -EINPROGRESS_INIT;
635
-	case IB_PORT_STATE_ARMED:	return -EINPROGRESS_ARMED;
636
-	case IB_PORT_STATE_ACTIVE:	return 0;
637
-	default:			return -EINVAL;
638
-	}
639
-}
640
-
641
 /***************************************************************************
686
 /***************************************************************************
642
  *
687
  *
643
  * Multicast
688
  * Multicast
799
  ***************************************************************************
844
  ***************************************************************************
800
  */
845
  */
801
 
846
 
802
-/**
803
- * Handle Infiniband link state change
804
- *
805
- * @v ibdev		Infiniband device
806
- */
807
-void ib_link_state_changed ( struct ib_device *ibdev ) {
808
-
809
-	/* Notify IPoIB of link state change */
810
-	ipoib_link_state_changed ( ibdev );
811
-}
812
-
813
 /**
847
 /**
814
  * Poll event queue
848
  * Poll event queue
815
  *
849
  *
883
  * @ret rc		Return status code
917
  * @ret rc		Return status code
884
  */
918
  */
885
 int register_ibdev ( struct ib_device *ibdev ) {
919
 int register_ibdev ( struct ib_device *ibdev ) {
920
+	struct ib_driver *driver;
886
 	int rc;
921
 	int rc;
887
 
922
 
888
 	/* Add to device list */
923
 	/* Add to device list */
889
 	ibdev_get ( ibdev );
924
 	ibdev_get ( ibdev );
890
 	list_add_tail ( &ibdev->list, &ib_devices );
925
 	list_add_tail ( &ibdev->list, &ib_devices );
926
+	DBGC ( ibdev, "IBDEV %p registered (phys %s)\n", ibdev,
927
+	       ibdev->dev->name );
891
 
928
 
892
-	/* Add IPoIB device */
893
-	if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
894
-		DBGC ( ibdev, "IBDEV %p could not add IPoIB device: %s\n",
895
-		       ibdev, strerror ( rc ) );
896
-		goto err_ipoib_probe;
929
+	/* Probe device */
930
+	for_each_table_entry ( driver, IB_DRIVERS ) {
931
+		if ( ( rc = driver->probe ( ibdev ) ) != 0 ) {
932
+			DBGC ( ibdev, "IBDEV %p could not add %s device: %s\n",
933
+			       ibdev, driver->name, strerror ( rc ) );
934
+			goto err_probe;
935
+		}
897
 	}
936
 	}
898
 
937
 
899
-	DBGC ( ibdev, "IBDEV %p registered (phys %s)\n", ibdev,
900
-	       ibdev->dev->name );
901
 	return 0;
938
 	return 0;
902
 
939
 
903
- err_ipoib_probe:
940
+ err_probe:
941
+	for_each_table_entry_continue_reverse ( driver, IB_DRIVERS )
942
+		driver->remove ( ibdev );
904
 	list_del ( &ibdev->list );
943
 	list_del ( &ibdev->list );
905
 	ibdev_put ( ibdev );
944
 	ibdev_put ( ibdev );
906
 	return rc;
945
 	return rc;
912
  * @v ibdev		Infiniband device
951
  * @v ibdev		Infiniband device
913
  */
952
  */
914
 void unregister_ibdev ( struct ib_device *ibdev ) {
953
 void unregister_ibdev ( struct ib_device *ibdev ) {
954
+	struct ib_driver *driver;
915
 
955
 
916
-	/* Close device */
917
-	ipoib_remove ( ibdev );
956
+	/* Remove device */
957
+	for_each_table_entry_reverse ( driver, IB_DRIVERS )
958
+		driver->remove ( ibdev );
918
 
959
 
919
 	/* Remove from device list */
960
 	/* Remove from device list */
920
 	list_del ( &ibdev->list );
961
 	list_del ( &ibdev->list );
953
 
994
 
954
 	return NULL;
995
 	return NULL;
955
 }
996
 }
997
+
998
+/* Drag in IPoIB */
999
+REQUIRE_OBJECT ( ipoib );

Loading…
Cancel
Save