Date: Tue, 17 May 2011 21:53:35 GMT From: Takuya ASADA <syuu@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 193316 for review Message-ID: <201105172153.p4HLrZTT025755@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@193316?ac=10 Change 193316 by syuu@kikurage on 2011/05/17 21:53:01 Multiqueue experimental implementation. BIOCRXQAFFINITY and BIOCTXQAFFINITY are not implemented yet. Quick hack multiqueue support for tcpdump/libpcap included. Affected files ... .. //depot/projects/soc2011/mq_bpf/src/contrib/libpcap/pcap-bpf.c#2 edit .. //depot/projects/soc2011/mq_bpf/src/contrib/libpcap/pcap-int.h#2 edit .. //depot/projects/soc2011/mq_bpf/src/contrib/libpcap/pcap.c#2 edit .. //depot/projects/soc2011/mq_bpf/src/contrib/libpcap/pcap/pcap.h#2 edit .. //depot/projects/soc2011/mq_bpf/src/contrib/tcpdump/tcpdump.c#2 edit .. //depot/projects/soc2011/mq_bpf/src/sys/dev/e1000/if_igb.c#2 edit .. //depot/projects/soc2011/mq_bpf/src/sys/net/bpf.c#2 edit .. //depot/projects/soc2011/mq_bpf/src/sys/net/bpf.h#2 edit .. //depot/projects/soc2011/mq_bpf/src/sys/net/bpfdesc.h#2 edit .. //depot/projects/soc2011/mq_bpf/src/sys/net/if_var.h#2 edit .. //depot/projects/soc2011/mq_bpf/src/sys/sys/mbuf.h#2 edit Differences ... ==== //depot/projects/soc2011/mq_bpf/src/contrib/libpcap/pcap-bpf.c#2 (text+ko) ==== @@ -35,6 +35,7 @@ #endif #include <sys/time.h> #include <sys/socket.h> +#include <sys/types.h> /* * <net/bpf.h> defines ioctls, but doesn't include <sys/ioccom.h>. * @@ -2103,6 +2104,40 @@ } #endif + if (p->rxq_num != (uint32_t)-1 || p->txq_num != (uint32_t)-1 || + p->other_mask != (uint32_t)-1) { + if (ioctl(fd, BIOCENAQMASK, NULL) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCENAQMASK: %s", + pcap_strerror(errno)); + status = PCAP_ERROR; + goto bad; + } + if (p->rxq_num != (uint32_t)-1) { + if (ioctl(fd, BIOCSTRXQMASK, &p->rxq_num) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSTRXQMASK: %s", + pcap_strerror(errno)); + status = PCAP_ERROR; + goto bad; + } + } + if (p->txq_num != (uint32_t)-1) { + if (ioctl(fd, BIOCSTTXQMASK, &p->txq_num) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSTTXQMASK: %s", + pcap_strerror(errno)); + status = PCAP_ERROR; + goto bad; + } + } + if (p->other_mask != (uint32_t)-1) { + if (ioctl(fd, BIOSTOTHERMASK, &p->other_mask) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSTOTHERQMASK: %s", + pcap_strerror(errno)); + status = PCAP_ERROR; + goto bad; + } + } + } + /* * If there's no filter program installed, there's * no indication to the kernel of what the snapshot ==== //depot/projects/soc2011/mq_bpf/src/contrib/libpcap/pcap-int.h#2 (text+ko) ==== @@ -333,6 +333,9 @@ u_int *dlt_list; struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */ + + uint32_t rxq_num, txq_num; + uint32_t other_mask; }; /* ==== //depot/projects/soc2011/mq_bpf/src/contrib/libpcap/pcap.c#2 (text+ko) ==== @@ -259,6 +259,9 @@ pcap_set_snaplen(p, 65535); /* max packet size */ p->opt.promisc = 0; p->opt.buffer_size = 0; + p->rxq_num = (uint32_t)-1; + p->txq_num = (uint32_t)-1; + p->other_mask = (uint32_t)-1; return (p); } @@ -347,6 +350,33 @@ return (status); } +int +pcap_set_rxq_mask(pcap_t *p, uint32_t num) +{ + if (pcap_check_activated(p)) + return PCAP_ERROR_ACTIVATED; + p->rxq_num = num; + return 0; +} + +int +pcap_set_txq_mask(pcap_t *p, uint32_t num) +{ + if (pcap_check_activated(p)) + return PCAP_ERROR_ACTIVATED; + p->txq_num = num; + return 0; +} + +int +pcap_set_other_mask(pcap_t *p, uint32_t mask) +{ + if (pcap_check_activated(p)) + return PCAP_ERROR_ACTIVATED; + p->other_mask = mask; + return 0; +} + pcap_t * pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf) { ==== //depot/projects/soc2011/mq_bpf/src/contrib/libpcap/pcap/pcap.h#2 (text+ko) ==== @@ -276,6 +276,10 @@ int pcap_set_buffer_size(pcap_t *, int); int pcap_activate(pcap_t *); +int pcap_set_rxq_mask(pcap_t *, uint32_t); +int pcap_set_txq_mask(pcap_t *, uint32_t); +int pcap_set_other_mask(pcap_t *, uint32_t); + pcap_t *pcap_open_live(const char *, int, int, int, char *); pcap_t *pcap_open_dead(int, int); pcap_t *pcap_open_offline(const char *, char *); ==== //depot/projects/soc2011/mq_bpf/src/contrib/tcpdump/tcpdump.c#2 (text+ko) ==== @@ -570,6 +570,7 @@ int devnum; #endif int status; + uint32_t rxq = (uint32_t)-1, txq = (uint32_t)-1, other = (uint32_t)-1; #ifdef WIN32 if(wsockinit() != 0) return 1; #endif /* WIN32 */ @@ -602,7 +603,7 @@ opterr = 0; while ( - (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:i:" I_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1) + (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:i:" I_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:Q:g:V")) != -1) switch (op) { case 'a': @@ -936,6 +937,20 @@ } break; + case 'Q': + rxq = atoi(optarg); + break; + + case 'g': + txq = atoi(optarg); + break; + + case 'V': + other = atoi(optarg); + if (other != 0 || other != 1) + usage(); + break; + default: usage(); /* NOTREACHED */ @@ -1065,6 +1080,13 @@ error("%s: pcap_set_buffer_size failed: %s", device, pcap_statustostr(status)); } + if (rxq != (uint32_t)-1) + pcap_set_rxq_mask(pd, rxq); + if (txq != (uint32_t)-1) + pcap_set_txq_mask(pd, txq); + if (other != (uint32_t)-1) + pcap_set_other_mask(pd, other); + status = pcap_activate(pd); if (status < 0) { /* ==== //depot/projects/soc2011/mq_bpf/src/sys/dev/e1000/if_igb.c#2 (text+ko) ==== @@ -651,6 +651,9 @@ adapter->led_dev = led_create(igb_led_func, adapter, device_get_nameunit(dev)); + + adapter->ifp->if_rxq_num = adapter->num_queues; + adapter->ifp->if_txq_num = adapter->num_queues; INIT_DEBUGOUT("igb_attach: end"); return (0); @@ -847,6 +850,9 @@ break; } + m_head->m_pkthdr.rxqid = (uint32_t)-1; + m_head->m_pkthdr.txqid = txr->me; + /* Send a copy of the frame to the BPF listener */ ETHER_BPF_MTAP(ifp, m_head); @@ -941,6 +947,10 @@ } enq++; drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags); + + next->m_pkthdr.rxqid = (uint32_t)-1; + next->m_pkthdr.txqid = txr->me; + ETHER_BPF_MTAP(ifp, next); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) break; @@ -1352,7 +1362,6 @@ struct igb_queue *que = adapter->queues; u32 reg_icr; - reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR); /* Hot eject? */ @@ -4474,6 +4483,9 @@ rxr->fmp->m_pkthdr.flowid = que->msix; rxr->fmp->m_flags |= M_FLOWID; #endif + rxr->fmp->m_pkthdr.rxqid = que->msix; + rxr->fmp->m_pkthdr.txqid = (uint32_t)-1; + sendmp = rxr->fmp; /* Make sure to set M_PKTHDR. */ sendmp->m_flags |= M_PKTHDR; ==== //depot/projects/soc2011/mq_bpf/src/sys/net/bpf.c#2 (text+ko) ==== @@ -690,6 +690,10 @@ d->bd_sig = SIGIO; d->bd_direction = BPF_D_INOUT; d->bd_pid = td->td_proc->p_pid; + d->bd_qmask.qm_enabled = FALSE; + d->bd_qmask.qm_rxq_mask = NULL; + d->bd_qmask.qm_txq_mask = NULL; + d->bd_qmask.qm_other_mask = FALSE; #ifdef MAC mac_bpfdesc_init(d); mac_bpfdesc_create(td->td_ucred, d); @@ -1510,6 +1514,190 @@ case BIOCROTZBUF: error = bpf_ioctl_rotzbuf(td, d, (struct bpf_zbuf *)addr); break; + + case BIOCRXQLEN: + { + printf("BIOCRXQLEN\n"); + struct ifnet *const ifp = d->bd_bif->bif_ifp; + *(int *)addr = ifp->if_rxq_num; + break; + } + + case BIOCTXQLEN: + { + printf("BIOCTXQLEN\n"); + struct ifnet *const ifp = d->bd_bif->bif_ifp; + *(int *)addr = ifp->if_txq_num; + break; + } + + /* XXX: not implemented yet */ + case BIOCRXQAFFINITY: + printf("BIOCRXQAFFINITY\n"); + error = EINVAL; + break; + + /* XXX: not implemented yet */ + case BIOCTXQAFFINITY: + printf("BIOCTXQAFFINITY\n"); + error = EINVAL; + break; + + case BIOCENAQMASK: + { + printf("BIOCENAQMASK\n"); + if (d->bd_bif == NULL) { + printf("d->bd_bif == NULL\n"); + /* + * No interface attached yet. + */ + error = EINVAL; + break; + } + if (d->bd_qmask.qm_enabled) { + printf("d->bd_qmask.qm_enabled\n"); + error = EINVAL; + break; + } + struct ifnet *const ifp = d->bd_bif->bif_ifp; + d->bd_qmask.qm_enabled = TRUE; + printf("ifp->if_rxq_num:%d\n", ifp->if_rxq_num); + d->bd_qmask.qm_rxq_mask = + malloc(ifp->if_rxq_num * sizeof(boolean_t), M_BPF, + M_WAITOK | M_ZERO); + printf("ifp->if_txq_num:%d\n", ifp->if_txq_num); + d->bd_qmask.qm_txq_mask = + malloc(ifp->if_txq_num * sizeof(boolean_t), M_BPF, + M_WAITOK | M_ZERO); + d->bd_qmask.qm_other_mask = FALSE; + break; + } + + case BIOCDISQMASK: + { + printf("BIOCDISQMASK\n"); + if (d->bd_bif == NULL) { + printf("d->bd_bif == NULL\n"); + /* + * No interface attached yet. + */ + error = EINVAL; + break; + } + if (!d->bd_qmask.qm_enabled) { + printf("!d->bd_qmask.qm_enabled\n"); + error = EINVAL; + 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); + break; + } + + case BIOCSTRXQMASK: + { + int index; + printf("BIOCSTRXQMASK\n"); + if (d->bd_bif == NULL) { + printf("d->bd_bif == NULL\n"); + /* + * No interface attached yet. + */ + error = EINVAL; + break; + } + if (!d->bd_qmask.qm_enabled) { + printf("!d->bd_qmask.qm_enabled\n"); + error = EINVAL; + break; + } + index = *(uint32_t *)addr; + printf("index:%d\n", index); + d->bd_qmask.qm_rxq_mask[index] = TRUE; + break; + } + + case BIOCGTRXQMASK: + { + int index; + printf("BIOCGTRXQMASK\n"); + if (d->bd_bif == NULL) { + printf("d->bd_bif == NULL\n"); + /* + * No interface attached yet. + */ + error = EINVAL; + break; + } + if (!d->bd_qmask.qm_enabled) { + printf("!d->bd_qmask.qm_enabled\n"); + error = EINVAL; + break; + } + index = *(uint32_t *)addr; + printf("index:%d\n", index); + *(uint32_t *)addr = d->bd_qmask.qm_rxq_mask[index]; + break; + } + + case BIOCSTTXQMASK: + { + int index; + printf("BIOCSTTXQMASK\n"); + if (d->bd_bif == NULL) { + printf("d->bd_bif == NULL\n"); + /* + * No interface attached yet. + */ + error = EINVAL; + break; + } + if (!d->bd_qmask.qm_enabled) { + printf("!d->bd_qmask.qm_enabled\n"); + error = EINVAL; + break; + } + index = *(uint32_t *)addr; + printf("index:%d\n", index); + d->bd_qmask.qm_txq_mask[index] = TRUE; + break; + } + + case BIOCGTTXQMASK: + { + int index; + printf("BIOCGTTXQMASK\n"); + if (d->bd_bif == NULL) { + printf("d->bd_bif == NULL\n"); + /* + * No interface attached yet. + */ + error = EINVAL; + break; + } + if (!d->bd_qmask.qm_enabled) { + printf("!d->bd_qmask.qm_enabled\n"); + error = EINVAL; + break; + } + index = *(uint32_t *)addr; + printf("index:%d\n", index); + *(uint32_t *)addr = d->bd_qmask.qm_txq_mask[index]; + break; + } + + case BIOSTOTHERMASK: + printf("BIOSTOTHERMASK\n"); + d->bd_qmask.qm_other_mask = (boolean_t)*(uint32_t *)addr; + printf("mask:%d\n", d->bd_qmask.qm_other_mask); + break; + + case BIOGTOTHERMASK: + printf("BIOGTOTHERMASK\n"); + printf("mask:%d\n", d->bd_qmask.qm_other_mask); + *(uint32_t *)addr = (uint32_t)d->bd_qmask.qm_other_mask; + break; } CURVNET_RESTORE(); return (error); @@ -1821,6 +2009,13 @@ gottime = BPF_TSTAMP_NONE; BPFIF_LOCK(bp); LIST_FOREACH(d, &bp->bif_dlist, bd_next) { + if (d->bd_qmask.qm_enabled) { + printf("bpf_tap other_mask:%d\n", + d->bd_qmask.qm_other_mask); + if (!d->bd_qmask.qm_other_mask) + continue; + } + BPFD_LOCK(d); ++d->bd_rcount; /* @@ -1855,9 +2050,6 @@ (((d)->bd_direction == BPF_D_IN && (r) != (i)) || \ ((d)->bd_direction == BPF_D_OUT && (r) == (i))) -/* - * Incoming linkage from device drivers, when packet is in an mbuf chain. - */ void bpf_mtap(struct bpf_if *bp, struct mbuf *m) { @@ -1869,6 +2061,13 @@ u_int pktlen, slen; int gottime; +#if 0 + if (m->m_pkthdr.txqid != (uint32_t)-1 && m->m_pkthdr.txqid != PCPU_GET(cpuid)) + printf("txqid:%d cpuid:%d\n", m->m_pkthdr.txqid, PCPU_GET(cpuid)); +#endif + if (m->m_pkthdr.rxqid != (uint32_t)-1 && m->m_pkthdr.rxqid != PCPU_GET(cpuid)) + printf("rxqid:%d cpuid:%d\n", m->m_pkthdr.rxqid, PCPU_GET(cpuid)); + /* Skip outgoing duplicate packets. */ if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) { m->m_flags &= ~M_PROMISC; @@ -1880,6 +2079,19 @@ gottime = BPF_TSTAMP_NONE; BPFIF_LOCK(bp); LIST_FOREACH(d, &bp->bif_dlist, bd_next) { + if (d->bd_qmask.qm_enabled) { + printf("bpf_mtap rxqid:%x txqid:%x rxqmask:%x txqmask:%x\n", + m->m_pkthdr.rxqid, m->m_pkthdr.txqid, + d->bd_qmask.qm_rxq_mask[m->m_pkthdr.rxqid], + d->bd_qmask.qm_txq_mask[m->m_pkthdr.txqid]); + + if (m->m_pkthdr.rxqid != (uint32_t)-1 && + !d->bd_qmask.qm_rxq_mask[m->m_pkthdr.rxqid]) + continue; + if (m->m_pkthdr.txqid != (uint32_t)-1 && + !d->bd_qmask.qm_txq_mask[m->m_pkthdr.txqid]) + continue; + } if (BPF_CHECK_DIRECTION(d, m->m_pkthdr.rcvif, bp->bif_ifp)) continue; BPFD_LOCK(d); @@ -1920,6 +2132,13 @@ u_int pktlen, slen; int gottime; +#if 0 + if (m->m_pkthdr.txqid != (uint32_t)-1 && m->m_pkthdr.txqid != PCPU_GET(cpuid)) + printf("txqid:%d cpuid:%d\n", m->m_pkthdr.txqid, PCPU_GET(cpuid)); +#endif + if (m->m_pkthdr.rxqid != (uint32_t)-1 && m->m_pkthdr.rxqid != PCPU_GET(cpuid)) + printf("rxqid:%d cpuid:%d\n", m->m_pkthdr.rxqid, PCPU_GET(cpuid)); + /* Skip outgoing duplicate packets. */ if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) { m->m_flags &= ~M_PROMISC; @@ -1940,6 +2159,19 @@ gottime = BPF_TSTAMP_NONE; BPFIF_LOCK(bp); LIST_FOREACH(d, &bp->bif_dlist, bd_next) { + if (d->bd_qmask.qm_enabled) { + printf("bpf_mtap2 rxqid:%x txqid:%x rxqmask:%x txqmask:%x\n", + m->m_pkthdr.rxqid, m->m_pkthdr.txqid, + d->bd_qmask.qm_rxq_mask[m->m_pkthdr.rxqid], + d->bd_qmask.qm_txq_mask[m->m_pkthdr.txqid]); + + if (m->m_pkthdr.rxqid != (uint32_t)-1 && + !d->bd_qmask.qm_rxq_mask[m->m_pkthdr.rxqid]) + continue; + if (m->m_pkthdr.txqid != (uint32_t)-1 && + !d->bd_qmask.qm_txq_mask[m->m_pkthdr.txqid]) + continue; + } if (BPF_CHECK_DIRECTION(d, m->m_pkthdr.rcvif, bp->bif_ifp)) continue; BPFD_LOCK(d); @@ -2196,6 +2428,12 @@ } if (d->bd_wfilter != NULL) free((caddr_t)d->bd_wfilter, M_BPF); + + if (d->bd_qmask.qm_enabled) { + free(d->bd_qmask.qm_rxq_mask, M_BPF); + free(d->bd_qmask.qm_txq_mask, M_BPF); + } + mtx_destroy(&d->bd_mtx); } ==== //depot/projects/soc2011/mq_bpf/src/sys/net/bpf.h#2 (text+ko) ==== @@ -147,6 +147,18 @@ #define BIOCSETFNR _IOW('B', 130, struct bpf_program) #define BIOCGTSTAMP _IOR('B', 131, u_int) #define BIOCSTSTAMP _IOW('B', 132, u_int) +#define BIOCRXQLEN _IOR('B', 133, int) +#define BIOCTXQLEN _IOR('B', 134, int) +#define BIOCRXQAFFINITY _IOWR('B', 135, u_long) +#define BIOCTXQAFFINITY _IOWR('B', 136, u_long) +#define BIOCENAQMASK _IO('B', 137) +#define BIOCDISQMASK _IO('B', 138) +#define BIOCSTRXQMASK _IOWR('B', 139, uint32_t) +#define BIOCGTRXQMASK _IOR('B', 140, uint32_t) +#define BIOCSTTXQMASK _IOWR('B', 141, uint32_t) +#define BIOCGTTXQMASK _IOR('B', 142, uint32_t) +#define BIOSTOTHERMASK _IOW('B', 143, uint32_t) +#define BIOGTOTHERMASK _IOR('B', 144, uint32_t) /* Obsolete */ #define BIOCGSEESENT BIOCGDIRECTION ==== //depot/projects/soc2011/mq_bpf/src/sys/net/bpfdesc.h#2 (text+ko) ==== @@ -45,6 +45,13 @@ #include <sys/conf.h> #include <net/if.h> +struct bpf_qmask { + boolean_t qm_enabled; + boolean_t * qm_rxq_mask; + boolean_t * qm_txq_mask; + boolean_t qm_other_mask; +}; + /* * Descriptor associated with each open bpf file. */ @@ -99,6 +106,7 @@ u_int64_t bd_wdcount; /* number of packets dropped during a write */ u_int64_t bd_zcopy; /* number of zero copy operations */ u_char bd_compat32; /* 32-bit stream on LP64 system */ + struct bpf_qmask bd_qmask; }; /* Values for bd_state */ ==== //depot/projects/soc2011/mq_bpf/src/sys/net/if_var.h#2 (text+ko) ==== @@ -206,6 +206,9 @@ char *if_description; /* interface description */ void *if_pspare[7]; int if_ispare[4]; + + int if_rxq_num; + int if_txq_num; }; typedef void if_init_f_t(void *); ==== //depot/projects/soc2011/mq_bpf/src/sys/sys/mbuf.h#2 (text+ko) ==== @@ -118,6 +118,8 @@ uint32_t flowid; /* packet's 4-tuple system * flow identifier */ + uint32_t rxqid; + uint32_t txqid; /* variables for hardware checksum */ int csum_flags; /* flags regarding checksum */ int csum_data; /* data field used by csum routines */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105172153.p4HLrZTT025755>