aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-12-01 19:36:21 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-02 00:24:50 -0500
commit56f643c28c5df63693d7c66e56f8e4767cfd7a65 (patch)
tree9a7f4df58b6ab11a4105b335296a5642bea94bda
parent325dde48914e8ec1614d79ffacdbf9c0b8d24f42 (diff)
[PATCH] chelsio: statistics improvement
Cleanup statistics management: * Get rid of duplicate or unused statistics * Convert high volume stats to per-cpu and 64 bit Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/chelsio/cxgb2.c74
-rw-r--r--drivers/net/chelsio/sge.c65
-rw-r--r--drivers/net/chelsio/sge.h29
3 files changed, 100 insertions, 68 deletions
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 0ca5b07c1a6b..53bec6739812 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -390,13 +390,19 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
390 "RxOutOfRangeLengthField", 390 "RxOutOfRangeLengthField",
391 "RxFrameTooLongErrors", 391 "RxFrameTooLongErrors",
392 392
393 "TSO", 393 /* Port stats */
394 "VLANextractions", 394 "RxPackets",
395 "VLANinsertions",
396 "RxCsumGood", 395 "RxCsumGood",
396 "TxPackets",
397 "TxCsumOffload", 397 "TxCsumOffload",
398 "RxDrops" 398 "TxTso",
399 399 "RxVlan",
400 "TxVlan",
401
402 /* Interrupt stats */
403 "rx drops",
404 "pure_rsps",
405 "unhandled irqs",
400 "respQ_empty", 406 "respQ_empty",
401 "respQ_overflow", 407 "respQ_overflow",
402 "freelistQ_empty", 408 "freelistQ_empty",
@@ -404,10 +410,6 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
404 "pkt_mismatch", 410 "pkt_mismatch",
405 "cmdQ_full0", 411 "cmdQ_full0",
406 "cmdQ_full1", 412 "cmdQ_full1",
407 "tx_ipfrags",
408 "tx_reg_pkts",
409 "tx_lso_pkts",
410 "tx_do_cksum",
411 413
412 "espi_DIP2ParityErr", 414 "espi_DIP2ParityErr",
413 "espi_DIP4Err", 415 "espi_DIP4Err",
@@ -451,12 +453,10 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
451 struct adapter *adapter = dev->priv; 453 struct adapter *adapter = dev->priv;
452 struct cmac *mac = adapter->port[dev->if_port].mac; 454 struct cmac *mac = adapter->port[dev->if_port].mac;
453 const struct cmac_statistics *s; 455 const struct cmac_statistics *s;
454 const struct sge_port_stats *ss;
455 const struct sge_intr_counts *t; 456 const struct sge_intr_counts *t;
457 struct sge_port_stats ss;
456 458
457 s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL); 459 s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL);
458 ss = t1_sge_get_port_stats(adapter->sge, dev->if_port);
459 t = t1_sge_get_intr_counts(adapter->sge);
460 460
461 *data++ = s->TxOctetsOK; 461 *data++ = s->TxOctetsOK;
462 *data++ = s->TxOctetsBad; 462 *data++ = s->TxOctetsBad;
@@ -492,35 +492,37 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
492 *data++ = s->RxOutOfRangeLengthField; 492 *data++ = s->RxOutOfRangeLengthField;
493 *data++ = s->RxFrameTooLongErrors; 493 *data++ = s->RxFrameTooLongErrors;
494 494
495 *data++ = ss->tso; 495 t1_sge_get_port_stats(adapter->sge, dev->if_port, &ss);
496 *data++ = ss->vlan_xtract; 496 *data++ = ss.rx_packets;
497 *data++ = ss->vlan_insert; 497 *data++ = ss.rx_cso_good;
498 *data++ = ss->rx_cso_good; 498 *data++ = ss.tx_packets;
499 *data++ = ss->tx_cso; 499 *data++ = ss.tx_cso;
500 *data++ = ss->rx_drops; 500 *data++ = ss.tx_tso;
501 501 *data++ = ss.vlan_xtract;
502 *data++ = (u64)t->respQ_empty; 502 *data++ = ss.vlan_insert;
503 *data++ = (u64)t->respQ_overflow; 503
504 *data++ = (u64)t->freelistQ_empty; 504 t = t1_sge_get_intr_counts(adapter->sge);
505 *data++ = (u64)t->pkt_too_big; 505 *data++ = t->rx_drops;
506 *data++ = (u64)t->pkt_mismatch; 506 *data++ = t->pure_rsps;
507 *data++ = (u64)t->cmdQ_full[0]; 507 *data++ = t->unhandled_irqs;
508 *data++ = (u64)t->cmdQ_full[1]; 508 *data++ = t->respQ_empty;
509 *data++ = (u64)t->tx_ipfrags; 509 *data++ = t->respQ_overflow;
510 *data++ = (u64)t->tx_reg_pkts; 510 *data++ = t->freelistQ_empty;
511 *data++ = (u64)t->tx_lso_pkts; 511 *data++ = t->pkt_too_big;
512 *data++ = (u64)t->tx_do_cksum; 512 *data++ = t->pkt_mismatch;
513 *data++ = t->cmdQ_full[0];
514 *data++ = t->cmdQ_full[1];
513 515
514 if (adapter->espi) { 516 if (adapter->espi) {
515 const struct espi_intr_counts *e; 517 const struct espi_intr_counts *e;
516 518
517 e = t1_espi_get_intr_counts(adapter->espi); 519 e = t1_espi_get_intr_counts(adapter->espi);
518 *data++ = (u64) e->DIP2_parity_err; 520 *data++ = e->DIP2_parity_err;
519 *data++ = (u64) e->DIP4_err; 521 *data++ = e->DIP4_err;
520 *data++ = (u64) e->rx_drops; 522 *data++ = e->rx_drops;
521 *data++ = (u64) e->tx_drops; 523 *data++ = e->tx_drops;
522 *data++ = (u64) e->rx_ovflw; 524 *data++ = e->rx_ovflw;
523 *data++ = (u64) e->parity_err; 525 *data++ = e->parity_err;
524 } 526 }
525} 527}
526 528
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 26df2049d849..9911048d8213 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -274,7 +274,7 @@ struct sge {
274 struct sk_buff *espibug_skb[MAX_NPORTS]; 274 struct sk_buff *espibug_skb[MAX_NPORTS];
275 u32 sge_control; /* shadow value of sge control reg */ 275 u32 sge_control; /* shadow value of sge control reg */
276 struct sge_intr_counts stats; 276 struct sge_intr_counts stats;
277 struct sge_port_stats port_stats[MAX_NPORTS]; 277 struct sge_port_stats *port_stats[MAX_NPORTS];
278 struct sched *tx_sched; 278 struct sched *tx_sched;
279 struct cmdQ cmdQ[SGE_CMDQ_N] ____cacheline_aligned_in_smp; 279 struct cmdQ cmdQ[SGE_CMDQ_N] ____cacheline_aligned_in_smp;
280}; 280};
@@ -820,6 +820,11 @@ static inline unsigned int jumbo_payload_capacity(const struct sge *sge)
820 */ 820 */
821void t1_sge_destroy(struct sge *sge) 821void t1_sge_destroy(struct sge *sge)
822{ 822{
823 int i;
824
825 for_each_port(sge->adapter, i)
826 free_percpu(sge->port_stats[i]);
827
823 kfree(sge->tx_sched); 828 kfree(sge->tx_sched);
824 free_tx_resources(sge); 829 free_tx_resources(sge);
825 free_rx_resources(sge); 830 free_rx_resources(sge);
@@ -985,14 +990,28 @@ int t1_sge_intr_error_handler(struct sge *sge)
985 return 0; 990 return 0;
986} 991}
987 992
988const struct sge_intr_counts *t1_sge_get_intr_counts(struct sge *sge) 993const struct sge_intr_counts *t1_sge_get_intr_counts(const struct sge *sge)
989{ 994{
990 return &sge->stats; 995 return &sge->stats;
991} 996}
992 997
993const struct sge_port_stats *t1_sge_get_port_stats(struct sge *sge, int port) 998void t1_sge_get_port_stats(const struct sge *sge, int port,
999 struct sge_port_stats *ss)
994{ 1000{
995 return &sge->port_stats[port]; 1001 int cpu;
1002
1003 memset(ss, 0, sizeof(*ss));
1004 for_each_possible_cpu(cpu) {
1005 struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[port], cpu);
1006
1007 ss->rx_packets += st->rx_packets;
1008 ss->rx_cso_good += st->rx_cso_good;
1009 ss->tx_packets += st->tx_packets;
1010 ss->tx_cso += st->tx_cso;
1011 ss->tx_tso += st->tx_tso;
1012 ss->vlan_xtract += st->vlan_xtract;
1013 ss->vlan_insert += st->vlan_insert;
1014 }
996} 1015}
997 1016
998/** 1017/**
@@ -1361,36 +1380,39 @@ static int sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
1361 struct sk_buff *skb; 1380 struct sk_buff *skb;
1362 struct cpl_rx_pkt *p; 1381 struct cpl_rx_pkt *p;
1363 struct adapter *adapter = sge->adapter; 1382 struct adapter *adapter = sge->adapter;
1383 struct sge_port_stats *st;
1364 1384
1365 sge->stats.ethernet_pkts++;
1366 skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad, 1385 skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad,
1367 sge->rx_pkt_pad, 2, SGE_RX_COPY_THRES, 1386 sge->rx_pkt_pad, 2, SGE_RX_COPY_THRES,
1368 SGE_RX_DROP_THRES); 1387 SGE_RX_DROP_THRES);
1369 if (!skb) { 1388 if (unlikely(!skb)) {
1370 sge->port_stats[0].rx_drops++; /* charge only port 0 for now */ 1389 sge->stats.rx_drops++;
1371 return 0; 1390 return 0;
1372 } 1391 }
1373 1392
1374 p = (struct cpl_rx_pkt *)skb->data; 1393 p = (struct cpl_rx_pkt *)skb->data;
1375 skb_pull(skb, sizeof(*p)); 1394 skb_pull(skb, sizeof(*p));
1376 skb->dev = adapter->port[p->iff].dev;
1377 if (p->iff >= adapter->params.nports) { 1395 if (p->iff >= adapter->params.nports) {
1378 kfree_skb(skb); 1396 kfree_skb(skb);
1379 return 0; 1397 return 0;
1380 } 1398 }
1381 1399
1400 skb->dev = adapter->port[p->iff].dev;
1382 skb->dev->last_rx = jiffies; 1401 skb->dev->last_rx = jiffies;
1402 st = per_cpu_ptr(sge->port_stats[p->iff], smp_processor_id());
1403 st->rx_packets++;
1404
1383 skb->protocol = eth_type_trans(skb, skb->dev); 1405 skb->protocol = eth_type_trans(skb, skb->dev);
1384 if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff && 1406 if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff &&
1385 skb->protocol == htons(ETH_P_IP) && 1407 skb->protocol == htons(ETH_P_IP) &&
1386 (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) { 1408 (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) {
1387 sge->port_stats[p->iff].rx_cso_good++; 1409 ++st->rx_cso_good;
1388 skb->ip_summed = CHECKSUM_UNNECESSARY; 1410 skb->ip_summed = CHECKSUM_UNNECESSARY;
1389 } else 1411 } else
1390 skb->ip_summed = CHECKSUM_NONE; 1412 skb->ip_summed = CHECKSUM_NONE;
1391 1413
1392 if (unlikely(adapter->vlan_grp && p->vlan_valid)) { 1414 if (unlikely(adapter->vlan_grp && p->vlan_valid)) {
1393 sge->port_stats[p->iff].vlan_xtract++; 1415 st->vlan_xtract++;
1394 if (adapter->params.sge.polling) 1416 if (adapter->params.sge.polling)
1395 vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, 1417 vlan_hwaccel_receive_skb(skb, adapter->vlan_grp,
1396 ntohs(p->vlan)); 1418 ntohs(p->vlan));
@@ -1862,8 +1884,8 @@ static inline int eth_hdr_len(const void *data)
1862int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) 1884int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
1863{ 1885{
1864 struct adapter *adapter = dev->priv; 1886 struct adapter *adapter = dev->priv;
1865 struct sge_port_stats *st = &adapter->sge->port_stats[dev->if_port];
1866 struct sge *sge = adapter->sge; 1887 struct sge *sge = adapter->sge;
1888 struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[dev->if_port], smp_processor_id());
1867 struct cpl_tx_pkt *cpl; 1889 struct cpl_tx_pkt *cpl;
1868 1890
1869 if (skb->protocol == htons(ETH_P_CPL5)) 1891 if (skb->protocol == htons(ETH_P_CPL5))
@@ -1873,7 +1895,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
1873 int eth_type; 1895 int eth_type;
1874 struct cpl_tx_pkt_lso *hdr; 1896 struct cpl_tx_pkt_lso *hdr;
1875 1897
1876 st->tso++; 1898 ++st->tx_tso;
1877 1899
1878 eth_type = skb->nh.raw - skb->data == ETH_HLEN ? 1900 eth_type = skb->nh.raw - skb->data == ETH_HLEN ?
1879 CPL_ETH_II : CPL_ETH_II_VLAN; 1901 CPL_ETH_II : CPL_ETH_II_VLAN;
@@ -1887,7 +1909,6 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
1887 skb_shinfo(skb)->gso_size)); 1909 skb_shinfo(skb)->gso_size));
1888 hdr->len = htonl(skb->len - sizeof(*hdr)); 1910 hdr->len = htonl(skb->len - sizeof(*hdr));
1889 cpl = (struct cpl_tx_pkt *)hdr; 1911 cpl = (struct cpl_tx_pkt *)hdr;
1890 sge->stats.tx_lso_pkts++;
1891 } else { 1912 } else {
1892 /* 1913 /*
1893 * Packets shorter than ETH_HLEN can break the MAC, drop them 1914 * Packets shorter than ETH_HLEN can break the MAC, drop them
@@ -1955,8 +1976,6 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
1955 /* the length field isn't used so don't bother setting it */ 1976 /* the length field isn't used so don't bother setting it */
1956 1977
1957 st->tx_cso += (skb->ip_summed == CHECKSUM_PARTIAL); 1978 st->tx_cso += (skb->ip_summed == CHECKSUM_PARTIAL);
1958 sge->stats.tx_do_cksum += (skb->ip_summed == CHECKSUM_PARTIAL);
1959 sge->stats.tx_reg_pkts++;
1960 } 1979 }
1961 cpl->iff = dev->if_port; 1980 cpl->iff = dev->if_port;
1962 1981
@@ -1970,6 +1989,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
1970 cpl->vlan_valid = 0; 1989 cpl->vlan_valid = 0;
1971 1990
1972send: 1991send:
1992 st->tx_packets++;
1973 dev->trans_start = jiffies; 1993 dev->trans_start = jiffies;
1974 return t1_sge_tx(skb, adapter, 0, dev); 1994 return t1_sge_tx(skb, adapter, 0, dev);
1975} 1995}
@@ -2151,6 +2171,7 @@ struct sge * __devinit t1_sge_create(struct adapter *adapter,
2151 struct sge_params *p) 2171 struct sge_params *p)
2152{ 2172{
2153 struct sge *sge = kzalloc(sizeof(*sge), GFP_KERNEL); 2173 struct sge *sge = kzalloc(sizeof(*sge), GFP_KERNEL);
2174 int i;
2154 2175
2155 if (!sge) 2176 if (!sge)
2156 return NULL; 2177 return NULL;
@@ -2160,6 +2181,12 @@ struct sge * __devinit t1_sge_create(struct adapter *adapter,
2160 sge->rx_pkt_pad = t1_is_T1B(adapter) ? 0 : 2; 2181 sge->rx_pkt_pad = t1_is_T1B(adapter) ? 0 : 2;
2161 sge->jumbo_fl = t1_is_T1B(adapter) ? 1 : 0; 2182 sge->jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
2162 2183
2184 for_each_port(adapter, i) {
2185 sge->port_stats[i] = alloc_percpu(struct sge_port_stats);
2186 if (!sge->port_stats[i])
2187 goto nomem_port;
2188 }
2189
2163 init_timer(&sge->tx_reclaim_timer); 2190 init_timer(&sge->tx_reclaim_timer);
2164 sge->tx_reclaim_timer.data = (unsigned long)sge; 2191 sge->tx_reclaim_timer.data = (unsigned long)sge;
2165 sge->tx_reclaim_timer.function = sge_tx_reclaim_cb; 2192 sge->tx_reclaim_timer.function = sge_tx_reclaim_cb;
@@ -2199,4 +2226,12 @@ struct sge * __devinit t1_sge_create(struct adapter *adapter,
2199 p->polling = 0; 2226 p->polling = 0;
2200 2227
2201 return sge; 2228 return sge;
2229nomem_port:
2230 while (i >= 0) {
2231 free_percpu(sge->port_stats[i]);
2232 --i;
2233 }
2234 kfree(sge);
2235 return NULL;
2236
2202} 2237}
diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h
index 4691c4f58e7f..7ceb0117d039 100644
--- a/drivers/net/chelsio/sge.h
+++ b/drivers/net/chelsio/sge.h
@@ -44,6 +44,9 @@
44#include <asm/byteorder.h> 44#include <asm/byteorder.h>
45 45
46struct sge_intr_counts { 46struct sge_intr_counts {
47 unsigned int rx_drops; /* # of packets dropped due to no mem */
48 unsigned int pure_rsps; /* # of non-payload responses */
49 unsigned int unhandled_irqs; /* # of unhandled interrupts */
47 unsigned int respQ_empty; /* # times respQ empty */ 50 unsigned int respQ_empty; /* # times respQ empty */
48 unsigned int respQ_overflow; /* # respQ overflow (fatal) */ 51 unsigned int respQ_overflow; /* # respQ overflow (fatal) */
49 unsigned int freelistQ_empty; /* # times freelist empty */ 52 unsigned int freelistQ_empty; /* # times freelist empty */
@@ -51,24 +54,16 @@ struct sge_intr_counts {
51 unsigned int pkt_mismatch; 54 unsigned int pkt_mismatch;
52 unsigned int cmdQ_full[3]; /* not HW IRQ, host cmdQ[] full */ 55 unsigned int cmdQ_full[3]; /* not HW IRQ, host cmdQ[] full */
53 unsigned int cmdQ_restarted[3];/* # of times cmdQ X was restarted */ 56 unsigned int cmdQ_restarted[3];/* # of times cmdQ X was restarted */
54 unsigned int ethernet_pkts; /* # of Ethernet packets received */
55 unsigned int offload_pkts; /* # of offload packets received */
56 unsigned int offload_bundles; /* # of offload pkt bundles delivered */
57 unsigned int pure_rsps; /* # of non-payload responses */
58 unsigned int unhandled_irqs; /* # of unhandled interrupts */
59 unsigned int tx_ipfrags;
60 unsigned int tx_reg_pkts;
61 unsigned int tx_lso_pkts;
62 unsigned int tx_do_cksum;
63}; 57};
64 58
65struct sge_port_stats { 59struct sge_port_stats {
66 unsigned long rx_cso_good; /* # of successful RX csum offloads */ 60 u64 rx_packets; /* # of Ethernet packets received */
67 unsigned long tx_cso; /* # of TX checksum offloads */ 61 u64 rx_cso_good; /* # of successful RX csum offloads */
68 unsigned long vlan_xtract; /* # of VLAN tag extractions */ 62 u64 tx_packets; /* # of TX packets */
69 unsigned long vlan_insert; /* # of VLAN tag extractions */ 63 u64 tx_cso; /* # of TX checksum offloads */
70 unsigned long tso; /* # of TSO requests */ 64 u64 tx_tso; /* # of TSO requests */
71 unsigned long rx_drops; /* # of packets dropped due to no mem */ 65 u64 vlan_xtract; /* # of VLAN tag extractions */
66 u64 vlan_insert; /* # of VLAN tag insertions */
72}; 67};
73 68
74struct sk_buff; 69struct sk_buff;
@@ -90,8 +85,8 @@ int t1_sge_intr_error_handler(struct sge *);
90void t1_sge_intr_enable(struct sge *); 85void t1_sge_intr_enable(struct sge *);
91void t1_sge_intr_disable(struct sge *); 86void t1_sge_intr_disable(struct sge *);
92void t1_sge_intr_clear(struct sge *); 87void t1_sge_intr_clear(struct sge *);
93const struct sge_intr_counts *t1_sge_get_intr_counts(struct sge *sge); 88const struct sge_intr_counts *t1_sge_get_intr_counts(const struct sge *sge);
94const struct sge_port_stats *t1_sge_get_port_stats(struct sge *sge, int port); 89void t1_sge_get_port_stats(const struct sge *sge, int port, struct sge_port_stats *);
95void t1_sched_set_max_avail_bytes(struct sge *, unsigned int); 90void t1_sched_set_max_avail_bytes(struct sge *, unsigned int);
96void t1_sched_set_drain_bits_per_us(struct sge *, unsigned int, unsigned int); 91void t1_sched_set_drain_bits_per_us(struct sge *, unsigned int, unsigned int);
97unsigned int t1_sched_update_parms(struct sge *, unsigned int, unsigned int, 92unsigned int t1_sched_update_parms(struct sge *, unsigned int, unsigned int,