diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-12-01 19:36:21 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-12-02 00:24:50 -0500 |
commit | 56f643c28c5df63693d7c66e56f8e4767cfd7a65 (patch) | |
tree | 9a7f4df58b6ab11a4105b335296a5642bea94bda /drivers/net/chelsio/sge.c | |
parent | 325dde48914e8ec1614d79ffacdbf9c0b8d24f42 (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>
Diffstat (limited to 'drivers/net/chelsio/sge.c')
-rw-r--r-- | drivers/net/chelsio/sge.c | 65 |
1 files changed, 50 insertions, 15 deletions
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 | */ |
821 | void t1_sge_destroy(struct sge *sge) | 821 | void 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 | ||
988 | const struct sge_intr_counts *t1_sge_get_intr_counts(struct sge *sge) | 993 | const 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 | ||
993 | const struct sge_port_stats *t1_sge_get_port_stats(struct sge *sge, int port) | 998 | void 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) | |||
1862 | int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) | 1884 | int 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 | ||
1972 | send: | 1991 | send: |
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; |
2229 | nomem_port: | ||
2230 | while (i >= 0) { | ||
2231 | free_percpu(sge->port_stats[i]); | ||
2232 | --i; | ||
2233 | } | ||
2234 | kfree(sge); | ||
2235 | return NULL; | ||
2236 | |||
2202 | } | 2237 | } |