@@ -1609,6 +1609,154 @@ static void hfi1_get_dev_fw_str(struct ib_device *ibdev, char *str,
1609
1609
dc8051_ver_min (ver ));
1610
1610
}
1611
1611
1612
+ static const char * const driver_cntr_names [] = {
1613
+ /* must be element 0*/
1614
+ "DRIVER_KernIntr" ,
1615
+ "DRIVER_ErrorIntr" ,
1616
+ "DRIVER_Tx_Errs" ,
1617
+ "DRIVER_Rcv_Errs" ,
1618
+ "DRIVER_HW_Errs" ,
1619
+ "DRIVER_NoPIOBufs" ,
1620
+ "DRIVER_CtxtsOpen" ,
1621
+ "DRIVER_RcvLen_Errs" ,
1622
+ "DRIVER_EgrBufFull" ,
1623
+ "DRIVER_EgrHdrFull"
1624
+ };
1625
+
1626
+ static const char * * dev_cntr_names ;
1627
+ static const char * * port_cntr_names ;
1628
+ static int num_driver_cntrs = ARRAY_SIZE (driver_cntr_names );
1629
+ static int num_dev_cntrs ;
1630
+ static int num_port_cntrs ;
1631
+ static int cntr_names_initialized ;
1632
+
1633
+ /*
1634
+ * Convert a list of names separated by '\n' into an array of NULL terminated
1635
+ * strings. Optionally some entries can be reserved in the array to hold extra
1636
+ * external strings.
1637
+ */
1638
+ static int init_cntr_names (const char * names_in ,
1639
+ const int names_len ,
1640
+ int num_extra_names ,
1641
+ int * num_cntrs ,
1642
+ const char * * * cntr_names )
1643
+ {
1644
+ char * names_out , * p , * * q ;
1645
+ int i , n ;
1646
+
1647
+ n = 0 ;
1648
+ for (i = 0 ; i < names_len ; i ++ )
1649
+ if (names_in [i ] == '\n' )
1650
+ n ++ ;
1651
+
1652
+ names_out = kmalloc ((n + num_extra_names ) * sizeof (char * ) + names_len ,
1653
+ GFP_KERNEL );
1654
+ if (!names_out ) {
1655
+ * num_cntrs = 0 ;
1656
+ * cntr_names = NULL ;
1657
+ return - ENOMEM ;
1658
+ }
1659
+
1660
+ p = names_out + (n + num_extra_names ) * sizeof (char * );
1661
+ memcpy (p , names_in , names_len );
1662
+
1663
+ q = (char * * )names_out ;
1664
+ for (i = 0 ; i < n ; i ++ ) {
1665
+ q [i ] = p ;
1666
+ p = strchr (p , '\n' );
1667
+ * p ++ = '\0' ;
1668
+ }
1669
+
1670
+ * num_cntrs = n ;
1671
+ * cntr_names = (const char * * )names_out ;
1672
+ return 0 ;
1673
+ }
1674
+
1675
+ static struct rdma_hw_stats * alloc_hw_stats (struct ib_device * ibdev ,
1676
+ u8 port_num )
1677
+ {
1678
+ int i , err ;
1679
+
1680
+ if (!cntr_names_initialized ) {
1681
+ struct hfi1_devdata * dd = dd_from_ibdev (ibdev );
1682
+
1683
+ err = init_cntr_names (dd -> cntrnames ,
1684
+ dd -> cntrnameslen ,
1685
+ num_driver_cntrs ,
1686
+ & num_dev_cntrs ,
1687
+ & dev_cntr_names );
1688
+ if (err )
1689
+ return NULL ;
1690
+
1691
+ for (i = 0 ; i < num_driver_cntrs ; i ++ )
1692
+ dev_cntr_names [num_dev_cntrs + i ] =
1693
+ driver_cntr_names [i ];
1694
+
1695
+ err = init_cntr_names (dd -> portcntrnames ,
1696
+ dd -> portcntrnameslen ,
1697
+ 0 ,
1698
+ & num_port_cntrs ,
1699
+ & port_cntr_names );
1700
+ if (err ) {
1701
+ kfree (dev_cntr_names );
1702
+ dev_cntr_names = NULL ;
1703
+ return NULL ;
1704
+ }
1705
+ cntr_names_initialized = 1 ;
1706
+ }
1707
+
1708
+ if (!port_num )
1709
+ return rdma_alloc_hw_stats_struct (
1710
+ dev_cntr_names ,
1711
+ num_dev_cntrs + num_driver_cntrs ,
1712
+ RDMA_HW_STATS_DEFAULT_LIFESPAN );
1713
+ else
1714
+ return rdma_alloc_hw_stats_struct (
1715
+ port_cntr_names ,
1716
+ num_port_cntrs ,
1717
+ RDMA_HW_STATS_DEFAULT_LIFESPAN );
1718
+ }
1719
+
1720
+ static u64 hfi1_sps_ints (void )
1721
+ {
1722
+ unsigned long flags ;
1723
+ struct hfi1_devdata * dd ;
1724
+ u64 sps_ints = 0 ;
1725
+
1726
+ spin_lock_irqsave (& hfi1_devs_lock , flags );
1727
+ list_for_each_entry (dd , & hfi1_dev_list , list ) {
1728
+ sps_ints += get_all_cpu_total (dd -> int_counter );
1729
+ }
1730
+ spin_unlock_irqrestore (& hfi1_devs_lock , flags );
1731
+ return sps_ints ;
1732
+ }
1733
+
1734
+ static int get_hw_stats (struct ib_device * ibdev , struct rdma_hw_stats * stats ,
1735
+ u8 port , int index )
1736
+ {
1737
+ u64 * values ;
1738
+ int count ;
1739
+
1740
+ if (!port ) {
1741
+ u64 * stats = (u64 * )& hfi1_stats ;
1742
+ int i ;
1743
+
1744
+ hfi1_read_cntrs (dd_from_ibdev (ibdev ), NULL , & values );
1745
+ values [num_dev_cntrs ] = hfi1_sps_ints ();
1746
+ for (i = 1 ; i < num_driver_cntrs ; i ++ )
1747
+ values [num_dev_cntrs + i ] = stats [i ];
1748
+ count = num_dev_cntrs + num_driver_cntrs ;
1749
+ } else {
1750
+ struct hfi1_ibport * ibp = to_iport (ibdev , port );
1751
+
1752
+ hfi1_read_portcntrs (ppd_from_ibp (ibp ), NULL , & values );
1753
+ count = num_port_cntrs ;
1754
+ }
1755
+
1756
+ memcpy (stats -> value , values , count * sizeof (u64 ));
1757
+ return count ;
1758
+ }
1759
+
1612
1760
/**
1613
1761
* hfi1_register_ib_device - register our device with the infiniband core
1614
1762
* @dd: the device data structure
@@ -1656,6 +1804,8 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd)
1656
1804
ibdev -> phys_port_cnt = dd -> num_pports ;
1657
1805
ibdev -> dma_device = & dd -> pcidev -> dev ;
1658
1806
ibdev -> modify_device = modify_device ;
1807
+ ibdev -> alloc_hw_stats = alloc_hw_stats ;
1808
+ ibdev -> get_hw_stats = get_hw_stats ;
1659
1809
1660
1810
/* keep process mad in the driver */
1661
1811
ibdev -> process_mad = hfi1_process_mad ;
@@ -1770,6 +1920,10 @@ void hfi1_unregister_ib_device(struct hfi1_devdata *dd)
1770
1920
1771
1921
del_timer_sync (& dev -> mem_timer );
1772
1922
verbs_txreq_exit (dev );
1923
+
1924
+ kfree (dev_cntr_names );
1925
+ kfree (port_cntr_names );
1926
+ cntr_names_initialized = 0 ;
1773
1927
}
1774
1928
1775
1929
void hfi1_cnp_rcv (struct hfi1_packet * packet )
0 commit comments