@@ -99,6 +99,33 @@ BUILD_ASSERT_DECL(MAX_NB_MBUF % ROUND_DOWN_POW2(MAX_NB_MBUF/MIN_NB_MBUF) == 0);
9999BUILD_ASSERT_DECL ((MAX_NB_MBUF / ROUND_DOWN_POW2 (MAX_NB_MBUF /MIN_NB_MBUF ))
100100 % MP_CACHE_SZ == 0 );
101101
102+ /*
103+ * DPDK XSTATS Counter names definition
104+ */
105+ #define XSTAT_RX_64_PACKETS "rx_size_64_packets"
106+ #define XSTAT_RX_65_TO_127_PACKETS "rx_size_65_to_127_packets"
107+ #define XSTAT_RX_128_TO_255_PACKETS "rx_size_128_to_255_packets"
108+ #define XSTAT_RX_256_TO_511_PACKETS "rx_size_256_to_511_packets"
109+ #define XSTAT_RX_512_TO_1023_PACKETS "rx_size_512_to_1023_packets"
110+ #define XSTAT_RX_1024_TO_1522_PACKETS "rx_size_1024_to_1522_packets"
111+ #define XSTAT_RX_1523_TO_MAX_PACKETS "rx_size_1523_to_max_packets"
112+
113+ #define XSTAT_TX_64_PACKETS "tx_size_64_packets"
114+ #define XSTAT_TX_65_TO_127_PACKETS "tx_size_65_to_127_packets"
115+ #define XSTAT_TX_128_TO_255_PACKETS "tx_size_128_to_255_packets"
116+ #define XSTAT_TX_256_TO_511_PACKETS "tx_size_256_to_511_packets"
117+ #define XSTAT_TX_512_TO_1023_PACKETS "tx_size_512_to_1023_packets"
118+ #define XSTAT_TX_1024_TO_1522_PACKETS "tx_size_1024_to_1522_packets"
119+ #define XSTAT_TX_1523_TO_MAX_PACKETS "tx_size_1523_to_max_packets"
120+
121+ #define XSTAT_TX_MULTICAST_PACKETS "tx_multicast_packets"
122+ #define XSTAT_RX_BROADCAST_PACKETS "rx_broadcast_packets"
123+ #define XSTAT_TX_BROADCAST_PACKETS "tx_broadcast_packets"
124+ #define XSTAT_RX_UNDERSIZED_ERRORS "rx_undersized_errors"
125+ #define XSTAT_RX_OVERSIZE_ERRORS "rx_oversize_errors"
126+ #define XSTAT_RX_FRAGMENTED_ERRORS "rx_fragmented_errors"
127+ #define XSTAT_RX_JABBER_ERRORS "rx_jabber_errors"
128+
102129#define SOCKET0 0
103130
104131#define NIC_PORT_RX_Q_SIZE 2048 /* Size of Physical NIC RX Queue, Max (n+32<=4096)*/
@@ -1142,18 +1169,46 @@ is_vhost_running(struct virtio_net *virtio_dev)
11421169 return (virtio_dev != NULL && (virtio_dev -> flags & VIRTIO_DEV_RUNNING ));
11431170}
11441171
1172+ static inline void
1173+ netdev_dpdk_vhost_update_rx_size_counters (struct netdev_stats * stats ,
1174+ unsigned int packet_size )
1175+ {
1176+ /* Hard-coded search for the size bucket. */
1177+ if (packet_size < 256 ) {
1178+ if (packet_size >= 128 ) {
1179+ stats -> rx_128_to_255_packets ++ ;
1180+ } else if (packet_size <= 64 ) {
1181+ stats -> rx_1_to_64_packets ++ ;
1182+ } else {
1183+ stats -> rx_65_to_127_packets ++ ;
1184+ }
1185+ } else {
1186+ if (packet_size >= 1523 ) {
1187+ stats -> rx_1523_to_max_packets ++ ;
1188+ } else if (packet_size >= 1024 ) {
1189+ stats -> rx_1024_to_1522_packets ++ ;
1190+ } else if (packet_size < 512 ) {
1191+ stats -> rx_256_to_511_packets ++ ;
1192+ } else {
1193+ stats -> rx_512_to_1023_packets ++ ;
1194+ }
1195+ }
1196+ }
1197+
11451198static inline void
11461199netdev_dpdk_vhost_update_rx_counters (struct netdev_stats * stats ,
11471200 struct dp_packet * * packets , int count )
11481201{
11491202 int i ;
1203+ unsigned int packet_size ;
11501204 struct dp_packet * packet ;
11511205
11521206 stats -> rx_packets += count ;
11531207 for (i = 0 ; i < count ; i ++ ) {
11541208 packet = packets [i ];
1209+ packet_size = dp_packet_size (packet );
11551210
1156- if (OVS_UNLIKELY (dp_packet_size ( packet ) < ETH_HEADER_LEN )) {
1211+ if (OVS_UNLIKELY (packet_size < ETH_HEADER_LEN )) {
11571212 /* This only protects the following multicast counting from
11581213 * too short packets, but it does not stop the packet from
11591214 * further processing. */
@@ -1162,12 +1217,14 @@ netdev_dpdk_vhost_update_rx_counters(struct netdev_stats *stats,
11621217 continue ;
11631218 }
11641219
1220+ netdev_dpdk_vhost_update_rx_size_counters (stats , packet_size );
1221+
11651222 struct eth_header * eh = (struct eth_header * ) dp_packet_data (packet );
11661223 if (OVS_UNLIKELY (eth_addr_is_multicast (eh -> eth_dst ))) {
11671224 stats -> multicast ++ ;
11681225 }
11691226
1170- stats -> rx_bytes += dp_packet_size ( packet ) ;
1227+ stats -> rx_bytes += packet_size ;
11711228 }
11721229}
11731230
@@ -1659,21 +1716,6 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev,
16591716 struct netdev_dpdk * dev = netdev_dpdk_cast (netdev );
16601717
16611718 ovs_mutex_lock (& dev -> mutex );
1662- memset (stats , 0 , sizeof (* stats ));
1663- /* Unsupported Stats */
1664- stats -> collisions = UINT64_MAX ;
1665- stats -> rx_crc_errors = UINT64_MAX ;
1666- stats -> rx_fifo_errors = UINT64_MAX ;
1667- stats -> rx_frame_errors = UINT64_MAX ;
1668- stats -> rx_missed_errors = UINT64_MAX ;
1669- stats -> rx_over_errors = UINT64_MAX ;
1670- stats -> tx_aborted_errors = UINT64_MAX ;
1671- stats -> tx_carrier_errors = UINT64_MAX ;
1672- stats -> tx_errors = UINT64_MAX ;
1673- stats -> tx_fifo_errors = UINT64_MAX ;
1674- stats -> tx_heartbeat_errors = UINT64_MAX ;
1675- stats -> tx_window_errors = UINT64_MAX ;
1676- stats -> rx_dropped += UINT64_MAX ;
16771719
16781720 rte_spinlock_lock (& dev -> stats_lock );
16791721 /* Supported Stats */
@@ -1685,13 +1727,83 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev,
16851727 stats -> tx_bytes = dev -> stats .tx_bytes ;
16861728 stats -> rx_errors = dev -> stats .rx_errors ;
16871729 stats -> rx_length_errors = dev -> stats .rx_length_errors ;
1730+
1731+ stats -> rx_1_to_64_packets = dev -> stats .rx_1_to_64_packets ;
1732+ stats -> rx_65_to_127_packets = dev -> stats .rx_65_to_127_packets ;
1733+ stats -> rx_128_to_255_packets = dev -> stats .rx_128_to_255_packets ;
1734+ stats -> rx_256_to_511_packets = dev -> stats .rx_256_to_511_packets ;
1735+ stats -> rx_512_to_1023_packets = dev -> stats .rx_512_to_1023_packets ;
1736+ stats -> rx_1024_to_1522_packets = dev -> stats .rx_1024_to_1522_packets ;
1737+ stats -> rx_1523_to_max_packets = dev -> stats .rx_1523_to_max_packets ;
1738+
16881739 rte_spinlock_unlock (& dev -> stats_lock );
16891740
16901741 ovs_mutex_unlock (& dev -> mutex );
16911742
16921743 return 0 ;
16931744}
16941745
1746+ static void
1747+ netdev_dpdk_convert_xstats (struct netdev_stats * stats ,
1748+ const struct rte_eth_xstats * xstats ,
1749+ const unsigned int size )
1750+ {
1751+ /* XXX Current implementation is simple search through an array
1752+ * to find hardcoded counter names. In future DPDK release (TBD)
1753+ * XSTATS API will change so each counter will be represented by
1754+ * unique ID instead of String. */
1755+
1756+ for (unsigned int i = 0 ; i < size ; i ++ ) {
1757+ if (strcmp (XSTAT_RX_64_PACKETS , xstats [i ].name ) == 0 ) {
1758+ stats -> rx_1_to_64_packets = xstats [i ].value ;
1759+ } else if (strcmp (XSTAT_RX_65_TO_127_PACKETS , xstats [i ].name ) == 0 ) {
1760+ stats -> rx_65_to_127_packets = xstats [i ].value ;
1761+ } else if (strcmp (XSTAT_RX_128_TO_255_PACKETS , xstats [i ].name ) == 0 ) {
1762+ stats -> rx_128_to_255_packets = xstats [i ].value ;
1763+ } else if (strcmp (XSTAT_RX_256_TO_511_PACKETS , xstats [i ].name ) == 0 ) {
1764+ stats -> rx_256_to_511_packets = xstats [i ].value ;
1765+ } else if (strcmp (XSTAT_RX_512_TO_1023_PACKETS ,
1766+ xstats [i ].name ) == 0 ) {
1767+ stats -> rx_512_to_1023_packets = xstats [i ].value ;
1768+ } else if (strcmp (XSTAT_RX_1024_TO_1522_PACKETS ,
1769+ xstats [i ].name ) == 0 ) {
1770+ stats -> rx_1024_to_1522_packets = xstats [i ].value ;
1771+ } else if (strcmp (XSTAT_RX_1523_TO_MAX_PACKETS ,
1772+ xstats [i ].name ) == 0 ) {
1773+ stats -> rx_1523_to_max_packets = xstats [i ].value ;
1774+ } else if (strcmp (XSTAT_TX_64_PACKETS , xstats [i ].name ) == 0 ) {
1775+ stats -> tx_1_to_64_packets = xstats [i ].value ;
1776+ } else if (strcmp (XSTAT_TX_65_TO_127_PACKETS , xstats [i ].name ) == 0 ) {
1777+ stats -> tx_65_to_127_packets = xstats [i ].value ;
1778+ } else if (strcmp (XSTAT_TX_128_TO_255_PACKETS , xstats [i ].name ) == 0 ) {
1779+ stats -> tx_128_to_255_packets = xstats [i ].value ;
1780+ } else if (strcmp (XSTAT_TX_256_TO_511_PACKETS , xstats [i ].name ) == 0 ) {
1781+ stats -> tx_256_to_511_packets = xstats [i ].value ;
1782+ } else if (strcmp (XSTAT_TX_512_TO_1023_PACKETS ,
1783+ xstats [i ].name ) == 0 ) {
1784+ stats -> tx_512_to_1023_packets = xstats [i ].value ;
1785+ } else if (strcmp (XSTAT_TX_1024_TO_1522_PACKETS ,
1786+ xstats [i ].name ) == 0 ) {
1787+ stats -> tx_1024_to_1522_packets = xstats [i ].value ;
1788+ } else if (strcmp (XSTAT_TX_1523_TO_MAX_PACKETS ,
1789+ xstats [i ].name ) == 0 ) {
1790+ stats -> tx_1523_to_max_packets = xstats [i ].value ;
1791+ } else if (strcmp (XSTAT_TX_MULTICAST_PACKETS , xstats [i ].name ) == 0 ) {
1792+ stats -> tx_multicast_packets = xstats [i ].value ;
1793+ } else if (strcmp (XSTAT_RX_BROADCAST_PACKETS , xstats [i ].name ) == 0 ) {
1794+ stats -> rx_broadcast_packets = xstats [i ].value ;
1795+ } else if (strcmp (XSTAT_TX_BROADCAST_PACKETS , xstats [i ].name ) == 0 ) {
1796+ stats -> tx_broadcast_packets = xstats [i ].value ;
1797+ } else if (strcmp (XSTAT_RX_UNDERSIZED_ERRORS , xstats [i ].name ) == 0 ) {
1798+ stats -> rx_undersized_errors = xstats [i ].value ;
1799+ } else if (strcmp (XSTAT_RX_FRAGMENTED_ERRORS , xstats [i ].name ) == 0 ) {
1800+ stats -> rx_fragmented_errors = xstats [i ].value ;
1801+ } else if (strcmp (XSTAT_RX_JABBER_ERRORS , xstats [i ].name ) == 0 ) {
1802+ stats -> rx_jabber_errors = xstats [i ].value ;
1803+ }
1804+ }
1805+ }
1806+
16951807static int
16961808netdev_dpdk_get_stats (const struct netdev * netdev , struct netdev_stats * stats )
16971809{
@@ -1701,9 +1813,28 @@ netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
17011813
17021814 netdev_dpdk_get_carrier (netdev , & gg );
17031815 ovs_mutex_lock (& dev -> mutex );
1704- rte_eth_stats_get (dev -> port_id , & rte_stats );
17051816
1706- memset (stats , 0 , sizeof (* stats ));
1817+ struct rte_eth_xstats * rte_xstats ;
1818+ int rte_xstats_len , rte_xstats_ret ;
1819+
1820+ if (rte_eth_stats_get (dev -> port_id , & rte_stats )) {
1821+ VLOG_ERR ("Can't get ETH statistics for port: %i." , dev -> port_id );
1822+ return EPROTO ;
1823+ }
1824+
1825+ rte_xstats_len = rte_eth_xstats_get (dev -> port_id , NULL , 0 );
1826+ if (rte_xstats_len > 0 ) {
1827+ rte_xstats = dpdk_rte_mzalloc (sizeof (* rte_xstats ) * rte_xstats_len );
1828+ memset (rte_xstats , 0xff , sizeof (* rte_xstats ) * rte_xstats_len );
1829+ rte_xstats_ret = rte_eth_xstats_get (dev -> port_id , rte_xstats ,
1830+ rte_xstats_len );
1831+ if (rte_xstats_ret > 0 && rte_xstats_ret <= rte_xstats_len ) {
1832+ netdev_dpdk_convert_xstats (stats , rte_xstats , rte_xstats_ret );
1833+ }
1834+ rte_free (rte_xstats );
1835+ } else {
1836+ VLOG_WARN ("Can't get XSTATS counters for port: %i." , dev -> port_id );
1837+ }
17071838
17081839 stats -> rx_packets = rte_stats .ipackets ;
17091840 stats -> tx_packets = rte_stats .opackets ;
@@ -1721,21 +1852,8 @@ netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
17211852 /* These are the available DPDK counters for packets not received due to
17221853 * local resource constraints in DPDK and NIC respectively. */
17231854 stats -> rx_dropped = rte_stats .rx_nombuf + rte_stats .imissed ;
1724- stats -> collisions = UINT64_MAX ;
1725-
1726- stats -> rx_length_errors = UINT64_MAX ;
1727- stats -> rx_over_errors = UINT64_MAX ;
1728- stats -> rx_crc_errors = UINT64_MAX ;
1729- stats -> rx_frame_errors = UINT64_MAX ;
1730- stats -> rx_fifo_errors = UINT64_MAX ;
17311855 stats -> rx_missed_errors = rte_stats .imissed ;
17321856
1733- stats -> tx_aborted_errors = UINT64_MAX ;
1734- stats -> tx_carrier_errors = UINT64_MAX ;
1735- stats -> tx_fifo_errors = UINT64_MAX ;
1736- stats -> tx_heartbeat_errors = UINT64_MAX ;
1737- stats -> tx_window_errors = UINT64_MAX ;
1738-
17391857 ovs_mutex_unlock (& dev -> mutex );
17401858
17411859 return 0 ;
0 commit comments