Date: Fri, 15 Jul 2011 22:26:09 GMT From: Takuya ASADA <syuu@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 196219 for review Message-ID: <201107152226.p6FMQ8Lc046364@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@196219?ac=10 Change 196219 by syuu@kikurage on 2011/07/15 22:25:26 test_mqbpf fix, BPFIF_LOCK reverted to mtx to stabilize, remove LOG_DEBUG and SDT for debugging, HASHTYPE support for igb Affected files ... .. //depot/projects/soc2011/mq_bpf/src/sys/dev/e1000/if_igb.c#9 edit .. //depot/projects/soc2011/mq_bpf/src/sys/net/bpf.c#13 edit .. //depot/projects/soc2011/mq_bpf/src/sys/net/bpfdesc.h#5 edit .. //depot/projects/soc2011/mq_bpf/src/sys/net/if.c#6 edit .. //depot/projects/soc2011/mq_bpf/src/sys/net/if_ethersubr.c#6 edit .. //depot/projects/soc2011/mq_bpf/src/sys/netinet/in_rss.c#3 edit .. //depot/projects/soc2011/mq_bpf/tests/Makefile#3 edit .. //depot/projects/soc2011/mq_bpf/tests/packet_trace.d#2 delete .. //depot/projects/soc2011/mq_bpf/tests/test_mqbpf.c#2 edit .. //depot/projects/soc2011/mq_bpf/tests/test_sqbpf.c#3 edit Differences ... ==== //depot/projects/soc2011/mq_bpf/src/sys/dev/e1000/if_igb.c#9 (text+ko) ==== @@ -37,6 +37,7 @@ #include "opt_device_polling.h" #include "opt_inet.h" #include "opt_altq.h" +#include "opt_rss.h" #endif #include <sys/param.h> @@ -59,7 +60,6 @@ #include <sys/eventhandler.h> #include <sys/pcpu.h> #include <sys/smp.h> -#include <sys/syslog.h> #include <machine/smp.h> #include <machine/bus.h> #include <machine/resource.h> @@ -82,6 +82,7 @@ #include <netinet/tcp.h> #include <netinet/tcp_lro.h> #include <netinet/udp.h> +#include <netinet/in_rss.h> #include <machine/in_cksum.h> #include <dev/led/led.h> @@ -2268,6 +2269,7 @@ #if __FreeBSD_version >= 800504 bus_describe_intr(dev, que->res, que->tag, "que %d", i); #endif + printf("%s: que->msix:%d i:%d\n", __func__, que->msix, i); que->msix = vector; if (adapter->hw.mac.type == e1000_82575) que->eims = E1000_EICR_TX_QUEUE0 << i; @@ -4105,13 +4107,17 @@ */ rxcsum = E1000_READ_REG(hw, E1000_RXCSUM); if (adapter->num_queues >1) { - u32 random[10], mrqc, shift = 0; + u32 rsskey[10], mrqc, shift = 0; union igb_reta { u32 dword; u8 bytes[4]; } reta; - arc4rand(&random, sizeof(random), 0); +#ifdef RSS + rss_getkey((uint8_t *)rsskey); +#else + arc4rand(&rsskey, sizeof(rsskey), 0); +#endif if (adapter->hw.mac.type == e1000_82575) shift = 6; /* Warning FM follows */ @@ -4126,7 +4132,7 @@ mrqc = E1000_MRQC_ENABLE_RSS_4Q; for (int i = 0; i < 10; i++) E1000_WRITE_REG_ARRAY(hw, - E1000_RSSRK(0), i, random[i]); + E1000_RSSRK(0), i, rsskey[i]); mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 | E1000_MRQC_RSS_FIELD_IPV4_TCP); @@ -4370,6 +4376,9 @@ struct mbuf *sendmp, *mh, *mp; struct igb_rx_buf *rxbuf; u16 hlen, plen, hdr, vtag; + u16 pkt; + u32 rss; + u8 rsstype; bool eop = FALSE; cur = &rxr->rx_base[i]; @@ -4390,6 +4399,9 @@ else vtag = le16toh(cur->wb.upper.vlan); hdr = le16toh(cur->wb.lower.lo_dword.hs_rss.hdr_info); + pkt = le16toh(cur->wb.lower.lo_dword.hs_rss.pkt_info); + rss = le32toh(cur->wb.lower.hi_dword.rss); + rsstype = (u8)(pkt & E1000_RXDADV_RSSTYPE_MASK); eop = ((staterr & E1000_RXD_STAT_EOP) == E1000_RXD_STAT_EOP); /* Make sure all segments of a bad packet are discarded */ @@ -4487,14 +4499,29 @@ rxr->fmp->m_pkthdr.ether_vtag = vtag; rxr->fmp->m_flags |= M_VLANTAG; } - const char *rsstype_str[] = {"NONE", "IPV4_TCP", "IPV4", "IPV6_TCP", "IPV6_EX", "IPV6", "IPV6_TCP_EX", "IPV4_UDP", "IPV6_UDP", "IPV6_UDP_EX"}; - u16 pkt = le16toh(cur->wb.lower.lo_dword.hs_rss.pkt_info); - u32 rss = le32toh(cur->wb.lower.hi_dword.rss); - u8 rsstype = (u8)(pkt & E1000_RXDADV_RSSTYPE_MASK); - log(LOG_DEBUG, "[%d]msix:%d rsstype:%s ptype:%u plen:%u hdr_info:%x rss:%x\n", PCPU_GET(cpuid), que->msix, rsstype_str[rsstype], ptype, plen, hdr, rss); #if __FreeBSD_version >= 800000 - rxr->fmp->m_pkthdr.flowid = que->msix; + rxr->fmp->m_pkthdr.flowid = rss; rxr->fmp->m_flags |= M_FLOWID; + switch (rsstype) { + case 1: + M_HASHTYPE_SET(rxr->fmp, M_HASHTYPE_RSS_TCP_IPV4); + break; + case 2: + case 7: + M_HASHTYPE_SET(rxr->fmp, M_HASHTYPE_RSS_IPV4); + break; + case 3: + case 6: + M_HASHTYPE_SET(rxr->fmp, M_HASHTYPE_RSS_TCP_IPV6); + break; + case 4: + case 8: + case 9: + M_HASHTYPE_SET(rxr->fmp, M_HASHTYPE_RSS_IPV6); + break; + default: + M_HASHTYPE_SET(rxr->fmp, M_HASHTYPE_NONE); + } #endif rxr->fmp->m_pkthdr.rxqid = que->msix; rxr->fmp->m_pkthdr.txqid = (uint32_t)-1; ==== //depot/projects/soc2011/mq_bpf/src/sys/net/bpf.c#13 (text+ko) ==== @@ -40,7 +40,6 @@ #include "opt_bpf.h" #include "opt_compat.h" #include "opt_netgraph.h" -#include "opt_kdtrace.h" #include <sys/types.h> #include <sys/param.h> @@ -80,7 +79,6 @@ #include <netinet/if_ether.h> #include <sys/kernel.h> #include <sys/sysctl.h> -#include <sys/sdt.h> #include <net80211/ieee80211_freebsd.h> @@ -199,25 +197,6 @@ .f_event = filt_bpfread, }; -SDT_PROVIDER_DECLARE(bpf); -SDT_PROVIDER_DEFINE(bpf); -SDT_PROBE_DEFINE2(bpf, functions, bpf_tap, entry, entry, "void*", "boolean_t"); -SDT_PROBE_DEFINE3(bpf, functions, bpf_mtap_rx, entry, entry, "void *", "uint32_t", "uint32_t"); -SDT_PROBE_DEFINE3(bpf, functions, bpf_mtap_tx, entry, entry, "void *", "uint32_t", "uint32_t"); -SDT_PROBE_DEFINE3(bpf, functions, bpf_mtap2_rx, entry, entry, "void *", "uint32_t", "uint32_t"); -SDT_PROBE_DEFINE3(bpf, functions, bpf_mtap2_tx, entry, entry, "void *", "uint32_t", "uint32_t"); -SDT_PROBE_DEFINE1(bpf, functions, bpfioctl_biocenaqmask, entry, entry, "int"); -SDT_PROBE_DEFINE1(bpf, functions, bpfioctl_biocdisqmask, entry, entry, "int"); -SDT_PROBE_DEFINE1(bpf, functions, bpfioctl_biocstrxqmask, entry, entry, "int"); -SDT_PROBE_DEFINE1(bpf, functions, bpfioctl_bioccrrxqmask, entry, entry, "int"); -SDT_PROBE_DEFINE2(bpf, functions, bpfioctl_biocgtrxqmask, entry, entry, "int", "int"); -SDT_PROBE_DEFINE1(bpf, functions, bpfioctl_biocsttxqmask, entry, entry, "int"); -SDT_PROBE_DEFINE1(bpf, functions, bpfioctl_bioccrtxqmask, entry, entry, "int"); -SDT_PROBE_DEFINE2(bpf, functions, bpfioctl_biocgttxqmask, entry, entry, "int", "int"); -SDT_PROBE_DEFINE1(bpf, functions, bpfioctl_biocstothermask, entry, entry, "int"); -SDT_PROBE_DEFINE1(bpf, functions, bpfioctl_bioccrothermask, entry, entry, "int"); -SDT_PROBE_DEFINE1(bpf, functions, bpfioctl_biocgtothermask, entry, entry, "int"); - /* * Wrapper functions for various buffering methods. If the set of buffer * modes expands, we will probably want to introduce a switch data structure @@ -1546,13 +1525,11 @@ * No interface attached yet. */ error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocenaqmask, entry, -1); break; } if (d->bd_qmask.qm_enabled) { log(LOG_ERR, "d->bd_qmask.qm_enabled\n"); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocenaqmask, entry, -1); break; } ifp = d->bd_bif->bif_ifp; @@ -1560,7 +1537,6 @@ (IFCAP_MULTIQUEUE | IFCAP_SOFT_MULTIQUEUE))) { log(LOG_ERR, "if doesn't support multiqueue\n"); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocenaqmask, entry, -1); break; } KASSERT(ifp->if_get_rxqueue_len, ("ifp->if_get_rxqueue_len not set\n")); @@ -1573,7 +1549,6 @@ malloc(ifp->if_get_txqueue_len(ifp) * sizeof(boolean_t), M_BPF, M_WAITOK | M_ZERO); d->bd_qmask.qm_other_mask = FALSE; - SDT_PROBE1(bpf, functions, bpfioctl_biocenaqmask, entry, ifp->if_get_rxqueue_len(ifp)); break; } @@ -1585,19 +1560,16 @@ * No interface attached yet. */ error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocdisqmask, entry, -1); break; } if (!d->bd_qmask.qm_enabled) { log(LOG_ERR, "!d->bd_qmask.qm_enabled\n"); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocdisqmask, entry, -1); break; } d->bd_qmask.qm_enabled = FALSE; free(d->bd_qmask.qm_rxq_mask, M_BPF); free(d->bd_qmask.qm_txq_mask, M_BPF); - SDT_PROBE1(bpf, functions, bpfioctl_biocdisqmask, entry, 0); break; } @@ -1612,13 +1584,11 @@ * No interface attached yet. */ error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocstrxqmask, entry, -1); break; } if (!d->bd_qmask.qm_enabled) { log(LOG_ERR, "!d->bd_qmask.qm_enabled\n"); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocstrxqmask, entry, -1); break; } ifp = d->bd_bif->bif_ifp; @@ -1626,11 +1596,9 @@ if (index > ifp->if_get_rxqueue_len(ifp)) { log(LOG_ERR, "BIOCSTRXQMASK: index too large index:%x rxq_num:%x\n", index, ifp->if_get_rxqueue_len(ifp)); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocstrxqmask, entry, -1); break; } d->bd_qmask.qm_rxq_mask[index] = TRUE; - SDT_PROBE1(bpf, functions, bpfioctl_biocstrxqmask, entry, index); break; } @@ -1645,13 +1613,11 @@ * No interface attached yet. */ error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_bioccrrxqmask, entry, -1); break; } if (!d->bd_qmask.qm_enabled) { log(LOG_ERR, "!d->bd_qmask.qm_enabled\n"); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_bioccrrxqmask, entry, -1); break; } ifp = d->bd_bif->bif_ifp; @@ -1659,11 +1625,9 @@ if (index > ifp->if_get_rxqueue_len(ifp)) { log(LOG_ERR, "BIOCCRRXQMASK: index too large index:%x rxq_num:%x\n", index, ifp->if_get_rxqueue_len(ifp)); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_bioccrrxqmask, entry, -1); break; } d->bd_qmask.qm_rxq_mask[index] = FALSE; - SDT_PROBE1(bpf, functions, bpfioctl_bioccrrxqmask, entry, index); break; } @@ -1678,13 +1642,11 @@ * No interface attached yet. */ error = EINVAL; - SDT_PROBE2(bpf, functions, bpfioctl_biocgtrxqmask, entry, -1, -1); break; } if (!d->bd_qmask.qm_enabled) { log(LOG_ERR, "!d->bd_qmask.qm_enabled\n"); error = EINVAL; - SDT_PROBE2(bpf, functions, bpfioctl_biocgtrxqmask, entry, -1, -1); break; } ifp = d->bd_bif->bif_ifp; @@ -1692,11 +1654,9 @@ if (index > ifp->if_get_rxqueue_len(ifp)) { log(LOG_ERR, "BIOCGTRXQMASK: index too large index:%x rxq_num:%x\n", index, ifp->if_get_rxqueue_len(ifp)); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocgtrxqmask, entry, -1); break; } *(uint32_t *)addr = d->bd_qmask.qm_rxq_mask[index]; - SDT_PROBE2(bpf, functions, bpfioctl_biocgtrxqmask, entry, index, d->bd_qmask.qm_rxq_mask[index]); break; } @@ -1711,13 +1671,11 @@ * No interface attached yet. */ error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocsttxqmask, entry, -1); break; } if (!d->bd_qmask.qm_enabled) { log(LOG_ERR, "!d->bd_qmask.qm_enabled\n"); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocsttxqmask, entry, -1); break; } @@ -1726,11 +1684,9 @@ if (index > ifp->if_get_txqueue_len(ifp)) { log(LOG_ERR, "BIOCSTTXQMASK: index too large index:%x txq_num:%x\n", index, ifp->if_get_txqueue_len(ifp)); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_biocsttxqmask, entry, -1); break; } d->bd_qmask.qm_txq_mask[index] = TRUE; - SDT_PROBE1(bpf, functions, bpfioctl_biocsttxqmask, entry, index); break; } @@ -1745,13 +1701,11 @@ * No interface attached yet. */ error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_bioccrtxqmask, entry, -1); break; } if (!d->bd_qmask.qm_enabled) { log(LOG_ERR, "!d->bd_qmask.qm_enabled\n"); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_bioccrtxqmask, entry, -1); break; } @@ -1760,11 +1714,9 @@ if (index > ifp->if_get_txqueue_len(ifp)) { log(LOG_ERR, "BIOCCRTXQMASK: index too large index:%x txq_num:%x\n", index, ifp->if_get_txqueue_len(ifp)); error = EINVAL; - SDT_PROBE1(bpf, functions, bpfioctl_bioccrtxqmask, entry, -1); break; } d->bd_qmask.qm_txq_mask[index] = FALSE; - SDT_PROBE1(bpf, functions, bpfioctl_bioccrtxqmask, entry, index); break; } @@ -1779,13 +1731,11 @@ * No interface attached yet. */ error = EINVAL; - SDT_PROBE2(bpf, functions, bpfioctl_biocgttxqmask, entry, -1, -1); break; } if (!d->bd_qmask.qm_enabled) { log(LOG_ERR, "!d->bd_qmask.qm_enabled\n"); error = EINVAL; - SDT_PROBE2(bpf, functions, bpfioctl_biocgttxqmask, entry, -1, -1); break; } ifp = d->bd_bif->bif_ifp; @@ -1793,27 +1743,22 @@ if (index > ifp->if_get_txqueue_len(ifp)) { log(LOG_ERR, "BIOCGTTXQMASK: index too large index:%x txq_num:%x\n", index, ifp->if_get_txqueue_len(ifp)); error = EINVAL; - SDT_PROBE2(bpf, functions, bpfioctl_biocgttxqmask, entry, -1, -1); break; } *(uint32_t *)addr = d->bd_qmask.qm_txq_mask[index]; - SDT_PROBE2(bpf, functions, bpfioctl_biocgttxqmask, entry, index, d->bd_qmask.qm_txq_mask[index]); break; } case BIOCSTOTHERMASK: d->bd_qmask.qm_other_mask = TRUE; - SDT_PROBE1(bpf, functions, bpfioctl_biocstothermask, entry, 1); break; case BIOCCROTHERMASK: d->bd_qmask.qm_other_mask = FALSE; - SDT_PROBE1(bpf, functions, bpfioctl_bioccrothermask, entry, 0); break; case BIOCGTOTHERMASK: *(uint32_t *)addr = (uint32_t)d->bd_qmask.qm_other_mask; - SDT_PROBE1(bpf, functions, bpfioctl_biocgtothermask, entry, d->bd_qmask.qm_other_mask); break; } CURVNET_RESTORE(); @@ -2122,13 +2067,12 @@ #endif u_int slen; int gottime; - struct rm_priotracker tracker; +// struct rm_priotracker tracker; gottime = BPF_TSTAMP_NONE; BPFIF_RLOCK(bp, &tracker); LIST_FOREACH(d, &bp->bif_dlist, bd_next) { if (d->bd_qmask.qm_enabled) { - SDT_PROBE2(bpf, functions, bpf_tap, entry, d, d->bd_qmask.qm_other_mask); if (!d->bd_qmask.qm_other_mask) continue; } @@ -2177,7 +2121,7 @@ #endif u_int pktlen, slen; int gottime; - struct rm_priotracker tracker; +// struct rm_priotracker tracker; /* Skip outgoing duplicate packets. */ if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) { @@ -2189,26 +2133,25 @@ gottime = BPF_TSTAMP_NONE; BPFIF_RLOCK(bp, &tracker); + struct ifnet *ifp = bp->bif_ifp; LIST_FOREACH(d, &bp->bif_dlist, bd_next) { if (d->bd_qmask.qm_enabled) { if (!(m->m_flags & M_FLOWID)) { - log(LOG_DEBUG, "m:%p ifp:%p !(m->flags & M_FLOWID)\n", - m, m->m_pkthdr.rcvif); if (!d->bd_qmask.qm_other_mask) continue; } else { - struct ifnet *ifp = bp->bif_ifp; - if (m->m_pkthdr.rxqid != (uint32_t)-1) - KASSERT(m->m_pkthdr.rxqid < ifp->if_get_rxqueue_len(ifp), - ("rxqid is not vaild rxqid:%x rxq_num:%x", - m->m_pkthdr.rxqid, ifp->if_get_rxqueue_len(ifp))); - if (m->m_pkthdr.txqid != (uint32_t)-1) - KASSERT(m->m_pkthdr.txqid < ifp->if_get_txqueue_len(ifp), - ("txqid is not vaild txqid:%x txq_num:%x", - m->m_pkthdr.txqid, ifp->if_get_txqueue_len(ifp))); - - SDT_PROBE3(bpf, functions, bpf_mtap_rx, entry, d, m->m_pkthdr.rxqid, ifp->if_get_rxqueue_len(ifp)); - SDT_PROBE3(bpf, functions, bpf_mtap_tx, entry, d, m->m_pkthdr.txqid, ifp->if_get_txqueue_len(ifp)); + log(LOG_DEBUG, "%s: ifp->if_get_rxqueue_len:%p\n", __func__, ifp->if_get_rxqueue_len); + if (m->m_pkthdr.rxqid != (uint32_t)-1 && m->m_pkthdr.rxqid >= ifp->if_get_rxqueue_len(ifp)) { + log(LOG_DEBUG, "rxqid is not vaild rxqid:%x rxq_num:%x\n", m->m_pkthdr.rxqid, ifp->if_get_rxqueue_len(ifp)); + BPFIF_RUNLOCK(bp, &tracker); + return; + } + log(LOG_DEBUG, "%s: ifp->if_get_txqueue_len:%p\n", __func__, ifp->if_get_txqueue_len); + if (m->m_pkthdr.txqid != (uint32_t)-1 && m->m_pkthdr.txqid >= ifp->if_get_txqueue_len(ifp)) { + log(LOG_DEBUG, "txqid is not vaild txqid:%x txq_num:%x\n", m->m_pkthdr.txqid, ifp->if_get_txqueue_len(ifp)); + BPFIF_RUNLOCK(bp, &tracker); + return; + } if (m->m_pkthdr.rxqid != (uint32_t)-1 && !d->bd_qmask.qm_rxq_mask[m->m_pkthdr.rxqid]) continue; @@ -2256,7 +2199,7 @@ struct bpf_d *d; u_int pktlen, slen; int gottime; - struct rm_priotracker tracker; +// struct rm_priotracker tracker; /* Skip outgoing duplicate packets. */ if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) { @@ -2279,10 +2222,6 @@ BPFIF_RLOCK(bp, &tracker); LIST_FOREACH(d, &bp->bif_dlist, bd_next) { if (d->bd_qmask.qm_enabled) { - struct ifnet *ifp = bp->bif_ifp; - SDT_PROBE3(bpf, functions, bpf_mtap2_rx, entry, d, m->m_pkthdr.rxqid, ifp->if_get_rxqueue_len(ifp)); - SDT_PROBE3(bpf, functions, bpf_mtap2_tx, entry, d, m->m_pkthdr.txqid, ifp->if_get_txqueue_len(ifp)); - if (m->m_pkthdr.rxqid != (uint32_t)-1 && !d->bd_qmask.qm_rxq_mask[m->m_pkthdr.rxqid]) continue; @@ -2732,7 +2671,7 @@ { struct bpf_if *bp; struct bpf_d *bd; - struct rm_priotracker tracker; +// struct rm_priotracker tracker; mtx_lock(&bpf_mtx); LIST_FOREACH(bp, &bpf_iflist, bif_next) { @@ -2790,7 +2729,7 @@ int index, error; struct bpf_if *bp; struct bpf_d *bd; - struct rm_priotracker tracker; +// struct rm_priotracker tracker; /* * XXX This is not technically correct. It is possible for non ==== //depot/projects/soc2011/mq_bpf/src/sys/net/bpfdesc.h#5 (text+ko) ==== @@ -153,11 +153,11 @@ }; #define BPFIF_LOCK_INIT(bif, d) \ - rm_init_flags(&(bif)->bif_lock, (d), RM_NOWITNESS | RM_RECURSE); -#define BPFIF_LOCK_DESTROY(bif) rm_destroy(&(bif)->bif_lock) -#define BPFIF_RLOCK(bif, tracker) rm_rlock(&(bif)->bif_lock, tracker) -#define BPFIF_RUNLOCK(bif, tracker) rm_runlock(&(bif)->bif_lock, tracker) -#define BPFIF_WLOCK(bif) rm_wlock(&(bif)->bif_lock) -#define BPFIF_WUNLOCK(bif) rm_wunlock(&(bif)->bif_lock) + mtx_init(&(bif)->bif_lock, (d), "bpf if lock", MTX_DEF); +#define BPFIF_LOCK_DESTROY(bif) mtx_destroy(&(bif)->bif_lock) +#define BPFIF_RLOCK(bif, tracker) mtx_lock(&(bif)->bif_lock) +#define BPFIF_RUNLOCK(bif, tracker) mtx_unlock(&(bif)->bif_lock) +#define BPFIF_WLOCK(bif) mtx_lock(&(bif)->bif_lock) +#define BPFIF_WUNLOCK(bif) mtx_unlock(&(bif)->bif_lock) #endif ==== //depot/projects/soc2011/mq_bpf/src/sys/net/if.c#6 (text+ko) ==== @@ -2433,9 +2433,8 @@ (IFCAP_MULTIQUEUE | IFCAP_SOFT_MULTIQUEUE))) return (EOPNOTSUPP); KASSERT(ifp->if_get_rxqueue_affinity, ("if_get_rxqueue_affinity not set")); - log(LOG_DEBUG, "%s: SIOCGIFRXQAFFINITY ifr_queue_affinity_index:%d\n", __func__, ifr->ifr_queue_affinity_index); - ifr->ifr_queue_affinity_cpu = ifp->if_get_rxqueue_affinity(ifp, ifr->ifr_queue_affinity_index); - log(LOG_DEBUG, "%s: SIOCGIFRXQAFFINITY ifr_queue_affinity_cpu:%d\n", __func__, ifr->ifr_queue_affinity_cpu); + ifr->ifr_queue_affinity_cpu = + ifp->if_get_rxqueue_affinity(ifp, ifr->ifr_queue_affinity_index); break; case SIOCGIFTXQAFFINITY: @@ -2443,9 +2442,8 @@ (IFCAP_MULTIQUEUE | IFCAP_SOFT_MULTIQUEUE))) return (EOPNOTSUPP); KASSERT(ifp->if_get_rxqueue_affinity, ("if_get_rxqueue_affinity not set")); - log(LOG_DEBUG, "%s: SIOCGIFTXQAFFINITY ifr_queue_affinity_index:%d\n", __func__, ifr->ifr_queue_affinity_index); - ifr->ifr_queue_affinity_cpu = ifp->if_get_rxqueue_affinity(ifp, ifr->ifr_queue_affinity_index); - log(LOG_DEBUG, "%s: SIOCGIFTXQAFFINITY ifr_queue_affinity_cpu:%d\n", __func__, ifr->ifr_queue_affinity_cpu); + ifr->ifr_queue_affinity_cpu = + ifp->if_get_rxqueue_affinity(ifp, ifr->ifr_queue_affinity_index); break; default: ==== //depot/projects/soc2011/mq_bpf/src/sys/net/if_ethersubr.c#6 (text+ko) ==== @@ -50,6 +50,7 @@ #include <sys/socket.h> #include <sys/sockio.h> #include <sys/sysctl.h> +#include <sys/syslog.h> #include <net/if.h> #include <net/if_arp.h> @@ -453,6 +454,7 @@ #ifdef SOFTRSS if (ifp->if_capenable & IFCAP_SOFT_MULTIQUEUE) { + log(LOG_DEBUG, "%s SOFTRSS setting txqid:0\n", __func__); m->m_pkthdr.rxqid = (uint32_t)-1; m->m_pkthdr.txqid = 0; } @@ -1061,17 +1063,13 @@ if_printf(ifp, "Ethernet address: %6D\n", lla, ":"); #ifdef SOFTRSS - printf("%s: SOFTRSS if:%s\n", __func__, ifp->if_xname); if (!(ifp->if_capabilities & IFCAP_MULTIQUEUE)) { - printf("%s: !IFCAP_MULTIQUEUE if:%s\n", __func__, ifp->if_xname); ifp->if_capabilities |= IFCAP_SOFT_MULTIQUEUE; ifp->if_capenable |= IFCAP_SOFT_MULTIQUEUE; ifp->if_get_rxqueue_len = softrss_get_rxqueue_len; ifp->if_get_txqueue_len = softrss_get_txqueue_len; ifp->if_get_rxqueue_affinity = softrss_get_rxqueue_affinity; ifp->if_get_txqueue_affinity = softrss_get_txqueue_affinity; - }else{ - printf("%s: IFCAP_MULTIQUEUE if:%s\n", __func__, ifp->if_xname); } #endif } ==== //depot/projects/soc2011/mq_bpf/src/sys/netinet/in_rss.c#3 (text+ko) ==== @@ -32,7 +32,6 @@ __FBSDID("$FreeBSD$"); #include "opt_inet6.h" -#include "opt_kdtrace.h" #include "opt_rss.h" #include <sys/param.h> @@ -438,6 +437,7 @@ case M_HASHTYPE_RSS_TCP_IPV4: *cpuid = rss_getcpu(rss_getbucket(m->m_pkthdr.flowid)); #ifdef SOFTRSS + log(LOG_DEBUG, "%s SOFTRSS set rxqid:%d\n", __func__, *cpuid); m->m_pkthdr.rxqid = *cpuid; m->m_pkthdr.txqid = (uint32_t)-1; SDT_PROBE2(rss, functions, rss_m2cpuid, entry, m->m_pkthdr.rxqid, m->m_pkthdr.txqid); @@ -447,6 +447,7 @@ default: *cpuid = NETISR_CPUID_NONE; #ifdef SOFTRSS + log(LOG_DEBUG, "%s SOFTRSS set rxqid:%d\n", __func__, *cpuid); m->m_pkthdr.rxqid = curcpu; m->m_pkthdr.txqid = (uint32_t)-1; SDT_PROBE2(rss, functions, rss_m2cpuid, entry, m->m_pkthdr.rxqid, m->m_pkthdr.txqid); ==== //depot/projects/soc2011/mq_bpf/tests/Makefile#3 (text+ko) ==== @@ -1,10 +1,16 @@ TARGETS = test_ifqueue test_sqbpf test_mqbpf CFLAGS = -Wall -Werror -g -test_mqbpf: - $(CC) $(CFLAGS) -lpthread -o $@ test_mqbpf.c +all: $(TARGETS) + +test_mqbpf: test_mqbpf.c + $(CC) $(CFLAGS) -lpthread -o $@ $< + +test_sqbpf: test_sqbpf.c + $(CC) $(CFLAGS) -o $@ $< -all: $(TARGETS) +test_ifqueue: test_ifqueue.c + $(CC) $(CFLAGS) -o $@ $< clean: rm -f $(TARGETS) *.o ==== //depot/projects/soc2011/mq_bpf/tests/test_mqbpf.c#2 (text+ko) ==== @@ -64,6 +64,7 @@ #include <stdlib.h> #include <err.h> #include <pthread.h> +#include <signal.h> #define CAP_FORMAT "cap.dat.%d" #define BPF_FORMAT "/dev/bpf%d" @@ -78,9 +79,14 @@ int queue; int cpu; cpuset_t cpuset; + int fd; + int wrote; }; -char *ifname = NULL; +static char *ifname = NULL; +static struct bpf_thread_instance *instances; +static int rxqlen, txqlen; +static struct timeval start; int bpf_thread(struct bpf_thread_instance *instance) { @@ -91,13 +97,9 @@ int rbuf_offset = 0; int rbuf_len = 0; int length = 0; - int wrote = 0; struct bpf_hdr *hdr; - struct timeval start, curr; - time_t sec; struct ifreq ifr; - printf("%d:%d ifname:%s\n", instance->type, instance->queue, ifname); ifr.ifr_addr.sa_family = AF_LOCAL; strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); @@ -108,10 +110,10 @@ sizeof(cpuset_t), &instance->cpuset); } snprintf(filename, sizeof(filename), CAP_FORMAT, instance->queue); - int fd = open(filename, O_RDWR | O_CREAT); - if (fd < 0) { + instance->fd = open(filename, O_RDWR | O_CREAT); + if (instance->fd < 0) { perror("open"); - return fd; + return instance->fd; } /* Open a BPF device */ for (b = 0; 1; b++) { @@ -180,19 +182,9 @@ break; } - gettimeofday(&start, NULL); + instance->wrote = 0; - /* - * All this complexity is because BPF doesn't guarantee that - * only one packet will be returned at a time. We're getting - * what we deserve, though - this is a terrible abuse of the BPF - * interface. Sigh. - */ - - /* Process packets until we get one we can return or until we've - * done a read and gotten nothing we can return... - */ - do { + while(1) { /* If the buffer is empty, fill it. */ if (rbuf_offset >= rbuf_len) { length = read(bpf, rbuf, @@ -246,30 +238,54 @@ continue; } - struct ether_header *eh = (struct ether_header *)(rbuf + rbuf_offset); - printf("%d:%d type:%x\n", - instance->type, instance->queue, eh->ether_type); /* Copy out the data in the packet... */ - write(fd, rbuf + rbuf_offset, hdr->bh_caplen); - wrote += hdr->bh_caplen; + write(instance->fd, rbuf + rbuf_offset, hdr->bh_caplen); + instance->wrote += hdr->bh_caplen; rbuf_offset = BPF_WORDALIGN(rbuf_offset + hdr->bh_caplen); - gettimeofday(&curr, NULL); - sec = curr.tv_sec - start.tv_sec; - } while (sec < 60); + } + return 0; +} + +static void timer_handler(int arg) +{ + struct timeval curr; + time_t sec; + int i, ret; + int wrote = 0; + + for (i = 0; i < (rxqlen + txqlen + 1); i++) { + pthread_cancel(instances[i].thread); + pthread_join(instances[i].thread, (void **)&ret); + wrote += instances[i].wrote; + } + gettimeofday(&curr, NULL); + sec = curr.tv_sec - start.tv_sec; wrote /= (1024 * 1024); printf("sec:%ld wrote:%d MB thoughput:%f MB/s\n", sec, wrote, (double)wrote / (double)sec); - close(fd); - return 0; + exit(0); } int main(int argc, char **argv) { struct ifreq ifr; - struct bpf_thread_instance *instances; - int i, j, rxqlen, txqlen, s; + int i, j, s, ret; + struct sigaction action = { + .sa_handler = timer_handler, + .sa_flags = 0 + }; + struct itimerval timer = { + .it_interval = { + .tv_sec = 0, + .tv_usec = 0 + }, + .it_value = { + .tv_sec = 60, + .tv_usec = 0 + } + }; if (argc < 2) { printf("usage: %s [ifname]\n", argv[0]); @@ -293,6 +309,18 @@ txqlen = ifr.ifr_txqueue_len; instances = (struct bpf_thread_instance *) malloc(sizeof(struct bpf_thread_instance) * (rxqlen + txqlen + 1)); + + sigemptyset(&action.sa_mask); + if (sigaction(SIGALRM, &action, NULL) < 0) { + perror("sigaction"); + return -1; + } + if (setitimer(ITIMER_REAL, &timer, NULL) < 0) { + perror("setitimer"); + return -1; + } + + gettimeofday(&start, NULL); for (i = 0; i < rxqlen; i++) { instances[i].type = QUEUE_TYPE_RX; instances[i].queue = ifr.ifr_queue_affinity_index = i; @@ -319,8 +347,10 @@ instances[j].queue = 1; pthread_create(&instances[j].thread, NULL, (void *(*)(void *))bpf_thread, &instances[j]); - for (i = 0; i < rxqlen; i++) { - pthread_join(instances[i].thread, NULL); + + for (i = 0; i < (rxqlen + txqlen + 1); i++) { + pthread_join(instances[i].thread, (void **)&ret); } + return 0; } ==== //depot/projects/soc2011/mq_bpf/tests/test_sqbpf.c#3 (text+ko) ==== @@ -61,9 +61,28 @@ #include <unistd.h> #include <stdlib.h> #include <err.h> +#include <signal.h> #define BPF_FORMAT "/dev/bpf%d" +static struct timeval start; +static int fd; +static int wrote = 0; + +static void timer_handler(int arg) +{ + struct timeval curr; + time_t sec; + + gettimeofday(&curr, NULL); + sec = curr.tv_sec - start.tv_sec; + wrote /= (1024 * 1024); + printf("sec:%ld wrote:%d MB thoughput:%f MB/s\n", + sec, wrote, (double)wrote / (double)sec); + close(fd); + exit(0); +} + int main(int argc, char **argv) { char filename[50]; @@ -73,17 +92,28 @@ int rbuf_offset = 0; int rbuf_len = 0; int length = 0; - int wrote = 0; struct bpf_hdr *hdr; struct ifreq ifr; - struct timeval start, curr; - time_t sec; + struct sigaction action = { + .sa_handler = timer_handler, + .sa_flags = 0 + }; + struct itimerval timer = { + .it_interval = { + .tv_sec = 0, + .tv_usec = 0 + }, + .it_value = { + .tv_sec = 60, + .tv_usec = 0 + } + }; if (argc < 2) { printf("usage: %s [ifname]\n", argv[0]); return -1; } - int fd = open("cap.dat", O_RDWR | O_CREAT); + fd = open("cap.dat", O_RDWR | O_CREAT); if (fd < 0) { perror("open"); return fd; @@ -132,19 +162,18 @@ return -1; } + sigemptyset(&action.sa_mask); + if (sigaction(SIGALRM, &action, NULL) < 0) { + perror("sigaction"); + return -1; + } + if (setitimer(ITIMER_REAL, &timer, NULL) < 0) { + perror("setitimer"); + return -1; + } gettimeofday(&start, NULL); - /* - * All this complexity is because BPF doesn't guarantee that - * only one packet will be returned at a time. We're getting - * what we deserve, though - this is a terrible abuse of the BPF - * interface. Sigh. - */ - - /* Process packets until we get one we can return or until we've - * done a read and gotten nothing we can return... - */ - do { + while(1) { /* If the buffer is empty, fill it. */ if (rbuf_offset >= rbuf_len) { length = read(bpf, rbuf, @@ -204,12 +233,6 @@ rbuf_offset = BPF_WORDALIGN(rbuf_offset + hdr->bh_caplen); - gettimeofday(&curr, NULL); - sec = curr.tv_sec - start.tv_sec; - } while (sec < 60); - wrote /= (1024 * 1024); - printf("sec:%ld wrote:%d MB thoughput:%f MB/s\n", - sec, wrote, (double)wrote / (double)sec); - close(fd); + } return 0; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107152226.p6FMQ8Lc046364>