PERFORCE change 193316 for review
Takuya ASADA
syuu at FreeBSD.org
Tue May 17 21:53:36 UTC 2011
http://p4web.freebsd.org/@@193316?ac=10
Change 193316 by syuu at 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 */
More information about the p4-projects
mailing list