Deleted Added
full compact
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 ---