sfxge_rx.c (254800) | sfxge_rx.c (272325) |
---|---|
1/*- 2 * Copyright (c) 2010-2011 Solarflare Communications, Inc. 3 * All rights reserved. 4 * 5 * This software was developed in part by Philip Paeps under contract for 6 * Solarflare Communications, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2010-2011 Solarflare Communications, Inc. 3 * All rights reserved. 4 * 5 * This software was developed in part by Philip Paeps under contract for 6 * Solarflare Communications, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/dev/sfxge/sfxge_rx.c 254800 2013-08-24 17:14:14Z andre $"); | 31__FBSDID("$FreeBSD: head/sys/dev/sfxge/sfxge_rx.c 272325 2014-09-30 20:18:10Z gnn $"); |
32 33#include <sys/types.h> 34#include <sys/mbuf.h> 35#include <sys/smp.h> 36#include <sys/socket.h> 37#include <sys/sysctl.h> 38#include <sys/limits.h> 39 --- 9 unchanged lines hidden (view full) --- 49#include <machine/in_cksum.h> 50 51#include "common/efx.h" 52 53 54#include "sfxge.h" 55#include "sfxge_rx.h" 56 | 32 33#include <sys/types.h> 34#include <sys/mbuf.h> 35#include <sys/smp.h> 36#include <sys/socket.h> 37#include <sys/sysctl.h> 38#include <sys/limits.h> 39 --- 9 unchanged lines hidden (view full) --- 49#include <machine/in_cksum.h> 50 51#include "common/efx.h" 52 53 54#include "sfxge.h" 55#include "sfxge_rx.h" 56 |
57#define RX_REFILL_THRESHOLD (EFX_RXQ_LIMIT(SFXGE_NDESCS) * 9 / 10) 58#define RX_REFILL_THRESHOLD_2 (RX_REFILL_THRESHOLD / 2) | 57#define RX_REFILL_THRESHOLD (EFX_RXQ_LIMIT(SFXGE_NDESCS) * 9 / 10) 58#define RX_REFILL_THRESHOLD_2 (RX_REFILL_THRESHOLD / 2) |
59 60/* Size of the LRO hash table. Must be a power of 2. A larger table 61 * means we can accelerate a larger number of streams. 62 */ 63static unsigned lro_table_size = 128; 64 65/* Maximum length of a hash chain. If chains get too long then the lookup 66 * time increases and may exceed the benefit of LRO. --- 15 unchanged lines hidden (view full) --- 82/* Number of packets with payload that must arrive in-order following loss 83 * before a connection is eligible for LRO. The idea is we should avoid 84 * coalescing segments when the sender is recovering from loss, because 85 * reducing the ACK rate can damage performance. 86 */ 87static int lro_loss_packets = 20; 88 89/* Flags for sfxge_lro_conn::l2_id; must not collide with EVL_VLID_MASK */ | 59 60/* Size of the LRO hash table. Must be a power of 2. A larger table 61 * means we can accelerate a larger number of streams. 62 */ 63static unsigned lro_table_size = 128; 64 65/* Maximum length of a hash chain. If chains get too long then the lookup 66 * time increases and may exceed the benefit of LRO. --- 15 unchanged lines hidden (view full) --- 82/* Number of packets with payload that must arrive in-order following loss 83 * before a connection is eligible for LRO. The idea is we should avoid 84 * coalescing segments when the sender is recovering from loss, because 85 * reducing the ACK rate can damage performance. 86 */ 87static int lro_loss_packets = 20; 88 89/* Flags for sfxge_lro_conn::l2_id; must not collide with EVL_VLID_MASK */ |
90#define SFXGE_LRO_L2_ID_VLAN 0x4000 91#define SFXGE_LRO_L2_ID_IPV6 0x8000 92#define SFXGE_LRO_CONN_IS_VLAN_ENCAP(c) ((c)->l2_id & SFXGE_LRO_L2_ID_VLAN) 93#define SFXGE_LRO_CONN_IS_TCPIPV4(c) (!((c)->l2_id & SFXGE_LRO_L2_ID_IPV6)) | 90#define SFXGE_LRO_L2_ID_VLAN 0x4000 91#define SFXGE_LRO_L2_ID_IPV6 0x8000 92#define SFXGE_LRO_CONN_IS_VLAN_ENCAP(c) ((c)->l2_id & SFXGE_LRO_L2_ID_VLAN) 93#define SFXGE_LRO_CONN_IS_TCPIPV4(c) (!((c)->l2_id & SFXGE_LRO_L2_ID_IPV6)) |
94 95/* Compare IPv6 addresses, avoiding conditional branches */ 96static __inline unsigned long ipv6_addr_cmp(const struct in6_addr *left, 97 const struct in6_addr *right) 98{ 99#if LONG_BIT == 64 100 const uint64_t *left64 = (const uint64_t *)left; 101 const uint64_t *right64 = (const uint64_t *)right; --- 72 unchanged lines hidden (view full) --- 174 struct mbuf *m; 175 176 /* Allocate mbuf structure */ 177 args.flags = M_PKTHDR; 178 args.type = MT_DATA; 179 m = (struct mbuf *)uma_zalloc_arg(zone_mbuf, &args, M_NOWAIT); 180 181 /* Allocate (and attach) packet buffer */ | 94 95/* Compare IPv6 addresses, avoiding conditional branches */ 96static __inline unsigned long ipv6_addr_cmp(const struct in6_addr *left, 97 const struct in6_addr *right) 98{ 99#if LONG_BIT == 64 100 const uint64_t *left64 = (const uint64_t *)left; 101 const uint64_t *right64 = (const uint64_t *)right; --- 72 unchanged lines hidden (view full) --- 174 struct mbuf *m; 175 176 /* Allocate mbuf structure */ 177 args.flags = M_PKTHDR; 178 args.type = MT_DATA; 179 m = (struct mbuf *)uma_zalloc_arg(zone_mbuf, &args, M_NOWAIT); 180 181 /* Allocate (and attach) packet buffer */ |
182 if (m && !uma_zalloc_arg(sc->rx_buffer_zone, m, M_NOWAIT)) { | 182 if (m != NULL && !uma_zalloc_arg(sc->rx_buffer_zone, m, M_NOWAIT)) { |
183 uma_zfree(zone_mbuf, m); 184 m = NULL; 185 } 186 | 183 uma_zfree(zone_mbuf, m); 184 m = NULL; 185 } 186 |
187 return m; | 187 return (m); |
188} 189 190#define SFXGE_REFILL_BATCH 64 191 192static void 193sfxge_rx_qfill(struct sfxge_rxq *rxq, unsigned int target, boolean_t retrying) 194{ 195 struct sfxge_softc *sc; --- 169 unchanged lines hidden (view full) --- 365 366/* Drop the given connection, and add it to the free list. */ 367static void sfxge_lro_drop(struct sfxge_rxq *rxq, struct sfxge_lro_conn *c) 368{ 369 unsigned bucket; 370 371 KASSERT(!c->mbuf, ("found orphaned mbuf")); 372 | 188} 189 190#define SFXGE_REFILL_BATCH 64 191 192static void 193sfxge_rx_qfill(struct sfxge_rxq *rxq, unsigned int target, boolean_t retrying) 194{ 195 struct sfxge_softc *sc; --- 169 unchanged lines hidden (view full) --- 365 366/* Drop the given connection, and add it to the free list. */ 367static void sfxge_lro_drop(struct sfxge_rxq *rxq, struct sfxge_lro_conn *c) 368{ 369 unsigned bucket; 370 371 KASSERT(!c->mbuf, ("found orphaned mbuf")); 372 |
373 if (c->next_buf.mbuf) { | 373 if (c->next_buf.mbuf != NULL) { |
374 sfxge_rx_deliver(rxq->sc, &c->next_buf); 375 LIST_REMOVE(c, active_link); 376 } 377 378 bucket = c->conn_hash & rxq->lro.conns_mask; 379 KASSERT(rxq->lro.conns_n[bucket] > 0, ("LRO: bucket fill level wrong")); 380 --rxq->lro.conns_n[bucket]; 381 TAILQ_REMOVE(&rxq->lro.conns[bucket], c, link); --- 123 unchanged lines hidden (view full) --- 505 /* timestamp option -- okay */ 506 } else { 507 dont_merge = 1; 508 } 509 } 510 511 if (__predict_false(th_seq != c->next_seq)) { 512 /* Out-of-order, so start counting again. */ | 374 sfxge_rx_deliver(rxq->sc, &c->next_buf); 375 LIST_REMOVE(c, active_link); 376 } 377 378 bucket = c->conn_hash & rxq->lro.conns_mask; 379 KASSERT(rxq->lro.conns_n[bucket] > 0, ("LRO: bucket fill level wrong")); 380 --rxq->lro.conns_n[bucket]; 381 TAILQ_REMOVE(&rxq->lro.conns[bucket], c, link); --- 123 unchanged lines hidden (view full) --- 505 /* timestamp option -- okay */ 506 } else { 507 dont_merge = 1; 508 } 509 } 510 511 if (__predict_false(th_seq != c->next_seq)) { 512 /* Out-of-order, so start counting again. */ |
513 if (c->mbuf) | 513 if (c->mbuf != NULL) |
514 sfxge_lro_deliver(&rxq->lro, c); 515 c->n_in_order_pkts -= lro_loss_packets; 516 c->next_seq = th_seq + data_length; 517 ++rxq->lro.n_misorder; 518 goto deliver_buf_out; 519 } 520 c->next_seq = th_seq + data_length; 521 522 now = ticks; 523 if (now - c->last_pkt_ticks > lro_idle_ticks) { 524 ++rxq->lro.n_drop_idle; | 514 sfxge_lro_deliver(&rxq->lro, c); 515 c->n_in_order_pkts -= lro_loss_packets; 516 c->next_seq = th_seq + data_length; 517 ++rxq->lro.n_misorder; 518 goto deliver_buf_out; 519 } 520 c->next_seq = th_seq + data_length; 521 522 now = ticks; 523 if (now - c->last_pkt_ticks > lro_idle_ticks) { 524 ++rxq->lro.n_drop_idle; |
525 if (c->mbuf) | 525 if (c->mbuf != NULL) |
526 sfxge_lro_deliver(&rxq->lro, c); 527 sfxge_lro_drop(rxq, c); | 526 sfxge_lro_deliver(&rxq->lro, c); 527 sfxge_lro_drop(rxq, c); |
528 return 0; | 528 return (0); |
529 } 530 c->last_pkt_ticks = ticks; 531 532 if (c->n_in_order_pkts < lro_slow_start_packets) { 533 /* May be in slow-start, so don't merge. */ 534 ++rxq->lro.n_slow_start; 535 ++c->n_in_order_pkts; 536 goto deliver_buf_out; 537 } 538 539 if (__predict_false(dont_merge)) { | 529 } 530 c->last_pkt_ticks = ticks; 531 532 if (c->n_in_order_pkts < lro_slow_start_packets) { 533 /* May be in slow-start, so don't merge. */ 534 ++rxq->lro.n_slow_start; 535 ++c->n_in_order_pkts; 536 goto deliver_buf_out; 537 } 538 539 if (__predict_false(dont_merge)) { |
540 if (c->mbuf) | 540 if (c->mbuf != NULL) |
541 sfxge_lro_deliver(&rxq->lro, c); 542 if (th->th_flags & (TH_FIN | TH_RST)) { 543 ++rxq->lro.n_drop_closed; 544 sfxge_lro_drop(rxq, c); | 541 sfxge_lro_deliver(&rxq->lro, c); 542 if (th->th_flags & (TH_FIN | TH_RST)) { 543 ++rxq->lro.n_drop_closed; 544 sfxge_lro_drop(rxq, c); |
545 return 0; | 545 return (0); |
546 } 547 goto deliver_buf_out; 548 } 549 550 rx_buf->mbuf->m_data += rxq->sc->rx_prefix_size; 551 552 if (__predict_true(c->mbuf != NULL)) { 553 /* Remove headers and any padding */ --- 4 unchanged lines hidden (view full) --- 558 } else { 559 /* Remove any padding */ 560 rx_buf->mbuf->m_len = pkt_length; 561 562 sfxge_lro_start(&rxq->lro, c, rx_buf->mbuf, c->next_nh, th); 563 } 564 565 rx_buf->mbuf = NULL; | 546 } 547 goto deliver_buf_out; 548 } 549 550 rx_buf->mbuf->m_data += rxq->sc->rx_prefix_size; 551 552 if (__predict_true(c->mbuf != NULL)) { 553 /* Remove headers and any padding */ --- 4 unchanged lines hidden (view full) --- 558 } else { 559 /* Remove any padding */ 560 rx_buf->mbuf->m_len = pkt_length; 561 562 sfxge_lro_start(&rxq->lro, c, rx_buf->mbuf, c->next_nh, th); 563 } 564 565 rx_buf->mbuf = NULL; |
566 return 1; | 566 return (1); |
567 568 deliver_buf_out: 569 sfxge_rx_deliver(rxq->sc, rx_buf); | 567 568 deliver_buf_out: 569 sfxge_rx_deliver(rxq->sc, rx_buf); |
570 return 1; | 570 return (1); |
571} 572 573static void sfxge_lro_new_conn(struct sfxge_lro_state *st, uint32_t conn_hash, 574 uint16_t l2_id, void *nh, struct tcphdr *th) 575{ 576 unsigned bucket = conn_hash & st->conns_mask; 577 struct sfxge_lro_conn *c; 578 --- 37 unchanged lines hidden (view full) --- 616sfxge_lro(struct sfxge_rxq *rxq, struct sfxge_rx_sw_desc *rx_buf) 617{ 618 struct sfxge_softc *sc = rxq->sc; 619 struct mbuf *m = rx_buf->mbuf; 620 struct ether_header *eh; 621 struct sfxge_lro_conn *c; 622 uint16_t l2_id; 623 uint16_t l3_proto; | 571} 572 573static void sfxge_lro_new_conn(struct sfxge_lro_state *st, uint32_t conn_hash, 574 uint16_t l2_id, void *nh, struct tcphdr *th) 575{ 576 unsigned bucket = conn_hash & st->conns_mask; 577 struct sfxge_lro_conn *c; 578 --- 37 unchanged lines hidden (view full) --- 616sfxge_lro(struct sfxge_rxq *rxq, struct sfxge_rx_sw_desc *rx_buf) 617{ 618 struct sfxge_softc *sc = rxq->sc; 619 struct mbuf *m = rx_buf->mbuf; 620 struct ether_header *eh; 621 struct sfxge_lro_conn *c; 622 uint16_t l2_id; 623 uint16_t l3_proto; |
624 void *nh; | 624 void *nh; |
625 struct tcphdr *th; 626 uint32_t conn_hash; 627 unsigned bucket; 628 629 /* Get the hardware hash */ 630 conn_hash = EFX_RX_HASH_VALUE(EFX_RX_HASHALG_TOEPLITZ, 631 mtod(m, uint8_t *)); 632 --- 33 unchanged lines hidden (view full) --- 666 667 bucket = conn_hash & rxq->lro.conns_mask; 668 669 TAILQ_FOREACH(c, &rxq->lro.conns[bucket], link) { 670 if ((c->l2_id - l2_id) | (c->conn_hash - conn_hash)) 671 continue; 672 if ((c->source - th->th_sport) | (c->dest - th->th_dport)) 673 continue; | 625 struct tcphdr *th; 626 uint32_t conn_hash; 627 unsigned bucket; 628 629 /* Get the hardware hash */ 630 conn_hash = EFX_RX_HASH_VALUE(EFX_RX_HASHALG_TOEPLITZ, 631 mtod(m, uint8_t *)); 632 --- 33 unchanged lines hidden (view full) --- 666 667 bucket = conn_hash & rxq->lro.conns_mask; 668 669 TAILQ_FOREACH(c, &rxq->lro.conns[bucket], link) { 670 if ((c->l2_id - l2_id) | (c->conn_hash - conn_hash)) 671 continue; 672 if ((c->source - th->th_sport) | (c->dest - th->th_dport)) 673 continue; |
674 if (c->mbuf) { | 674 if (c->mbuf != NULL) { |
675 if (SFXGE_LRO_CONN_IS_TCPIPV4(c)) { 676 struct ip *c_iph, *iph = nh; 677 c_iph = c->nh; 678 if ((c_iph->ip_src.s_addr - iph->ip_src.s_addr) | 679 (c_iph->ip_dst.s_addr - iph->ip_dst.s_addr)) 680 continue; 681 } else { 682 struct ip6_hdr *c_iph, *iph = nh; 683 c_iph = c->nh; 684 if (ipv6_addr_cmp(&c_iph->ip6_src, &iph->ip6_src) | 685 ipv6_addr_cmp(&c_iph->ip6_dst, &iph->ip6_dst)) 686 continue; 687 } 688 } 689 690 /* Re-insert at head of list to reduce lookup time. */ 691 TAILQ_REMOVE(&rxq->lro.conns[bucket], c, link); 692 TAILQ_INSERT_HEAD(&rxq->lro.conns[bucket], c, link); 693 | 675 if (SFXGE_LRO_CONN_IS_TCPIPV4(c)) { 676 struct ip *c_iph, *iph = nh; 677 c_iph = c->nh; 678 if ((c_iph->ip_src.s_addr - iph->ip_src.s_addr) | 679 (c_iph->ip_dst.s_addr - iph->ip_dst.s_addr)) 680 continue; 681 } else { 682 struct ip6_hdr *c_iph, *iph = nh; 683 c_iph = c->nh; 684 if (ipv6_addr_cmp(&c_iph->ip6_src, &iph->ip6_src) | 685 ipv6_addr_cmp(&c_iph->ip6_dst, &iph->ip6_dst)) 686 continue; 687 } 688 } 689 690 /* Re-insert at head of list to reduce lookup time. */ 691 TAILQ_REMOVE(&rxq->lro.conns[bucket], c, link); 692 TAILQ_INSERT_HEAD(&rxq->lro.conns[bucket], c, link); 693 |
694 if (c->next_buf.mbuf) { | 694 if (c->next_buf.mbuf != NULL) { |
695 if (!sfxge_lro_try_merge(rxq, c)) 696 goto deliver_now; 697 } else { 698 LIST_INSERT_HEAD(&rxq->lro.active_conns, c, 699 active_link); 700 } 701 c->next_buf = *rx_buf; 702 c->next_eh = eh; --- 12 unchanged lines hidden (view full) --- 715static void sfxge_lro_end_of_burst(struct sfxge_rxq *rxq) 716{ 717 struct sfxge_lro_state *st = &rxq->lro; 718 struct sfxge_lro_conn *c; 719 unsigned t; 720 721 while (!LIST_EMPTY(&st->active_conns)) { 722 c = LIST_FIRST(&st->active_conns); | 695 if (!sfxge_lro_try_merge(rxq, c)) 696 goto deliver_now; 697 } else { 698 LIST_INSERT_HEAD(&rxq->lro.active_conns, c, 699 active_link); 700 } 701 c->next_buf = *rx_buf; 702 c->next_eh = eh; --- 12 unchanged lines hidden (view full) --- 715static void sfxge_lro_end_of_burst(struct sfxge_rxq *rxq) 716{ 717 struct sfxge_lro_state *st = &rxq->lro; 718 struct sfxge_lro_conn *c; 719 unsigned t; 720 721 while (!LIST_EMPTY(&st->active_conns)) { 722 c = LIST_FIRST(&st->active_conns); |
723 if (!c->delivered && c->mbuf) | 723 if (!c->delivered && c->mbuf != NULL) |
724 sfxge_lro_deliver(st, c); 725 if (sfxge_lro_try_merge(rxq, c)) { | 724 sfxge_lro_deliver(st, c); 725 if (sfxge_lro_try_merge(rxq, c)) { |
726 if (c->mbuf) | 726 if (c->mbuf != NULL) |
727 sfxge_lro_deliver(st, c); 728 LIST_REMOVE(c, active_link); 729 } 730 c->delivered = 0; 731 } 732 733 t = *(volatile int *)&ticks; 734 if (__predict_false(t != st->last_purge_ticks)) --- 96 unchanged lines hidden (view full) --- 831 struct sfxge_rxq *rxq; 832 struct sfxge_evq *evq; 833 unsigned int count; 834 835 rxq = sc->rxq[index]; 836 evq = sc->evq[index]; 837 838 mtx_lock(&evq->lock); | 727 sfxge_lro_deliver(st, c); 728 LIST_REMOVE(c, active_link); 729 } 730 c->delivered = 0; 731 } 732 733 t = *(volatile int *)&ticks; 734 if (__predict_false(t != st->last_purge_ticks)) --- 96 unchanged lines hidden (view full) --- 831 struct sfxge_rxq *rxq; 832 struct sfxge_evq *evq; 833 unsigned int count; 834 835 rxq = sc->rxq[index]; 836 evq = sc->evq[index]; 837 838 mtx_lock(&evq->lock); |
839 | 839 |
840 KASSERT(rxq->init_state == SFXGE_RXQ_STARTED, 841 ("rxq not started")); 842 843 rxq->init_state = SFXGE_RXQ_INITIALIZED; 844 845 callout_stop(&rxq->refill_callout); 846 847again: --- 28 unchanged lines hidden (view full) --- 876 ("rxq->completed != rxq->pending")); 877 878 rxq->added = 0; 879 rxq->pending = 0; 880 rxq->completed = 0; 881 rxq->loopback = 0; 882 883 /* Destroy the common code receive queue. */ | 840 KASSERT(rxq->init_state == SFXGE_RXQ_STARTED, 841 ("rxq not started")); 842 843 rxq->init_state = SFXGE_RXQ_INITIALIZED; 844 845 callout_stop(&rxq->refill_callout); 846 847again: --- 28 unchanged lines hidden (view full) --- 876 ("rxq->completed != rxq->pending")); 877 878 rxq->added = 0; 879 rxq->pending = 0; 880 rxq->completed = 0; 881 rxq->loopback = 0; 882 883 /* Destroy the common code receive queue. */ |
884 efx_rx_qdestroy(rxq->common); | 884 efx_rx_qdestroy(rxq->common); |
885 886 efx_sram_buf_tbl_clear(sc->enp, rxq->buf_base_id, 887 EFX_RXQ_NBUFS(SFXGE_NDESCS)); 888 889 mtx_unlock(&evq->lock); 890} 891 892static int --- 238 unchanged lines hidden (view full) --- 1131 1132 return (0); 1133} 1134 1135static const struct { 1136 const char *name; 1137 size_t offset; 1138} sfxge_rx_stats[] = { | 885 886 efx_sram_buf_tbl_clear(sc->enp, rxq->buf_base_id, 887 EFX_RXQ_NBUFS(SFXGE_NDESCS)); 888 889 mtx_unlock(&evq->lock); 890} 891 892static int --- 238 unchanged lines hidden (view full) --- 1131 1132 return (0); 1133} 1134 1135static const struct { 1136 const char *name; 1137 size_t offset; 1138} sfxge_rx_stats[] = { |
1139#define SFXGE_RX_STAT(name, member) \ | 1139#define SFXGE_RX_STAT(name, member) \ |
1140 { #name, offsetof(struct sfxge_rxq, member) } 1141 SFXGE_RX_STAT(lro_merges, lro.n_merges), 1142 SFXGE_RX_STAT(lro_bursts, lro.n_bursts), 1143 SFXGE_RX_STAT(lro_slow_start, lro.n_slow_start), 1144 SFXGE_RX_STAT(lro_misorder, lro.n_misorder), 1145 SFXGE_RX_STAT(lro_too_many, lro.n_too_many), 1146 SFXGE_RX_STAT(lro_new_stream, lro.n_new_stream), 1147 SFXGE_RX_STAT(lro_drop_idle, lro.n_drop_idle), --- 8 unchanged lines hidden (view full) --- 1156 unsigned int sum, index; 1157 1158 /* Sum across all RX queues */ 1159 sum = 0; 1160 for (index = 0; index < sc->intr.n_alloc; index++) 1161 sum += *(unsigned int *)((caddr_t)sc->rxq[index] + 1162 sfxge_rx_stats[id].offset); 1163 | 1140 { #name, offsetof(struct sfxge_rxq, member) } 1141 SFXGE_RX_STAT(lro_merges, lro.n_merges), 1142 SFXGE_RX_STAT(lro_bursts, lro.n_bursts), 1143 SFXGE_RX_STAT(lro_slow_start, lro.n_slow_start), 1144 SFXGE_RX_STAT(lro_misorder, lro.n_misorder), 1145 SFXGE_RX_STAT(lro_too_many, lro.n_too_many), 1146 SFXGE_RX_STAT(lro_new_stream, lro.n_new_stream), 1147 SFXGE_RX_STAT(lro_drop_idle, lro.n_drop_idle), --- 8 unchanged lines hidden (view full) --- 1156 unsigned int sum, index; 1157 1158 /* Sum across all RX queues */ 1159 sum = 0; 1160 for (index = 0; index < sc->intr.n_alloc; index++) 1161 sum += *(unsigned int *)((caddr_t)sc->rxq[index] + 1162 sfxge_rx_stats[id].offset); 1163 |
1164 return SYSCTL_OUT(req, &sum, sizeof(sum)); | 1164 return (SYSCTL_OUT(req, &sum, sizeof(sum))); |
1165} 1166 1167static void 1168sfxge_rx_stat_init(struct sfxge_softc *sc) 1169{ 1170 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); 1171 struct sysctl_oid_list *stat_list; 1172 unsigned int id; --- 60 unchanged lines hidden --- | 1165} 1166 1167static void 1168sfxge_rx_stat_init(struct sfxge_softc *sc) 1169{ 1170 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev); 1171 struct sysctl_oid_list *stat_list; 1172 unsigned int id; --- 60 unchanged lines hidden --- |