svn commit: r368037 - stable/12/tools/tools/netmap
Author: vmaffione Date: Wed Nov 25 21:25:17 2020 New Revision: 368037 URL: https://svnweb.freebsd.org/changeset/base/368037 Log: MFC r367936 netmap: bridge: improve readability Multiple cosmetic changes, plus a fix to a verbose print (indicating wrong net->host/host->net direction). Modified: stable/12/tools/tools/netmap/bridge.c Directory Properties: stable/12/ (props changed) Modified: stable/12/tools/tools/netmap/bridge.c == --- stable/12/tools/tools/netmap/bridge.c Wed Nov 25 21:24:39 2020 (r368036) +++ stable/12/tools/tools/netmap/bridge.c Wed Nov 25 21:25:17 2020 (r368037) @@ -3,19 +3,19 @@ * * BSD license * - * A netmap client to bridge two network interfaces - * (or one interface and the host stack). + * A netmap application to bridge two network interfaces, + * or one interface and the host stack. * * $FreeBSD$ */ +#include +#include #include #include #include -#include #include #include -#include static int verbose = 0; @@ -32,30 +32,39 @@ sigint_h(int sig) /* - * how many packets on this set of queues ? + * How many slots do we (user application) have on this + * set of queues ? */ static int -pkt_queued(struct nmport_d *d, int tx) +rx_slots_avail(struct nmport_d *d) { u_int i, tot = 0; - if (tx) { - for (i = d->first_tx_ring; i <= d->last_tx_ring; i++) { - tot += nm_ring_space(NETMAP_TXRING(d->nifp, i)); - } - } else { - for (i = d->first_rx_ring; i <= d->last_rx_ring; i++) { - tot += nm_ring_space(NETMAP_RXRING(d->nifp, i)); - } + for (i = d->first_rx_ring; i <= d->last_rx_ring; i++) { + tot += nm_ring_space(NETMAP_RXRING(d->nifp, i)); } + return tot; } +static int +tx_slots_avail(struct nmport_d *d) +{ + u_int i, tot = 0; + + for (i = d->first_tx_ring; i <= d->last_tx_ring; i++) { + tot += nm_ring_space(NETMAP_TXRING(d->nifp, i)); + } + + return tot; +} + /* - * move up to 'limit' pkts from rxring to txring swapping buffers. + * Move up to 'limit' pkts from rxring to txring, swapping buffers + * if zerocopy is possible. Otherwise fall back on packet copying. */ static int -process_rings(struct netmap_ring *rxring, struct netmap_ring *txring, +rings_move(struct netmap_ring *rxring, struct netmap_ring *txring, u_int limit, const char *msg) { u_int j, k, m = 0; @@ -63,7 +72,7 @@ process_rings(struct netmap_ring *rxring, struct netma /* print a warning if any of the ring flags is set (e.g. NM_REINIT) */ if (rxring->flags || txring->flags) D("%s rxflags %x txflags %x", - msg, rxring->flags, txring->flags); + msg, rxring->flags, txring->flags); j = rxring->head; /* RX */ k = txring->head; /* TX */ m = nm_ring_space(rxring); @@ -79,16 +88,18 @@ process_rings(struct netmap_ring *rxring, struct netma /* swap packets */ if (ts->buf_idx < 2 || rs->buf_idx < 2) { - RD(5, "wrong index rx[%d] = %d -> tx[%d] = %d", - j, rs->buf_idx, k, ts->buf_idx); + RD(2, "wrong index rxr[%d] = %d -> txr[%d] = %d", + j, rs->buf_idx, k, ts->buf_idx); sleep(2); } /* copy the packet length. */ if (rs->len > rxring->nr_buf_size) { - RD(5, "wrong len %d rx[%d] -> tx[%d]", rs->len, j, k); + RD(2, "%s: invalid len %u, rxr[%d] -> txr[%d]", + msg, rs->len, j, k); rs->len = 0; } else if (verbose > 1) { - D("%s send len %d rx[%d] -> tx[%d]", msg, rs->len, j, k); + D("%s: fwd len %u, rx[%d] -> tx[%d]", + msg, rs->len, j, k); } ts->len = rs->len; if (zerocopy) { @@ -111,24 +122,23 @@ process_rings(struct netmap_ring *rxring, struct netma rxring->head = rxring->cur = j; txring->head = txring->cur = k; if (verbose && m > 0) - D("%s sent %d packets to %p", msg, m, txring); + D("%s fwd %d packets: rxring %u --> txring %u", + msg, m, rxring->ringid, txring->ringid); return (m); } -/* move packts from src to destination */ +/* Move packets from source port to destination port. */ static int -move(struct nmport_d *src, struct nmport_d *dst, u_int limit) +ports_move(struct nmport_d *src, struct nmport_d *dst, u_int limit, + const char *msg) { struct netmap_ring *txring, *rxring; u_int m = 0, si = src->first_rx_ring, di =
svn commit: r368036 - stable/12/usr.sbin/valectl
Author: vmaffione Date: Wed Nov 25 21:24:39 2020 New Revision: 368036 URL: https://svnweb.freebsd.org/changeset/base/368036 Log: MFC r367935 netmap: valectl: switch to libnetmap Use the newer libnetmap (included in base) rather than the older nm_open()/nm_close() defined in netmap_user.h Modified: stable/12/usr.sbin/valectl/Makefile stable/12/usr.sbin/valectl/valectl.c Directory Properties: stable/12/ (props changed) Modified: stable/12/usr.sbin/valectl/Makefile == --- stable/12/usr.sbin/valectl/Makefile Wed Nov 25 21:23:58 2020 (r368035) +++ stable/12/usr.sbin/valectl/Makefile Wed Nov 25 21:24:39 2020 (r368036) @@ -5,4 +5,6 @@ MAN=valectl.8 WARNS?=3 +LIBADD=netmap + .include Modified: stable/12/usr.sbin/valectl/valectl.c == --- stable/12/usr.sbin/valectl/valectl.cWed Nov 25 21:23:58 2020 (r368035) +++ stable/12/usr.sbin/valectl/valectl.cWed Nov 25 21:24:39 2020 (r368036) @@ -25,9 +25,8 @@ /* $FreeBSD$ */ -#define NETMAP_WITH_LIBS -#include -#include +#define LIBNETMAP_NOTHREADSAFE +#include #include #include @@ -42,14 +41,58 @@ #include /* basename */ #include /* atoi, free */ +int verbose; + +struct args { + const char *name; + const char *config; + const char *mem_id; + + uint16_t nr_reqtype; + uint32_t nr_mode; +}; + static void -parse_nmr_config(const char* conf, struct nmreq *nmr) +dump_port_info(struct nmreq_port_info_get *v) { + printf("memsize:%"PRIu64"\n", v->nr_memsize); + printf("tx_slots: %"PRIu32"\n", v->nr_tx_slots); + printf("rx_slots: %"PRIu32"\n", v->nr_rx_slots); + printf("tx_rings: %"PRIu16"\n", v->nr_tx_rings); + printf("rx_rings%"PRIu16"\n", v->nr_rx_rings); + printf("mem_id: %"PRIu16"\n", v->nr_mem_id); +} + +static void +dump_newif(struct nmreq_vale_newif *v) +{ + printf("tx_slots: %"PRIu32"\n", v->nr_tx_slots); + printf("rx_slots: %"PRIu32"\n", v->nr_rx_slots); + printf("tx_rings: %"PRIu16"\n", v->nr_tx_rings); + printf("rx_ring:%"PRIu16"\n", v->nr_rx_rings); + printf("mem_id: %"PRIu16"\n", v->nr_mem_id); +} + +static void +dump_vale_list(struct nmreq_vale_list *v) +{ + printf("bridge_idx: %"PRIu16"\n", v->nr_bridge_idx); + printf("port_idx: %"PRIu16"\n", v->nr_port_idx); +} + + +static void +parse_ring_config(const char* conf, + uint32_t *nr_tx_slots, + uint32_t *nr_rx_slots, + uint16_t *nr_tx_rings, + uint16_t *nr_rx_rings) +{ char *w, *tok; int i, v; - nmr->nr_tx_rings = nmr->nr_rx_rings = 0; - nmr->nr_tx_slots = nmr->nr_rx_slots = 0; + *nr_tx_rings = *nr_rx_rings = 0; + *nr_tx_slots = *nr_rx_slots = 0; if (conf == NULL || ! *conf) return; w = strdup(conf); @@ -57,137 +100,235 @@ parse_nmr_config(const char* conf, struct nmreq *nmr) v = atoi(tok); switch (i) { case 0: - nmr->nr_tx_slots = nmr->nr_rx_slots = v; + *nr_tx_slots = *nr_rx_slots = v; break; case 1: - nmr->nr_rx_slots = v; + *nr_rx_slots = v; break; case 2: - nmr->nr_tx_rings = nmr->nr_rx_rings = v; + *nr_tx_rings = *nr_rx_rings = v; break; case 3: - nmr->nr_rx_rings = v; + *nr_rx_rings = v; break; default: - D("ignored config: %s", tok); + fprintf(stderr, "ignored config: %s", tok); break; } } - D("txr %d txd %d rxr %d rxd %d", - nmr->nr_tx_rings, nmr->nr_tx_slots, - nmr->nr_rx_rings, nmr->nr_rx_slots); + ND("txr %d txd %d rxr %d rxd %d", + *nr_tx_rings, *nr_tx_slots, + *nr_rx_rings, *nr_rx_slots); free(w); } static int -bdg_ctl(const char *name, int nr_cmd, int nr_arg, char *nmr_config, int nr_arg2) +parse_poll_config(const char *conf, struct nmreq_vale_polling *v) { - struct nmreq nmr; - int error = 0; - int fd = open("/dev/netmap", O_RDWR); + char *w, *tok; + int i, p; - if (fd == -1) { - D("Unable to open /dev/netmap"); + if (conf == NULL || ! *conf) { + fprintf(stderr, "invalid null/empty config\n"); return -1; } + w = strdup(conf); + for (i = 0, tok = strtok(w, ","); tok; i++, tok =
svn commit: r368035 - stable/12/tools/tools/netmap
Author: vmaffione Date: Wed Nov 25 21:23:58 2020 New Revision: 368035 URL: https://svnweb.freebsd.org/changeset/base/368035 Log: MFC r367934 netmap: nmreplay: switch to libnetmap Use the newer libnetmap (included in base) rather than the older nm_open()/nm_close() defined in netmap_user.h Modified: stable/12/tools/tools/netmap/nmreplay.c Directory Properties: stable/12/ (props changed) Modified: stable/12/tools/tools/netmap/nmreplay.c == --- stable/12/tools/tools/netmap/nmreplay.c Wed Nov 25 21:23:13 2020 (r368034) +++ stable/12/tools/tools/netmap/nmreplay.c Wed Nov 25 21:23:58 2020 (r368035) @@ -106,12 +106,27 @@ #define DDD(_fmt, ...) ED("--DDD-- " _fmt, ##__VA_ARGS__) #define _GNU_SOURCE// for CPU_SET() etc +#include +#include +#include +#include /* log, exp etc. */ +#include +#ifdef __FreeBSD__ +#include /* pthread w/ affinity */ +#include /* cpu_set */ +#endif /* __FreeBSD__ */ +#include #include -#define NETMAP_WITH_LIBS -#include +#include +#include /* memcpy */ +#include +#include +#include #include +#include // setpriority +#include +#include - /* * * A packet in the queue is q_pkt plus the payload. @@ -242,15 +257,6 @@ static struct nm_pcap_file *readpcap(const char *fn); static void destroy_pcap(struct nm_pcap_file *file); -#include -#include -#include -#include -#include -#include /* memcpy */ - -#include - #define NS_SCALE 10UL /* nanoseconds in 1s */ static void destroy_pcap(struct nm_pcap_file *pf) @@ -435,18 +441,6 @@ static int verbose = 0; static int do_abort = 0; -#include -#include -#include -#include - -#include // setpriority - -#ifdef __FreeBSD__ -#include /* pthread w/ affinity */ -#include /* cpu_set */ -#endif /* __FreeBSD__ */ - #ifdef linux #define cpuset_tcpu_set_t #endif @@ -566,7 +560,7 @@ struct _qs { /* shared queue */ struct nm_pcap_file *pcap; /* the pcap struct */ /* parameters for reading from the netmap port */ - struct nm_desc *src_port; /* netmap descriptor */ + struct nmport_d *src_port; /* netmap descriptor */ const char *prod_ifname;/* interface name or pcap file */ struct netmap_ring *rxring; /* current ring being handled */ uint32_tsi; /* ring index */ @@ -640,8 +634,8 @@ struct pipe_args { int cons_core; /* core for cons() */ int prod_core; /* core for prod() */ - struct nm_desc *pa; /* netmap descriptor */ - struct nm_desc *pb; + struct nmport_d *pa;/* netmap descriptor */ + struct nmport_d *pb; struct _qs q; }; @@ -843,7 +837,7 @@ fail: if (q->buf != NULL) { free(q->buf); } -nm_close(pa->pb); +nmport_close(pa->pb); return (NULL); } @@ -893,7 +887,7 @@ cons(void *_pa) continue; } /* XXX copy is inefficient but simple */ - if (nm_inject(pa->pb, (char *)(p + 1), p->pktlen) == 0) { + if (nmport_inject(pa->pb, (char *)(p + 1), p->pktlen) == 0) { RD(1, "inject failed len %d now %ld tx %ld h %ld t %ld next %ld", (int)p->pktlen, (u_long)q->cons_now, (u_long)p->pt_tx, (u_long)q->_head, (u_long)q->_tail, (u_long)p->next); @@ -939,7 +933,7 @@ nmreplay_main(void *_a) pcap_prod((void*)a); destroy_pcap(q->pcap); q->pcap = NULL; -a->pb = nm_open(q->cons_ifname, NULL, 0, NULL); +a->pb = nmport_open(q->cons_ifname); if (a->pb == NULL) { EEE("cannot open netmap on %s", q->cons_ifname); do_abort = 1; // XXX any better way ? @@ -1372,7 +1366,6 @@ parse_bw(const char *arg) * 24 useful random bits. */ -#include /* log, exp etc. */ static inline uint64_t my_random24(void) /* 24 useful bits */ { ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r368034 - stable/12/tools/tools/netmap
Author: vmaffione Date: Wed Nov 25 21:23:13 2020 New Revision: 368034 URL: https://svnweb.freebsd.org/changeset/base/368034 Log: MFC r367933 netmap: lb: switch to libnetmap Use the newer libnetmap (included in base) rather than the older nm_open()/nm_close() defined in netmap_user.h Modified: stable/12/tools/tools/netmap/lb.c stable/12/tools/tools/netmap/pkt_hash.c Directory Properties: stable/12/ (props changed) Modified: stable/12/tools/tools/netmap/lb.c == --- stable/12/tools/tools/netmap/lb.c Wed Nov 25 21:22:16 2020 (r368033) +++ stable/12/tools/tools/netmap/lb.c Wed Nov 25 21:23:13 2020 (r368034) @@ -23,21 +23,22 @@ * SUCH DAMAGE. */ /* $FreeBSD$ */ -#include -#include #include -#include +#include #include +#include +#include /* htonl */ +#include +#include +#include +#include +#include +#include #include - -#define NETMAP_WITH_LIBS -#include +#include #include +#include -#include /* htonl */ - -#include - #include "pkt_hash.h" #include "ctrs.h" @@ -86,12 +87,12 @@ struct compact_ipv6_hdr { #define DEF_BATCH 2048 #define DEF_WAIT_LINK 2 #define DEF_STATS_INT 600 -#define BUF_REVOKE 100 +#define BUF_REVOKE 150 #define STAT_MSG_MAXSIZE 1024 static struct { - char ifname[MAX_IFNAMELEN]; - char base_name[MAX_IFNAMELEN]; + char ifname[MAX_IFNAMELEN + 1]; + char base_name[MAX_IFNAMELEN + 1]; int netmap_fd; uint16_t output_rings; uint16_t num_groups; @@ -173,7 +174,7 @@ struct port_des { unsigned int last_sync; uint32_t last_tail; struct overflow_queue *oq; - struct nm_desc *nmd; + struct nmport_d *nmd; struct netmap_ring *ring; struct group_des *group; }; @@ -375,7 +376,7 @@ free_buffers(void) D("added %d buffers to netmap free list", tot); for (i = 0; i < glob_arg.output_rings + 1; ++i) { - nm_close(ports[i].nmd); + nmport_close(ports[i].nmd); } } @@ -480,6 +481,28 @@ init_groups(void) g->last = 1; } + +/* To support packets that span multiple slots (NS_MOREFRAG) we + * need to make sure of the following: + * + * - all fragments of the same packet must go to the same output pipe + * - when dropping, all fragments of the same packet must be dropped + * + * For the former point we remember and reuse the last hash computed + * in each input ring, and only update it when NS_MOREFRAG was not + * set in the last received slot (this marks the start of a new packet). + * + * For the latter point, we only update the output ring head pointer + * when an entire packet has been forwarded. We keep a shadow_head + * pointer to know where to put the next partial fragment and, + * when the need to drop arises, we roll it back to head. + */ +struct morefrag { + uint16_t last_flag; /* for intput rings */ + uint32_t last_hash; /* for input rings */ + uint32_t shadow_head; /* for output rings */ +}; + /* push the packet described by slot rs to the group g. * This may cause other buffers to be pushed down the * chain headed by g. @@ -493,21 +516,28 @@ forward_packet(struct group_des *g, struct netmap_slot struct port_des *port = >ports[output_port]; struct netmap_ring *ring = port->ring; struct overflow_queue *q = port->oq; + struct morefrag *mf = (struct morefrag *)ring->sem; + uint16_t curmf = rs->flags & NS_MOREFRAG; /* Move the packet to the output pipe, unless there is * either no space left on the ring, or there is some * packet still in the overflow queue (since those must * take precedence over the new one) */ - if (ring->head != ring->tail && (q == NULL || oq_empty(q))) { - struct netmap_slot *ts = >slot[ring->head]; + if (mf->shadow_head != ring->tail && (q == NULL || oq_empty(q))) { + struct netmap_slot *ts = >slot[mf->shadow_head]; struct netmap_slot old_slot = *ts; ts->buf_idx = rs->buf_idx; ts->len = rs->len; - ts->flags |= NS_BUF_CHANGED; + ts->flags = rs->flags | NS_BUF_CHANGED; ts->ptr = rs->ptr; - ring->head = nm_ring_next(ring, ring->head); + mf->shadow_head = nm_ring_next(ring, mf->shadow_head); + if (!curmf) { + ring->head = mf->shadow_head; + } + ND("curmf %2x ts->flags %2x shadow_head %3u head %3u tail %3u", + curmf, ts->flags, mf->shadow_head, ring->head, ring->tail); port->ctr.bytes += rs->len; port->ctr.pkts++; forwarded++; @@ -516,9 +546,20 @@ forward_packet(struct group_des *g, struct netmap_slot /* use
svn commit: r368033 - stable/12/tools/tools/netmap
Author: vmaffione Date: Wed Nov 25 21:22:16 2020 New Revision: 368033 URL: https://svnweb.freebsd.org/changeset/base/368033 Log: MFC r367932 netmap: pkt-gen: switch to libnetmap Use the newer libnetmap (included in base) rather than the older nm_open()/nm_close() defined in netmap_user.h Modified: stable/12/tools/tools/netmap/pkt-gen.c Directory Properties: stable/12/ (props changed) Modified: stable/12/tools/tools/netmap/pkt-gen.c == --- stable/12/tools/tools/netmap/pkt-gen.c Wed Nov 25 21:20:55 2020 (r368032) +++ stable/12/tools/tools/netmap/pkt-gen.c Wed Nov 25 21:22:16 2020 (r368033) @@ -38,36 +38,40 @@ */ #define _GNU_SOURCE/* for CPU_SET() */ -#include -#define NETMAP_WITH_LIBS -#include - -#include // isprint() -#include // sysconf() -#include #include /* ntohs */ -#ifndef _WIN32 -#include /* sysctl */ -#endif +#include +#include // isprint() +#include +#include #include/* getifaddrs */ +#include +#include #include #include #include -#include #include +#include +#ifndef NO_PCAP +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(_WIN32) && !defined(linux) +#include /* sysctl */ +#endif +#include +#include // sysconf() #ifdef linux #define IPV6_VERSION 0x60 #define IPV6_DEFHLIM 64 #endif -#include -#include -#include - -#ifndef NO_PCAP -#include -#endif - #include "ctrs.h" static void usage(int); @@ -236,7 +240,8 @@ struct mac_range { }; /* ifname can be netmap:foo- */ -#define MAX_IFNAMELEN 64 /* our buffer for ifname */ +#define MAX_IFNAMELEN 512 /* our buffer for ifname */ +//#define MAX_PKTSIZE 1536 #define MAX_PKTSIZEMAX_BODYSIZE/* XXX: + IP_HDR + ETH_HDR */ /* compact timestamp to fit into 60 byte packet. (enough to obtain RTT) */ @@ -288,7 +293,8 @@ struct glob_arg { int affinity; int main_fd; - struct nm_desc *nmd; + struct nmport_d *nmd; + uint32_t orig_mode; int report_interval;/* milliseconds between prints */ void *(*td_body)(void *); int td_type; @@ -322,7 +328,7 @@ struct targ { int completed; int cancel; int fd; - struct nm_desc *nmd; + struct nmport_d *nmd; /* these ought to be volatile, but they are * only sampled and errors should not accumulate */ @@ -515,17 +521,21 @@ extract_mac_range(struct mac_range *r) static int get_if_mtu(const struct glob_arg *g) { - char ifname[IFNAMSIZ]; struct ifreq ifreq; int s, ret; + const char *ifname = g->nmd->hdr.nr_name; + size_t len; - if (!strncmp(g->ifname, "netmap:", 7) && !strchr(g->ifname, '{') - && !strchr(g->ifname, '}')) { - /* Parse the interface name and ask the kernel for the -* MTU value. */ - strncpy(ifname, g->ifname+7, IFNAMSIZ-1); - ifname[strcspn(ifname, "-*^{}/@")] = '\0'; + if (!strncmp(g->ifname, "netmap:", 7) && !strchr(ifname, '{') + && !strchr(ifname, '}')) { + len = strlen(ifname); + + if (len > IFNAMSIZ) { + D("'%s' too long, cannot ask for MTU", ifname); + return -1; + } + s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { D("socket() failed: %s", strerror(errno)); @@ -533,13 +543,15 @@ get_if_mtu(const struct glob_arg *g) } memset(, 0, sizeof(ifreq)); - strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); + memcpy(ifreq.ifr_name, ifname, len); ret = ioctl(s, SIOCGIFMTU, ); if (ret) { D("ioctl(SIOCGIFMTU) failed: %s", strerror(errno)); } + close(s); + return ifreq.ifr_mtu; } @@ -620,7 +632,7 @@ system_ncpus(void) * and #rx-rings. */ static int -parse_nmr_config(const char* conf, struct nmreq *nmr) +parse_nmr_config(const char* conf, struct nmreq_register *nmr) { char *w, *tok; int i, v; @@ -654,9 +666,7 @@ parse_nmr_config(const char* conf, struct nmreq *nmr) nmr->nr_tx_rings, nmr->nr_tx_slots, nmr->nr_rx_rings, nmr->nr_rx_slots); free(w); - return (nmr->nr_tx_rings || nmr->nr_tx_slots || - nmr->nr_rx_rings || nmr->nr_rx_slots) ? - NM_OPEN_RING_CFG : 0; + return 0; } @@ -1108,20 +1118,22 @@ initialize_packet(struct targ *targ) static void get_vnet_hdr_len(struct glob_arg *g) { - struct nmreq req; + struct nmreq_header hdr; + struct nmreq_port_hdr ph; int err; - memset(,
svn commit: r368032 - stable/12/tools/tools/netmap
Author: vmaffione Date: Wed Nov 25 21:20:55 2020 New Revision: 368032 URL: https://svnweb.freebsd.org/changeset/base/368032 Log: MFC r367931 netmap: bridge: switch to libnetmap Use the newer libnetmap (included in base) rather than the older nm_open()/nm_close() defined in netmap_user.h Modified: stable/12/tools/tools/netmap/Makefile stable/12/tools/tools/netmap/bridge.c Directory Properties: stable/12/ (props changed) Modified: stable/12/tools/tools/netmap/Makefile == --- stable/12/tools/tools/netmap/Makefile Wed Nov 25 20:58:01 2020 (r368031) +++ stable/12/tools/tools/netmap/Makefile Wed Nov 25 21:20:55 2020 (r368032) @@ -11,7 +11,7 @@ MAN= .include .include -LDFLAGS += -lpthread +LDFLAGS += -lpthread -lnetmap .ifdef WITHOUT_PCAP CFLAGS += -DNO_PCAP .else @@ -27,7 +27,7 @@ pkt-gen: pkt-gen.o $(CC) $(CFLAGS) -o pkt-gen pkt-gen.o $(LDFLAGS) bridge: bridge.o - $(CC) $(CFLAGS) -o bridge bridge.o + $(CC) $(CFLAGS) -o bridge bridge.o $(LDFLAGS) nmreplay: nmreplay.o $(CC) $(CFLAGS) -o nmreplay nmreplay.o $(LDFLAGS) Modified: stable/12/tools/tools/netmap/bridge.c == --- stable/12/tools/tools/netmap/bridge.c Wed Nov 25 20:58:01 2020 (r368031) +++ stable/12/tools/tools/netmap/bridge.c Wed Nov 25 21:20:55 2020 (r368032) @@ -10,9 +10,12 @@ */ #include -#define NETMAP_WITH_LIBS -#include #include +#include +#include +#include +#include +#include static int verbose = 0; @@ -32,7 +35,7 @@ sigint_h(int sig) * how many packets on this set of queues ? */ static int -pkt_queued(struct nm_desc *d, int tx) +pkt_queued(struct nmport_d *d, int tx) { u_int i, tot = 0; @@ -61,8 +64,8 @@ process_rings(struct netmap_ring *rxring, struct netma if (rxring->flags || txring->flags) D("%s rxflags %x txflags %x", msg, rxring->flags, txring->flags); - j = rxring->cur; /* RX */ - k = txring->cur; /* TX */ + j = rxring->head; /* RX */ + k = txring->head; /* TX */ m = nm_ring_space(rxring); if (m < limit) limit = m; @@ -115,11 +118,11 @@ process_rings(struct netmap_ring *rxring, struct netma /* move packts from src to destination */ static int -move(struct nm_desc *src, struct nm_desc *dst, u_int limit) +move(struct nmport_d *src, struct nmport_d *dst, u_int limit) { struct netmap_ring *txring, *rxring; u_int m = 0, si = src->first_rx_ring, di = dst->first_tx_ring; - const char *msg = (src->req.nr_flags == NR_REG_SW) ? + const char *msg = (src->reg.nr_flags == NR_REG_SW) ? "host->net" : "net->host"; while (si <= src->last_rx_ring && di <= dst->last_tx_ring) { @@ -175,7 +178,7 @@ main(int argc, char **argv) struct pollfd pollfd[2]; int ch; u_int burst = 1024, wait_link = 4; - struct nm_desc *pa = NULL, *pb = NULL; + struct nmport_d *pa = NULL, *pb = NULL; char *ifa = NULL, *ifb = NULL; char ifabuf[64] = { 0 }; int loopback = 0; @@ -252,16 +255,16 @@ main(int argc, char **argv) } else { /* two different interfaces. Take all rings on if1 */ } - pa = nm_open(ifa, NULL, 0, NULL); + pa = nmport_open(ifa); if (pa == NULL) { D("cannot open %s", ifa); return (1); } /* try to reuse the mmap() of the first interface, if possible */ - pb = nm_open(ifb, NULL, NM_OPEN_NO_MMAP, pa); + pb = nmport_open(ifb); if (pb == NULL) { D("cannot open %s", ifb); - nm_close(pa); + nmport_close(pa); return (1); } zerocopy = zerocopy && (pa->mem == pb->mem); @@ -275,8 +278,8 @@ main(int argc, char **argv) D("Wait %d secs for link to come up...", wait_link); sleep(wait_link); D("Ready to go, %s 0x%x/%d <-> %s 0x%x/%d.", - pa->req.nr_name, pa->first_rx_ring, pa->req.nr_rx_rings, - pb->req.nr_name, pb->first_rx_ring, pb->req.nr_rx_rings); + pa->hdr.nr_name, pa->first_rx_ring, pa->reg.nr_rx_rings, + pb->hdr.nr_name, pb->first_rx_ring, pb->reg.nr_rx_rings); /* main loop */ signal(SIGINT, sigint_h); @@ -320,12 +323,12 @@ main(int argc, char **argv) pollfd[0].events, pollfd[0].revents, pkt_queued(pa, 0), - NETMAP_RXRING(pa->nifp, pa->cur_rx_ring)->cur, + NETMAP_RXRING(pa->nifp, pa->cur_rx_ring)->head, pkt_queued(pa, 1), pollfd[1].events,
svn commit: r367996 - stable/12/tools/tools/netmap
Author: vmaffione Date: Tue Nov 24 19:55:01 2020 New Revision: 367996 URL: https://svnweb.freebsd.org/changeset/base/367996 Log: MFC r367920, r367921 netmap: bridge: update man page with more information Update the man page to describe how it is necessary to enable promiscuous mode and/or disable offloads. Modified: stable/12/tools/tools/netmap/bridge.8 stable/12/tools/tools/netmap/pkt-gen.8 Directory Properties: stable/12/ (props changed) Modified: stable/12/tools/tools/netmap/bridge.8 == --- stable/12/tools/tools/netmap/bridge.8 Tue Nov 24 17:53:13 2020 (r367995) +++ stable/12/tools/tools/netmap/bridge.8 Tue Nov 24 19:55:01 2020 (r367996) @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 28, 2018 +.Dd November 21, 2020 .Dt BRIDGE 8 .Os .Sh NAME @@ -49,6 +49,20 @@ forwards packets without copying the packets payload ( explicitly prevented by the .Fl c flag. +.Pp +When bridging two physical ports, it is necessary that both NICS are in +promiscuous mode, otherwise unicast traffic directed to other hosts will +be dropped by the hardware, and bridging will not work. +.Pp +When bridging the hardware rings of a physical port with the corresponding +host rings, it is necessary to turn off the offloads, because netmap does +not prepare the NIC rings with offload information. +Example: +.Bd -literal -offset indent +ifconfig em0 -rxcsum -txcsum -tso4 -tso6 -lro +.Ed +.Pp +Available options: .Bl -tag -width Ds .It Fl i Ar port Name of the netmap port. @@ -71,8 +85,8 @@ Disable zero-copy mode. .El .Sh SEE ALSO .Xr netmap 4 , -.Xr pkt-gen 8 , -.Xr lb 8 +.Xr lb 8 , +.Xr pkt-gen 8 .Sh AUTHORS .An -nosplit .Nm Modified: stable/12/tools/tools/netmap/pkt-gen.8 == --- stable/12/tools/tools/netmap/pkt-gen.8 Tue Nov 24 17:53:13 2020 (r367995) +++ stable/12/tools/tools/netmap/pkt-gen.8 Tue Nov 24 19:55:01 2020 (r367996) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 3, 2020 +.Dd November 21, 2020 .Dt PKT-GEN 8 .Os .Sh NAME @@ -287,7 +287,7 @@ Send a stream of fake DNS packets between two hosts wi length of 128 bytes. You must set the destination MAC address for packets to be received by the target host. -.Bd -literal -offset intent +.Bd -literal -offset indent pkt-gen -i netmap:ncxl0 -f tx -s 172.16.0.1:53 -d 172.16.1.3:53 -D 00:07:43:29:2a:e0 .Ed .Sh SEE ALSO ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r367936 - head/tools/tools/netmap
Author: vmaffione Date: Sun Nov 22 13:39:21 2020 New Revision: 367936 URL: https://svnweb.freebsd.org/changeset/base/367936 Log: netmap: bridge: improve readability Multiple cosmetic changes, plus a fix to a verbose print (indicating wrong net->host/host->net direction). MFC after:3 days Modified: head/tools/tools/netmap/bridge.c Modified: head/tools/tools/netmap/bridge.c == --- head/tools/tools/netmap/bridge.cSun Nov 22 10:02:56 2020 (r367935) +++ head/tools/tools/netmap/bridge.cSun Nov 22 13:39:21 2020 (r367936) @@ -3,19 +3,19 @@ * * BSD license * - * A netmap client to bridge two network interfaces - * (or one interface and the host stack). + * A netmap application to bridge two network interfaces, + * or one interface and the host stack. * * $FreeBSD$ */ +#include +#include #include #include #include -#include #include #include -#include static int verbose = 0; @@ -32,30 +32,39 @@ sigint_h(int sig) /* - * how many packets on this set of queues ? + * How many slots do we (user application) have on this + * set of queues ? */ static int -pkt_queued(struct nmport_d *d, int tx) +rx_slots_avail(struct nmport_d *d) { u_int i, tot = 0; - if (tx) { - for (i = d->first_tx_ring; i <= d->last_tx_ring; i++) { - tot += nm_ring_space(NETMAP_TXRING(d->nifp, i)); - } - } else { - for (i = d->first_rx_ring; i <= d->last_rx_ring; i++) { - tot += nm_ring_space(NETMAP_RXRING(d->nifp, i)); - } + for (i = d->first_rx_ring; i <= d->last_rx_ring; i++) { + tot += nm_ring_space(NETMAP_RXRING(d->nifp, i)); } + return tot; } +static int +tx_slots_avail(struct nmport_d *d) +{ + u_int i, tot = 0; + + for (i = d->first_tx_ring; i <= d->last_tx_ring; i++) { + tot += nm_ring_space(NETMAP_TXRING(d->nifp, i)); + } + + return tot; +} + /* - * move up to 'limit' pkts from rxring to txring swapping buffers. + * Move up to 'limit' pkts from rxring to txring, swapping buffers + * if zerocopy is possible. Otherwise fall back on packet copying. */ static int -process_rings(struct netmap_ring *rxring, struct netmap_ring *txring, +rings_move(struct netmap_ring *rxring, struct netmap_ring *txring, u_int limit, const char *msg) { u_int j, k, m = 0; @@ -63,7 +72,7 @@ process_rings(struct netmap_ring *rxring, struct netma /* print a warning if any of the ring flags is set (e.g. NM_REINIT) */ if (rxring->flags || txring->flags) D("%s rxflags %x txflags %x", - msg, rxring->flags, txring->flags); + msg, rxring->flags, txring->flags); j = rxring->head; /* RX */ k = txring->head; /* TX */ m = nm_ring_space(rxring); @@ -79,16 +88,18 @@ process_rings(struct netmap_ring *rxring, struct netma /* swap packets */ if (ts->buf_idx < 2 || rs->buf_idx < 2) { - RD(5, "wrong index rx[%d] = %d -> tx[%d] = %d", - j, rs->buf_idx, k, ts->buf_idx); + RD(2, "wrong index rxr[%d] = %d -> txr[%d] = %d", + j, rs->buf_idx, k, ts->buf_idx); sleep(2); } /* copy the packet length. */ if (rs->len > rxring->nr_buf_size) { - RD(5, "wrong len %d rx[%d] -> tx[%d]", rs->len, j, k); + RD(2, "%s: invalid len %u, rxr[%d] -> txr[%d]", + msg, rs->len, j, k); rs->len = 0; } else if (verbose > 1) { - D("%s send len %d rx[%d] -> tx[%d]", msg, rs->len, j, k); + D("%s: fwd len %u, rx[%d] -> tx[%d]", + msg, rs->len, j, k); } ts->len = rs->len; if (zerocopy) { @@ -111,24 +122,23 @@ process_rings(struct netmap_ring *rxring, struct netma rxring->head = rxring->cur = j; txring->head = txring->cur = k; if (verbose && m > 0) - D("%s sent %d packets to %p", msg, m, txring); + D("%s fwd %d packets: rxring %u --> txring %u", + msg, m, rxring->ringid, txring->ringid); return (m); } -/* move packts from src to destination */ +/* Move packets from source port to destination port. */ static int -move(struct nmport_d *src, struct nmport_d *dst, u_int limit) +ports_move(struct nmport_d *src, struct nmport_d *dst, u_int limit, + const char *msg) { struct netmap_ring *txring, *rxring; u_int m = 0, si = src->first_rx_ring, di = dst->first_tx_ring; - const char *msg = (src->reg.nr_flags ==
svn commit: r367935 - head/usr.sbin/valectl
Author: vmaffione Date: Sun Nov 22 10:02:56 2020 New Revision: 367935 URL: https://svnweb.freebsd.org/changeset/base/367935 Log: netmap: valectl: switch to libnetmap Use the newer libnetmap (included in base) rather than the older nm_open()/nm_close() defined in netmap_user.h MFC after: 3 days Modified: head/usr.sbin/valectl/Makefile head/usr.sbin/valectl/valectl.c Modified: head/usr.sbin/valectl/Makefile == --- head/usr.sbin/valectl/Makefile Sun Nov 22 09:38:01 2020 (r367934) +++ head/usr.sbin/valectl/Makefile Sun Nov 22 10:02:56 2020 (r367935) @@ -5,4 +5,6 @@ MAN=valectl.8 WARNS?=3 +LIBADD=netmap + .include Modified: head/usr.sbin/valectl/valectl.c == --- head/usr.sbin/valectl/valectl.c Sun Nov 22 09:38:01 2020 (r367934) +++ head/usr.sbin/valectl/valectl.c Sun Nov 22 10:02:56 2020 (r367935) @@ -25,9 +25,8 @@ /* $FreeBSD$ */ -#define NETMAP_WITH_LIBS -#include -#include +#define LIBNETMAP_NOTHREADSAFE +#include #include #include @@ -42,14 +41,58 @@ #include /* basename */ #include /* atoi, free */ +int verbose; + +struct args { + const char *name; + const char *config; + const char *mem_id; + + uint16_t nr_reqtype; + uint32_t nr_mode; +}; + static void -parse_nmr_config(const char* conf, struct nmreq *nmr) +dump_port_info(struct nmreq_port_info_get *v) { + printf("memsize:%"PRIu64"\n", v->nr_memsize); + printf("tx_slots: %"PRIu32"\n", v->nr_tx_slots); + printf("rx_slots: %"PRIu32"\n", v->nr_rx_slots); + printf("tx_rings: %"PRIu16"\n", v->nr_tx_rings); + printf("rx_rings%"PRIu16"\n", v->nr_rx_rings); + printf("mem_id: %"PRIu16"\n", v->nr_mem_id); +} + +static void +dump_newif(struct nmreq_vale_newif *v) +{ + printf("tx_slots: %"PRIu32"\n", v->nr_tx_slots); + printf("rx_slots: %"PRIu32"\n", v->nr_rx_slots); + printf("tx_rings: %"PRIu16"\n", v->nr_tx_rings); + printf("rx_ring:%"PRIu16"\n", v->nr_rx_rings); + printf("mem_id: %"PRIu16"\n", v->nr_mem_id); +} + +static void +dump_vale_list(struct nmreq_vale_list *v) +{ + printf("bridge_idx: %"PRIu16"\n", v->nr_bridge_idx); + printf("port_idx: %"PRIu16"\n", v->nr_port_idx); +} + + +static void +parse_ring_config(const char* conf, + uint32_t *nr_tx_slots, + uint32_t *nr_rx_slots, + uint16_t *nr_tx_rings, + uint16_t *nr_rx_rings) +{ char *w, *tok; int i, v; - nmr->nr_tx_rings = nmr->nr_rx_rings = 0; - nmr->nr_tx_slots = nmr->nr_rx_slots = 0; + *nr_tx_rings = *nr_rx_rings = 0; + *nr_tx_slots = *nr_rx_slots = 0; if (conf == NULL || ! *conf) return; w = strdup(conf); @@ -57,137 +100,235 @@ parse_nmr_config(const char* conf, struct nmreq *nmr) v = atoi(tok); switch (i) { case 0: - nmr->nr_tx_slots = nmr->nr_rx_slots = v; + *nr_tx_slots = *nr_rx_slots = v; break; case 1: - nmr->nr_rx_slots = v; + *nr_rx_slots = v; break; case 2: - nmr->nr_tx_rings = nmr->nr_rx_rings = v; + *nr_tx_rings = *nr_rx_rings = v; break; case 3: - nmr->nr_rx_rings = v; + *nr_rx_rings = v; break; default: - D("ignored config: %s", tok); + fprintf(stderr, "ignored config: %s", tok); break; } } - D("txr %d txd %d rxr %d rxd %d", - nmr->nr_tx_rings, nmr->nr_tx_slots, - nmr->nr_rx_rings, nmr->nr_rx_slots); + ND("txr %d txd %d rxr %d rxd %d", + *nr_tx_rings, *nr_tx_slots, + *nr_rx_rings, *nr_rx_slots); free(w); } static int -bdg_ctl(const char *name, int nr_cmd, int nr_arg, char *nmr_config, int nr_arg2) +parse_poll_config(const char *conf, struct nmreq_vale_polling *v) { - struct nmreq nmr; - int error = 0; - int fd = open("/dev/netmap", O_RDWR); + char *w, *tok; + int i, p; - if (fd == -1) { - D("Unable to open /dev/netmap"); + if (conf == NULL || ! *conf) { + fprintf(stderr, "invalid null/empty config\n"); return -1; } + w = strdup(conf); + for (i = 0, tok = strtok(w, ","); tok; i++, tok = strtok(NULL, ",")) { + p = atoi(tok); + switch (i)
svn commit: r367934 - head/tools/tools/netmap
Author: vmaffione Date: Sun Nov 22 09:38:01 2020 New Revision: 367934 URL: https://svnweb.freebsd.org/changeset/base/367934 Log: netmap: nmreplay: switch to libnetmap Use the newer libnetmap (included in base) rather than the older nm_open()/nm_close() defined in netmap_user.h MFC after: 3 days Modified: head/tools/tools/netmap/nmreplay.c Modified: head/tools/tools/netmap/nmreplay.c == --- head/tools/tools/netmap/nmreplay.c Sun Nov 22 09:28:50 2020 (r367933) +++ head/tools/tools/netmap/nmreplay.c Sun Nov 22 09:38:01 2020 (r367934) @@ -106,12 +106,27 @@ #define DDD(_fmt, ...) ED("--DDD-- " _fmt, ##__VA_ARGS__) #define _GNU_SOURCE// for CPU_SET() etc +#include +#include +#include +#include /* log, exp etc. */ +#include +#ifdef __FreeBSD__ +#include /* pthread w/ affinity */ +#include /* cpu_set */ +#endif /* __FreeBSD__ */ +#include #include -#define NETMAP_WITH_LIBS -#include +#include +#include /* memcpy */ +#include +#include +#include #include +#include // setpriority +#include +#include - /* * * A packet in the queue is q_pkt plus the payload. @@ -242,15 +257,6 @@ static struct nm_pcap_file *readpcap(const char *fn); static void destroy_pcap(struct nm_pcap_file *file); -#include -#include -#include -#include -#include -#include /* memcpy */ - -#include - #define NS_SCALE 10UL /* nanoseconds in 1s */ static void destroy_pcap(struct nm_pcap_file *pf) @@ -435,18 +441,6 @@ static int verbose = 0; static int do_abort = 0; -#include -#include -#include -#include - -#include // setpriority - -#ifdef __FreeBSD__ -#include /* pthread w/ affinity */ -#include /* cpu_set */ -#endif /* __FreeBSD__ */ - #ifdef linux #define cpuset_tcpu_set_t #endif @@ -566,7 +560,7 @@ struct _qs { /* shared queue */ struct nm_pcap_file *pcap; /* the pcap struct */ /* parameters for reading from the netmap port */ - struct nm_desc *src_port; /* netmap descriptor */ + struct nmport_d *src_port; /* netmap descriptor */ const char *prod_ifname;/* interface name or pcap file */ struct netmap_ring *rxring; /* current ring being handled */ uint32_tsi; /* ring index */ @@ -640,8 +634,8 @@ struct pipe_args { int cons_core; /* core for cons() */ int prod_core; /* core for prod() */ - struct nm_desc *pa; /* netmap descriptor */ - struct nm_desc *pb; + struct nmport_d *pa;/* netmap descriptor */ + struct nmport_d *pb; struct _qs q; }; @@ -843,7 +837,7 @@ fail: if (q->buf != NULL) { free(q->buf); } -nm_close(pa->pb); +nmport_close(pa->pb); return (NULL); } @@ -893,7 +887,7 @@ cons(void *_pa) continue; } /* XXX copy is inefficient but simple */ - if (nm_inject(pa->pb, (char *)(p + 1), p->pktlen) == 0) { + if (nmport_inject(pa->pb, (char *)(p + 1), p->pktlen) == 0) { RD(1, "inject failed len %d now %ld tx %ld h %ld t %ld next %ld", (int)p->pktlen, (u_long)q->cons_now, (u_long)p->pt_tx, (u_long)q->_head, (u_long)q->_tail, (u_long)p->next); @@ -939,7 +933,7 @@ nmreplay_main(void *_a) pcap_prod((void*)a); destroy_pcap(q->pcap); q->pcap = NULL; -a->pb = nm_open(q->cons_ifname, NULL, 0, NULL); +a->pb = nmport_open(q->cons_ifname); if (a->pb == NULL) { EEE("cannot open netmap on %s", q->cons_ifname); do_abort = 1; // XXX any better way ? @@ -1372,7 +1366,6 @@ parse_bw(const char *arg) * 24 useful random bits. */ -#include /* log, exp etc. */ static inline uint64_t my_random24(void) /* 24 useful bits */ { ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r367933 - head/tools/tools/netmap
Author: vmaffione Date: Sun Nov 22 09:28:50 2020 New Revision: 367933 URL: https://svnweb.freebsd.org/changeset/base/367933 Log: netmap: lb: switch to libnetmap Use the newer libnetmap (included in base) rather than the older nm_open()/nm_close() defined in netmap_user.h MFC after:3 days Modified: head/tools/tools/netmap/lb.c head/tools/tools/netmap/pkt_hash.c Modified: head/tools/tools/netmap/lb.c == --- head/tools/tools/netmap/lb.cSun Nov 22 09:20:08 2020 (r367932) +++ head/tools/tools/netmap/lb.cSun Nov 22 09:28:50 2020 (r367933) @@ -23,21 +23,22 @@ * SUCH DAMAGE. */ /* $FreeBSD$ */ -#include -#include #include -#include +#include #include +#include +#include /* htonl */ +#include +#include +#include +#include +#include +#include #include - -#define NETMAP_WITH_LIBS -#include +#include #include +#include -#include /* htonl */ - -#include - #include "pkt_hash.h" #include "ctrs.h" @@ -86,12 +87,12 @@ struct compact_ipv6_hdr { #define DEF_BATCH 2048 #define DEF_WAIT_LINK 2 #define DEF_STATS_INT 600 -#define BUF_REVOKE 100 +#define BUF_REVOKE 150 #define STAT_MSG_MAXSIZE 1024 static struct { - char ifname[MAX_IFNAMELEN]; - char base_name[MAX_IFNAMELEN]; + char ifname[MAX_IFNAMELEN + 1]; + char base_name[MAX_IFNAMELEN + 1]; int netmap_fd; uint16_t output_rings; uint16_t num_groups; @@ -173,7 +174,7 @@ struct port_des { unsigned int last_sync; uint32_t last_tail; struct overflow_queue *oq; - struct nm_desc *nmd; + struct nmport_d *nmd; struct netmap_ring *ring; struct group_des *group; }; @@ -375,7 +376,7 @@ free_buffers(void) D("added %d buffers to netmap free list", tot); for (i = 0; i < glob_arg.output_rings + 1; ++i) { - nm_close(ports[i].nmd); + nmport_close(ports[i].nmd); } } @@ -480,6 +481,28 @@ init_groups(void) g->last = 1; } + +/* To support packets that span multiple slots (NS_MOREFRAG) we + * need to make sure of the following: + * + * - all fragments of the same packet must go to the same output pipe + * - when dropping, all fragments of the same packet must be dropped + * + * For the former point we remember and reuse the last hash computed + * in each input ring, and only update it when NS_MOREFRAG was not + * set in the last received slot (this marks the start of a new packet). + * + * For the latter point, we only update the output ring head pointer + * when an entire packet has been forwarded. We keep a shadow_head + * pointer to know where to put the next partial fragment and, + * when the need to drop arises, we roll it back to head. + */ +struct morefrag { + uint16_t last_flag; /* for intput rings */ + uint32_t last_hash; /* for input rings */ + uint32_t shadow_head; /* for output rings */ +}; + /* push the packet described by slot rs to the group g. * This may cause other buffers to be pushed down the * chain headed by g. @@ -493,21 +516,28 @@ forward_packet(struct group_des *g, struct netmap_slot struct port_des *port = >ports[output_port]; struct netmap_ring *ring = port->ring; struct overflow_queue *q = port->oq; + struct morefrag *mf = (struct morefrag *)ring->sem; + uint16_t curmf = rs->flags & NS_MOREFRAG; /* Move the packet to the output pipe, unless there is * either no space left on the ring, or there is some * packet still in the overflow queue (since those must * take precedence over the new one) */ - if (ring->head != ring->tail && (q == NULL || oq_empty(q))) { - struct netmap_slot *ts = >slot[ring->head]; + if (mf->shadow_head != ring->tail && (q == NULL || oq_empty(q))) { + struct netmap_slot *ts = >slot[mf->shadow_head]; struct netmap_slot old_slot = *ts; ts->buf_idx = rs->buf_idx; ts->len = rs->len; - ts->flags |= NS_BUF_CHANGED; + ts->flags = rs->flags | NS_BUF_CHANGED; ts->ptr = rs->ptr; - ring->head = nm_ring_next(ring, ring->head); + mf->shadow_head = nm_ring_next(ring, mf->shadow_head); + if (!curmf) { + ring->head = mf->shadow_head; + } + ND("curmf %2x ts->flags %2x shadow_head %3u head %3u tail %3u", + curmf, ts->flags, mf->shadow_head, ring->head, ring->tail); port->ctr.bytes += rs->len; port->ctr.pkts++; forwarded++; @@ -516,9 +546,20 @@ forward_packet(struct group_des *g, struct netmap_slot /* use the overflow queue, if available */ if (q == NULL ||
svn commit: r367932 - head/tools/tools/netmap
Author: vmaffione Date: Sun Nov 22 09:20:08 2020 New Revision: 367932 URL: https://svnweb.freebsd.org/changeset/base/367932 Log: netmap: pkt-gen: switch to libnetmap Use the newer libnetmap (included in base) rather than the older nm_open()/nm_close() defined in netmap_user.h Modified: head/tools/tools/netmap/pkt-gen.c Modified: head/tools/tools/netmap/pkt-gen.c == --- head/tools/tools/netmap/pkt-gen.c Sun Nov 22 09:10:12 2020 (r367931) +++ head/tools/tools/netmap/pkt-gen.c Sun Nov 22 09:20:08 2020 (r367932) @@ -38,36 +38,40 @@ */ #define _GNU_SOURCE/* for CPU_SET() */ -#include -#define NETMAP_WITH_LIBS -#include - -#include // isprint() -#include // sysconf() -#include #include /* ntohs */ -#ifndef _WIN32 -#include /* sysctl */ -#endif +#include +#include // isprint() +#include +#include #include/* getifaddrs */ +#include +#include #include #include #include -#include #include +#include +#ifndef NO_PCAP +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(_WIN32) && !defined(linux) +#include /* sysctl */ +#endif +#include +#include // sysconf() #ifdef linux #define IPV6_VERSION 0x60 #define IPV6_DEFHLIM 64 #endif -#include -#include -#include - -#ifndef NO_PCAP -#include -#endif - #include "ctrs.h" static void usage(int); @@ -236,7 +240,8 @@ struct mac_range { }; /* ifname can be netmap:foo- */ -#define MAX_IFNAMELEN 64 /* our buffer for ifname */ +#define MAX_IFNAMELEN 512 /* our buffer for ifname */ +//#define MAX_PKTSIZE 1536 #define MAX_PKTSIZEMAX_BODYSIZE/* XXX: + IP_HDR + ETH_HDR */ /* compact timestamp to fit into 60 byte packet. (enough to obtain RTT) */ @@ -288,7 +293,8 @@ struct glob_arg { int affinity; int main_fd; - struct nm_desc *nmd; + struct nmport_d *nmd; + uint32_t orig_mode; int report_interval;/* milliseconds between prints */ void *(*td_body)(void *); int td_type; @@ -322,7 +328,7 @@ struct targ { int completed; int cancel; int fd; - struct nm_desc *nmd; + struct nmport_d *nmd; /* these ought to be volatile, but they are * only sampled and errors should not accumulate */ @@ -515,17 +521,21 @@ extract_mac_range(struct mac_range *r) static int get_if_mtu(const struct glob_arg *g) { - char ifname[IFNAMSIZ]; struct ifreq ifreq; int s, ret; + const char *ifname = g->nmd->hdr.nr_name; + size_t len; - if (!strncmp(g->ifname, "netmap:", 7) && !strchr(g->ifname, '{') - && !strchr(g->ifname, '}')) { - /* Parse the interface name and ask the kernel for the -* MTU value. */ - strncpy(ifname, g->ifname+7, IFNAMSIZ-1); - ifname[strcspn(ifname, "-*^{}/@")] = '\0'; + if (!strncmp(g->ifname, "netmap:", 7) && !strchr(ifname, '{') + && !strchr(ifname, '}')) { + len = strlen(ifname); + + if (len > IFNAMSIZ) { + D("'%s' too long, cannot ask for MTU", ifname); + return -1; + } + s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { D("socket() failed: %s", strerror(errno)); @@ -533,13 +543,15 @@ get_if_mtu(const struct glob_arg *g) } memset(, 0, sizeof(ifreq)); - strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); + memcpy(ifreq.ifr_name, ifname, len); ret = ioctl(s, SIOCGIFMTU, ); if (ret) { D("ioctl(SIOCGIFMTU) failed: %s", strerror(errno)); } + close(s); + return ifreq.ifr_mtu; } @@ -620,7 +632,7 @@ system_ncpus(void) * and #rx-rings. */ static int -parse_nmr_config(const char* conf, struct nmreq *nmr) +parse_nmr_config(const char* conf, struct nmreq_register *nmr) { char *w, *tok; int i, v; @@ -654,9 +666,7 @@ parse_nmr_config(const char* conf, struct nmreq *nmr) nmr->nr_tx_rings, nmr->nr_tx_slots, nmr->nr_rx_rings, nmr->nr_rx_slots); free(w); - return (nmr->nr_tx_rings || nmr->nr_tx_slots || - nmr->nr_rx_rings || nmr->nr_rx_slots) ? - NM_OPEN_RING_CFG : 0; + return 0; } @@ -1108,20 +1118,22 @@ initialize_packet(struct targ *targ) static void get_vnet_hdr_len(struct glob_arg *g) { - struct nmreq req; + struct nmreq_header hdr; + struct nmreq_port_hdr ph; int err; - memset(, 0, sizeof(req)); - bcopy(g->nmd->req.nr_name, req.nr_name, sizeof(req.nr_name)); -
svn commit: r367931 - head/tools/tools/netmap
Author: vmaffione Date: Sun Nov 22 09:10:12 2020 New Revision: 367931 URL: https://svnweb.freebsd.org/changeset/base/367931 Log: netmap: bridge: switch to libnetmap Use the newer libnetmap (included in base) rather than the older nm_open()/nm_close() defined in netmap_user.h Modified: head/tools/tools/netmap/Makefile head/tools/tools/netmap/bridge.c Modified: head/tools/tools/netmap/Makefile == --- head/tools/tools/netmap/MakefileSun Nov 22 05:47:45 2020 (r367930) +++ head/tools/tools/netmap/MakefileSun Nov 22 09:10:12 2020 (r367931) @@ -11,7 +11,7 @@ MAN= .include .include -LDFLAGS += -lpthread +LDFLAGS += -lpthread -lnetmap .ifdef WITHOUT_PCAP CFLAGS += -DNO_PCAP .else @@ -27,7 +27,7 @@ pkt-gen: pkt-gen.o $(CC) $(CFLAGS) -o pkt-gen pkt-gen.o $(LDFLAGS) bridge: bridge.o - $(CC) $(CFLAGS) -o bridge bridge.o + $(CC) $(CFLAGS) -o bridge bridge.o $(LDFLAGS) nmreplay: nmreplay.o $(CC) $(CFLAGS) -o nmreplay nmreplay.o $(LDFLAGS) Modified: head/tools/tools/netmap/bridge.c == --- head/tools/tools/netmap/bridge.cSun Nov 22 05:47:45 2020 (r367930) +++ head/tools/tools/netmap/bridge.cSun Nov 22 09:10:12 2020 (r367931) @@ -10,9 +10,12 @@ */ #include -#define NETMAP_WITH_LIBS -#include #include +#include +#include +#include +#include +#include static int verbose = 0; @@ -32,7 +35,7 @@ sigint_h(int sig) * how many packets on this set of queues ? */ static int -pkt_queued(struct nm_desc *d, int tx) +pkt_queued(struct nmport_d *d, int tx) { u_int i, tot = 0; @@ -61,8 +64,8 @@ process_rings(struct netmap_ring *rxring, struct netma if (rxring->flags || txring->flags) D("%s rxflags %x txflags %x", msg, rxring->flags, txring->flags); - j = rxring->cur; /* RX */ - k = txring->cur; /* TX */ + j = rxring->head; /* RX */ + k = txring->head; /* TX */ m = nm_ring_space(rxring); if (m < limit) limit = m; @@ -115,11 +118,11 @@ process_rings(struct netmap_ring *rxring, struct netma /* move packts from src to destination */ static int -move(struct nm_desc *src, struct nm_desc *dst, u_int limit) +move(struct nmport_d *src, struct nmport_d *dst, u_int limit) { struct netmap_ring *txring, *rxring; u_int m = 0, si = src->first_rx_ring, di = dst->first_tx_ring; - const char *msg = (src->req.nr_flags == NR_REG_SW) ? + const char *msg = (src->reg.nr_flags == NR_REG_SW) ? "host->net" : "net->host"; while (si <= src->last_rx_ring && di <= dst->last_tx_ring) { @@ -175,7 +178,7 @@ main(int argc, char **argv) struct pollfd pollfd[2]; int ch; u_int burst = 1024, wait_link = 4; - struct nm_desc *pa = NULL, *pb = NULL; + struct nmport_d *pa = NULL, *pb = NULL; char *ifa = NULL, *ifb = NULL; char ifabuf[64] = { 0 }; int loopback = 0; @@ -252,16 +255,16 @@ main(int argc, char **argv) } else { /* two different interfaces. Take all rings on if1 */ } - pa = nm_open(ifa, NULL, 0, NULL); + pa = nmport_open(ifa); if (pa == NULL) { D("cannot open %s", ifa); return (1); } /* try to reuse the mmap() of the first interface, if possible */ - pb = nm_open(ifb, NULL, NM_OPEN_NO_MMAP, pa); + pb = nmport_open(ifb); if (pb == NULL) { D("cannot open %s", ifb); - nm_close(pa); + nmport_close(pa); return (1); } zerocopy = zerocopy && (pa->mem == pb->mem); @@ -275,8 +278,8 @@ main(int argc, char **argv) D("Wait %d secs for link to come up...", wait_link); sleep(wait_link); D("Ready to go, %s 0x%x/%d <-> %s 0x%x/%d.", - pa->req.nr_name, pa->first_rx_ring, pa->req.nr_rx_rings, - pb->req.nr_name, pb->first_rx_ring, pb->req.nr_rx_rings); + pa->hdr.nr_name, pa->first_rx_ring, pa->reg.nr_rx_rings, + pb->hdr.nr_name, pb->first_rx_ring, pb->reg.nr_rx_rings); /* main loop */ signal(SIGINT, sigint_h); @@ -320,12 +323,12 @@ main(int argc, char **argv) pollfd[0].events, pollfd[0].revents, pkt_queued(pa, 0), - NETMAP_RXRING(pa->nifp, pa->cur_rx_ring)->cur, + NETMAP_RXRING(pa->nifp, pa->cur_rx_ring)->head, pkt_queued(pa, 1), pollfd[1].events, pollfd[1].revents, pkt_queued(pb, 0), -
svn commit: r367921 - head/tools/tools/netmap
Author: vmaffione Date: Sat Nov 21 18:47:13 2020 New Revision: 367921 URL: https://svnweb.freebsd.org/changeset/base/367921 Log: netmap: bridge, pkt-gen: fix man page typo Reported by: ian MFC after:3 days Modified: head/tools/tools/netmap/bridge.8 head/tools/tools/netmap/pkt-gen.8 Modified: head/tools/tools/netmap/bridge.8 == --- head/tools/tools/netmap/bridge.8Sat Nov 21 18:20:21 2020 (r367920) +++ head/tools/tools/netmap/bridge.8Sat Nov 21 18:47:13 2020 (r367921) @@ -58,7 +58,7 @@ When bridging the hardware rings of a physical port wi host rings, it is necessary to turn off the offloads, because netmap does not prepare the NIC rings with offload information. Example: -.Bd -literal -offset intent +.Bd -literal -offset indent ifconfig em0 -rxcsum -txcsum -tso4 -tso6 -lro .Ed .Pp Modified: head/tools/tools/netmap/pkt-gen.8 == --- head/tools/tools/netmap/pkt-gen.8 Sat Nov 21 18:20:21 2020 (r367920) +++ head/tools/tools/netmap/pkt-gen.8 Sat Nov 21 18:47:13 2020 (r367921) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 3, 2020 +.Dd November 21, 2020 .Dt PKT-GEN 8 .Os .Sh NAME @@ -287,7 +287,7 @@ Send a stream of fake DNS packets between two hosts wi length of 128 bytes. You must set the destination MAC address for packets to be received by the target host. -.Bd -literal -offset intent +.Bd -literal -offset indent pkt-gen -i netmap:ncxl0 -f tx -s 172.16.0.1:53 -d 172.16.1.3:53 -D 00:07:43:29:2a:e0 .Ed .Sh SEE ALSO ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
Re: svn commit: r367920 - head/tools/tools/netmap
ups... Thanks! Cheers, Vincenzo Il giorno sab 21 nov 2020 alle ore 19:27 Ian Lepore ha scritto: > On Sat, 2020-11-21 at 18:20 +0000, Vincenzo Maffione wrote: > > Author: vmaffione > > Date: Sat Nov 21 18:20:21 2020 > > New Revision: 367920 > ... > > +.Bd -literal -offset intent > > > > s/intent/indent/ ? > > -- Ian > > ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r367920 - head/tools/tools/netmap
Author: vmaffione Date: Sat Nov 21 18:20:21 2020 New Revision: 367920 URL: https://svnweb.freebsd.org/changeset/base/367920 Log: netmap: bridge: update man page with more information Update the man page to describe how it is necessary to enable promiscuous mode and/or disable offloads. Modified: head/tools/tools/netmap/bridge.8 Modified: head/tools/tools/netmap/bridge.8 == --- head/tools/tools/netmap/bridge.8Sat Nov 21 10:58:19 2020 (r367919) +++ head/tools/tools/netmap/bridge.8Sat Nov 21 18:20:21 2020 (r367920) @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 28, 2018 +.Dd November 21, 2020 .Dt BRIDGE 8 .Os .Sh NAME @@ -49,6 +49,20 @@ forwards packets without copying the packets payload ( explicitly prevented by the .Fl c flag. +.Pp +When bridging two physical ports, it is necessary that both NICS are in +promiscuous mode, otherwise unicast traffic directed to other hosts will +be dropped by the hardware, and bridging will not work. +.Pp +When bridging the hardware rings of a physical port with the corresponding +host rings, it is necessary to turn off the offloads, because netmap does +not prepare the NIC rings with offload information. +Example: +.Bd -literal -offset intent +ifconfig em0 -rxcsum -txcsum -tso4 -tso6 -lro +.Ed +.Pp +Available options: .Bl -tag -width Ds .It Fl i Ar port Name of the netmap port. @@ -71,8 +85,8 @@ Disable zero-copy mode. .El .Sh SEE ALSO .Xr netmap 4 , -.Xr pkt-gen 8 , -.Xr lb 8 +.Xr lb 8 , +.Xr pkt-gen 8 .Sh AUTHORS .An -nosplit .Nm ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r367599 - stable/12/sys/net
Author: vmaffione Date: Wed Nov 11 21:27:16 2020 New Revision: 367599 URL: https://svnweb.freebsd.org/changeset/base/367599 Log: MFC r367093, r367117 iflib: add per-tx-queue netmap timer The way netmap TX is handled in iflib when TX interrupts are not used (IFC_NETMAP_TX_IRQ not set) has some issues: - The netmap_tx_irq() function gets called by iflib_timer(), which gets scheduled with tick granularity (hz). This is not frequent enough for 10Gbps NICs and beyond (e.g., ixgbe or ixl). The end result is that the transmitting netmap application is not woken up fast enough to saturate the link with small packets. - The iflib_timer() functions also calls isc_txd_credits_update() to ask for more TX completion updates. However, this violates the netmap requirement that only txsync can access the TX queue for datapath operations. Only netmap_tx_irq() may be called out of the txsync context. This change introduces per-tx-queue netmap timers, using microsecond granularity to ensure that netmap_tx_irq() can be called often enough to allow for maximum packet rate. The timer routine simply calls netmap_tx_irq() to wake up the netmap application. The latter will wake up and call txsync to collect TX completion updates. This change brings back line rate speed with small packets for ixgbe. For the time being, timer expiration is hardcoded to 90 microseconds, in order to avoid introducing a new sysctl. We may eventually implement an adaptive expiration period or use another deferred work mechanism in place of timers. Also, fix the timers usage to make sure that each queue is serviced by a different CPU. PR: 248652 Reported by:s...@efficientip.com Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Wed Nov 11 18:45:06 2020(r367598) +++ stable/12/sys/net/iflib.c Wed Nov 11 21:27:16 2020(r367599) @@ -348,6 +348,9 @@ struct iflib_txq { qidx_t ift_size; uint16_tift_id; struct callout ift_timer; +#ifdef DEV_NETMAP + struct callout ift_netmap_timer; +#endif /* DEV_NETMAP */ if_txsd_vec_t ift_sds; uint8_t ift_qstatus; @@ -763,6 +766,7 @@ iflib_num_tx_descs(if_ctx_t ctx) MODULE_DEPEND(iflib, netmap, 1, 1, 1); static int netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, bool init); +static void iflib_netmap_timer(void *arg); /* * device-specific sysctl variables: @@ -928,6 +932,8 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring return (0); } +#define NETMAP_TX_TIMER_US 90 + /* * Reconcile kernel and user view of the transmit ring. * @@ -1057,9 +1063,8 @@ iflib_netmap_txsync(struct netmap_kring *kring, int fl * Second part: reclaim buffers for completed transmissions. * * If there are unclaimed buffers, attempt to reclaim them. -* If none are reclaimed, and TX IRQs are not in use, do an initial -* minimal delay, then trigger the tx handler which will spin in the -* group task queue. +* If we don't manage to reclaim them all, and TX IRQs are not in use, +* trigger a per-tx-queue timer to try again later. */ if (kring->nr_hwtail != nm_prev(kring->nr_hwcur, lim)) { if (iflib_tx_credits_update(ctx, txq)) { @@ -1068,11 +1073,14 @@ iflib_netmap_txsync(struct netmap_kring *kring, int fl kring->nr_hwtail = nm_prev(netmap_idx_n2k(kring, nic_i), lim); } } + if (!(ctx->ifc_flags & IFC_NETMAP_TX_IRQ)) if (kring->nr_hwtail != nm_prev(kring->nr_hwcur, lim)) { - callout_reset_on(>ift_timer, hz < 2000 ? 1 : hz / 1000, - iflib_timer, txq, txq->ift_timer.c_cpu); - } + callout_reset_sbt_on(>ift_netmap_timer, + NETMAP_TX_TIMER_US * SBT_1US, SBT_1US, + iflib_netmap_timer, txq, + txq->ift_netmap_timer.c_cpu, 0); + } return (0); } @@ -1275,28 +1283,16 @@ iflib_netmap_rxq_init(if_ctx_t ctx, iflib_rxq_t rxq) } static void -iflib_netmap_timer_adjust(if_ctx_t ctx, iflib_txq_t txq, uint32_t *reset_on) +iflib_netmap_timer(void *arg) { - struct netmap_kring *kring; - uint16_t txqid; + iflib_txq_t txq = arg; + if_ctx_t ctx = txq->ift_ctx; - txqid = txq->ift_id; - kring = netmap_kring_on(NA(ctx->ifc_ifp), txqid, NR_TX); - if (kring == NULL) - return; - - if (kring->nr_hwcur != nm_next(kring->nr_hwtail, kring->nkr_num_slots - 1)) { - bus_dmamap_sync(txq->ift_ifdi->idi_tag,
svn commit: r367117 - head/sys/net
Author: vmaffione Date: Wed Oct 28 21:06:17 2020 New Revision: 367117 URL: https://svnweb.freebsd.org/changeset/base/367117 Log: iflib: fix typo bug introduced by r367093 Code was supposed to call callout_reset_sbt_on() rather than callout_reset_sbt(). This resulted into passing a "cpu" value to a "flag" argument. A recipe for subtle errors. PR: 248652 Reported by: s...@efficientip.com MFC with: r367093 Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cWed Oct 28 21:02:43 2020(r367116) +++ head/sys/net/iflib.cWed Oct 28 21:06:17 2020(r367117) @@ -1066,9 +1066,10 @@ iflib_netmap_txsync(struct netmap_kring *kring, int fl if (!(ctx->ifc_flags & IFC_NETMAP_TX_IRQ)) if (kring->nr_hwtail != nm_prev(kring->nr_hwcur, lim)) { - callout_reset_sbt(>ift_netmap_timer, + callout_reset_sbt_on(>ift_netmap_timer, NETMAP_TX_TIMER_US * SBT_1US, SBT_1US, - iflib_netmap_timer, txq, txq->ift_netmap_timer.c_cpu); + iflib_netmap_timer, txq, + txq->ift_netmap_timer.c_cpu, 0); } return (0); } ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r367093 - head/sys/net
Author: vmaffione Date: Tue Oct 27 21:53:33 2020 New Revision: 367093 URL: https://svnweb.freebsd.org/changeset/base/367093 Log: iflib: add per-tx-queue netmap timer The way netmap TX is handled in iflib when TX interrupts are not used (IFC_NETMAP_TX_IRQ not set) has some issues: - The netmap_tx_irq() function gets called by iflib_timer(), which gets scheduled with tick granularity (hz). This is not frequent enough for 10Gbps NICs and beyond (e.g., ixgbe or ixl). The end result is that the transmitting netmap application is not woken up fast enough to saturate the link with small packets. - The iflib_timer() functions also calls isc_txd_credits_update() to ask for more TX completion updates. However, this violates the netmap requirement that only txsync can access the TX queue for datapath operations. Only netmap_tx_irq() may be called out of the txsync context. This change introduces per-tx-queue netmap timers, using microsecond granularity to ensure that netmap_tx_irq() can be called often enough to allow for maximum packet rate. The timer routine simply calls netmap_tx_irq() to wake up the netmap application. The latter will wake up and call txsync to collect TX completion updates. This change brings back line rate speed with small packets for ixgbe. For the time being, timer expiration is hardcoded to 90 microseconds, in order to avoid introducing a new sysctl. We may eventually implement an adaptive expiration period or use another deferred work mechanism in place of timers. Also, fix the timers usage to make sure that each queue is serviced by a different CPU. PR: 248652 Reported by: s...@efficientip.com MFC after:2 weeks Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cTue Oct 27 20:13:33 2020(r367092) +++ head/sys/net/iflib.cTue Oct 27 21:53:33 2020(r367093) @@ -346,6 +346,9 @@ struct iflib_txq { qidx_t ift_size; uint16_tift_id; struct callout ift_timer; +#ifdef DEV_NETMAP + struct callout ift_netmap_timer; +#endif /* DEV_NETMAP */ if_txsd_vec_t ift_sds; uint8_t ift_qstatus; @@ -753,6 +756,7 @@ iflib_num_tx_descs(if_ctx_t ctx) MODULE_DEPEND(iflib, netmap, 1, 1, 1); static int netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, bool init); +static void iflib_netmap_timer(void *arg); /* * device-specific sysctl variables: @@ -918,6 +922,8 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring return (0); } +#define NETMAP_TX_TIMER_US 90 + /* * Reconcile kernel and user view of the transmit ring. * @@ -1047,9 +1053,8 @@ iflib_netmap_txsync(struct netmap_kring *kring, int fl * Second part: reclaim buffers for completed transmissions. * * If there are unclaimed buffers, attempt to reclaim them. -* If none are reclaimed, and TX IRQs are not in use, do an initial -* minimal delay, then trigger the tx handler which will spin in the -* group task queue. +* If we don't manage to reclaim them all, and TX IRQs are not in use, +* trigger a per-tx-queue timer to try again later. */ if (kring->nr_hwtail != nm_prev(kring->nr_hwcur, lim)) { if (iflib_tx_credits_update(ctx, txq)) { @@ -1058,11 +1063,13 @@ iflib_netmap_txsync(struct netmap_kring *kring, int fl kring->nr_hwtail = nm_prev(netmap_idx_n2k(kring, nic_i), lim); } } + if (!(ctx->ifc_flags & IFC_NETMAP_TX_IRQ)) if (kring->nr_hwtail != nm_prev(kring->nr_hwcur, lim)) { - callout_reset_on(>ift_timer, hz < 2000 ? 1 : hz / 1000, - iflib_timer, txq, txq->ift_timer.c_cpu); - } + callout_reset_sbt(>ift_netmap_timer, + NETMAP_TX_TIMER_US * SBT_1US, SBT_1US, + iflib_netmap_timer, txq, txq->ift_netmap_timer.c_cpu); + } return (0); } @@ -1263,28 +1270,16 @@ iflib_netmap_rxq_init(if_ctx_t ctx, iflib_rxq_t rxq) } static void -iflib_netmap_timer_adjust(if_ctx_t ctx, iflib_txq_t txq, uint32_t *reset_on) +iflib_netmap_timer(void *arg) { - struct netmap_kring *kring; - uint16_t txqid; + iflib_txq_t txq = arg; + if_ctx_t ctx = txq->ift_ctx; - txqid = txq->ift_id; - kring = netmap_kring_on(NA(ctx->ifc_ifp), txqid, NR_TX); - if (kring == NULL) - return; - - if (kring->nr_hwcur != nm_next(kring->nr_hwtail, kring->nkr_num_slots - 1)) { - bus_dmamap_sync(txq->ift_ifdi->idi_tag, txq->ift_ifdi->idi_map, - BUS_DMASYNC_POSTREAD); - if
svn commit: r367036 - stable/12/sys/dev/netmap
Author: vmaffione Date: Sun Oct 25 07:48:07 2020 New Revision: 367036 URL: https://svnweb.freebsd.org/changeset/base/367036 Log: MFC r366952 netmap: fix mutex double unlock bug https://github.com/luigirizzo/netmap/pull/733 Submitted by:brian90013 Modified: stable/12/sys/dev/netmap/netmap_mem2.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/netmap/netmap_mem2.c == --- stable/12/sys/dev/netmap/netmap_mem2.c Sun Oct 25 01:36:33 2020 (r367035) +++ stable/12/sys/dev/netmap/netmap_mem2.c Sun Oct 25 07:48:07 2020 (r367036) @@ -2007,7 +2007,6 @@ netmap_mem2_if_new(struct netmap_adapter *na, struct n len = sizeof(struct netmap_if) + (ntot * sizeof(ssize_t)); nifp = netmap_if_malloc(na->nm_mem, len); if (nifp == NULL) { - NMA_UNLOCK(na->nm_mem); return NULL; } ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r366952 - head/sys/dev/netmap
Author: vmaffione Date: Thu Oct 22 20:21:11 2020 New Revision: 366952 URL: https://svnweb.freebsd.org/changeset/base/366952 Log: netmap: fix mutex double unlock bug https://github.com/luigirizzo/netmap/pull/733 Submitted by: brian90013 MFC after:3 days Modified: head/sys/dev/netmap/netmap_mem2.c Modified: head/sys/dev/netmap/netmap_mem2.c == --- head/sys/dev/netmap/netmap_mem2.c Thu Oct 22 20:02:02 2020 (r366951) +++ head/sys/dev/netmap/netmap_mem2.c Thu Oct 22 20:21:11 2020 (r366952) @@ -2007,7 +2007,6 @@ netmap_mem2_if_new(struct netmap_adapter *na, struct n len = sizeof(struct netmap_if) + (ntot * sizeof(ssize_t)); nifp = netmap_if_malloc(na->nm_mem, len); if (nifp == NULL) { - NMA_UNLOCK(na->nm_mem); return NULL; } ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r366499 - stable/12/tools/tools/netmap
Author: vmaffione Date: Tue Oct 6 19:15:11 2020 New Revision: 366499 URL: https://svnweb.freebsd.org/changeset/base/366499 Log: MFC r366394 netmap: tools: extend CFLAGS after including bsd.prog.mk MFC after: 1 week Modified: stable/12/tools/tools/netmap/Makefile Directory Properties: stable/12/ (props changed) Modified: stable/12/tools/tools/netmap/Makefile == --- stable/12/tools/tools/netmap/Makefile Tue Oct 6 19:14:03 2020 (r366498) +++ stable/12/tools/tools/netmap/Makefile Tue Oct 6 19:15:11 2020 (r366499) @@ -7,9 +7,10 @@ PROGS = pkt-gen nmreplay bridge lb CLEANFILES = $(PROGS) *.o MAN= -CFLAGS += -Werror -Wall -CFLAGS += -Wextra +.include +.include + LDFLAGS += -lpthread .ifdef WITHOUT_PCAP CFLAGS += -DNO_PCAP @@ -17,9 +18,6 @@ CFLAGS += -DNO_PCAP LDFLAGS += -lpcap .endif LDFLAGS += -lm # used by nmreplay - -.include -.include CFLAGS += -Wno-cast-align ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r366498 - stable/12/tools/tools/netmap
Author: vmaffione Date: Tue Oct 6 19:14:03 2020 New Revision: 366498 URL: https://svnweb.freebsd.org/changeset/base/366498 Log: MFC r366393 netmap: tools: fix several compiler warnings MFC after: 1 week Modified: stable/12/tools/tools/netmap/Makefile stable/12/tools/tools/netmap/bridge.c stable/12/tools/tools/netmap/ctrs.h stable/12/tools/tools/netmap/lb.c stable/12/tools/tools/netmap/nmreplay.c stable/12/tools/tools/netmap/pkt-gen.c stable/12/tools/tools/netmap/pkt_hash.c Directory Properties: stable/12/ (props changed) Modified: stable/12/tools/tools/netmap/Makefile == --- stable/12/tools/tools/netmap/Makefile Tue Oct 6 19:12:43 2020 (r366497) +++ stable/12/tools/tools/netmap/Makefile Tue Oct 6 19:14:03 2020 (r366498) @@ -21,6 +21,8 @@ LDFLAGS += -lm # used by nmreplay .include .include +CFLAGS += -Wno-cast-align + all: $(PROGS) pkt-gen: pkt-gen.o Modified: stable/12/tools/tools/netmap/bridge.c == --- stable/12/tools/tools/netmap/bridge.c Tue Oct 6 19:12:43 2020 (r366497) +++ stable/12/tools/tools/netmap/bridge.c Tue Oct 6 19:14:03 2020 (r366498) @@ -14,7 +14,7 @@ #include #include -int verbose = 0; +static int verbose = 0; static int do_abort = 0; static int zerocopy = 1; /* enable zerocopy if possible */ @@ -31,7 +31,7 @@ sigint_h(int sig) /* * how many packets on this set of queues ? */ -int +static int pkt_queued(struct nm_desc *d, int tx) { u_int i, tot = 0; Modified: stable/12/tools/tools/netmap/ctrs.h == --- stable/12/tools/tools/netmap/ctrs.h Tue Oct 6 19:12:43 2020 (r366497) +++ stable/12/tools/tools/netmap/ctrs.h Tue Oct 6 19:14:03 2020 (r366498) @@ -18,12 +18,12 @@ struct my_ctrs { * Caller has to make sure that the buffer is large enough. */ static const char * -norm2(char *buf, double val, char *fmt, int normalize) +norm2(char *buf, double val, const char *fmt, int normalize) { - char *units[] = { "", "K", "M", "G", "T" }; + const char *units[] = { "", "K", "M", "G", "T" }; u_int i; if (normalize) - for (i = 0; val >=1000 && i < sizeof(units)/sizeof(char *) - 1; i++) + for (i = 0; val >=1000 && i < sizeof(units)/sizeof(const char *) - 1; i++) val /= 1000; else i=0; Modified: stable/12/tools/tools/netmap/lb.c == --- stable/12/tools/tools/netmap/lb.c Tue Oct 6 19:12:43 2020 (r366497) +++ stable/12/tools/tools/netmap/lb.c Tue Oct 6 19:14:03 2020 (r366498) @@ -89,7 +89,7 @@ struct compact_ipv6_hdr { #define BUF_REVOKE 100 #define STAT_MSG_MAXSIZE 1024 -struct { +static struct { char ifname[MAX_IFNAMELEN]; char base_name[MAX_IFNAMELEN]; int netmap_fd; @@ -115,7 +115,7 @@ struct overflow_queue { uint32_t size; }; -struct overflow_queue *freeq; +static struct overflow_queue *freeq; static inline int oq_full(struct overflow_queue *q) @@ -160,12 +160,12 @@ oq_deq(struct overflow_queue *q) static volatile int do_abort = 0; -uint64_t dropped = 0; -uint64_t forwarded = 0; -uint64_t received_bytes = 0; -uint64_t received_pkts = 0; -uint64_t non_ip = 0; -uint32_t freeq_n = 0; +static uint64_t dropped = 0; +static uint64_t forwarded = 0; +static uint64_t received_bytes = 0; +static uint64_t received_pkts = 0; +static uint64_t non_ip = 0; +static uint32_t freeq_n = 0; struct port_des { char interface[MAX_PORTNAMELEN]; @@ -178,7 +178,7 @@ struct port_des { struct group_des *group; }; -struct port_des *ports; +static struct port_des *ports; /* each group of pipes receives all the packets */ struct group_des { @@ -190,7 +190,7 @@ struct group_des { int custom_port; }; -struct group_des *groups; +static struct group_des *groups; /* statistcs */ struct counters { @@ -205,7 +205,7 @@ struct counters { #define COUNTERS_FULL 1 }; -struct counters counters_buf; +static struct counters counters_buf; static void * print_stats(void *arg) @@ -387,7 +387,7 @@ static void sigint_h(int sig) signal(SIGINT, SIG_DFL); } -void usage() +static void usage() { printf("usage: lb [options]\n"); printf("where options are:\n"); @@ -404,9 +404,9 @@ void usage() } static int -parse_pipes(char *spec) +parse_pipes(const char *spec) { - char *end = index(spec, ':'); + const char *end = index(spec, ':'); static int max_groups = 0; struct group_des *g; @@ -458,7 +458,8 @@ parse_pipes(char *spec) } /* complete the initialization of the groups data structure */ -void init_groups(void) +static
svn commit: r366497 - in stable/12: share/man/man4 tools/tools/netmap
Author: vmaffione Date: Tue Oct 6 19:12:43 2020 New Revision: 366497 URL: https://svnweb.freebsd.org/changeset/base/366497 Log: MFC r366389 netmap: minor documentation fix Also update date of pkt-gen.8 (not done in r366387). Submitted by: milosz.kaniew...@gmail.com Modified: stable/12/share/man/man4/netmap.4 stable/12/tools/tools/netmap/pkt-gen.8 Directory Properties: stable/12/ (props changed) Modified: stable/12/share/man/man4/netmap.4 == --- stable/12/share/man/man4/netmap.4 Tue Oct 6 19:11:55 2020 (r366496) +++ stable/12/share/man/man4/netmap.4 Tue Oct 6 19:12:43 2020 (r366497) @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 6, 2020 +.Dd October 3, 2020 .Dt NETMAP 4 .Os .Sh NAME @@ -1051,7 +1051,7 @@ void receiver(void) for (;;) { poll(, 1, -1); while ( (buf = nm_nextpkt(d, )) ) - consume_pkt(buf, h->len); + consume_pkt(buf, h.len); } nm_close(d); } Modified: stable/12/tools/tools/netmap/pkt-gen.8 == --- stable/12/tools/tools/netmap/pkt-gen.8 Tue Oct 6 19:11:55 2020 (r366496) +++ stable/12/tools/tools/netmap/pkt-gen.8 Tue Oct 6 19:12:43 2020 (r366497) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 31, 2018 +.Dd October 3, 2020 .Dt PKT-GEN 8 .Os .Sh NAME ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r366496 - stable/12/sys/net
Author: vmaffione Date: Tue Oct 6 19:11:55 2020 New Revision: 366496 URL: https://svnweb.freebsd.org/changeset/base/366496 Log: MFC r366388 netmap: fix constness warnings generated by "-Wcast-qual" Submitted by: milosz.kaniew...@gmail.com Modified: stable/12/sys/net/netmap_user.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/netmap_user.h == --- stable/12/sys/net/netmap_user.h Tue Oct 6 19:10:32 2020 (r366495) +++ stable/12/sys/net/netmap_user.h Tue Oct 6 19:11:55 2020 (r366496) @@ -292,7 +292,7 @@ struct nm_desc { * when the descriptor is open correctly, d->self == d * Eventually we should also use some magic number. */ -#define P2NMD(p) ((struct nm_desc *)(p)) +#define P2NMD(p) ((const struct nm_desc *)(p)) #define IS_NETMAP_DESC(d) ((d) && P2NMD(d)->self == P2NMD(d)) #define NETMAP_FD(d) (P2NMD(d)->fd) @@ -623,7 +623,7 @@ nm_parse(const char *ifname, struct nm_desc *d, char * const char *vpname = NULL; u_int namelen; uint32_t nr_ringid = 0, nr_flags; - char errmsg[MAXERRMSG] = ""; + char errmsg[MAXERRMSG] = "", *tmp; long num; uint16_t nr_arg2 = 0; enum { P_START, P_RNGSFXOK, P_GETNUM, P_FLAGS, P_FLAGSOK, P_MEMID } p_state; @@ -720,12 +720,13 @@ nm_parse(const char *ifname, struct nm_desc *d, char * port++; break; case P_GETNUM: - num = strtol(port, (char **), 10); + num = strtol(port, , 10); if (num < 0 || num >= NETMAP_RING_MASK) { snprintf(errmsg, MAXERRMSG, "'%ld' out of range [0, %d)", num, NETMAP_RING_MASK); goto fail; } + port = tmp; nr_ringid = num & NETMAP_RING_MASK; p_state = P_RNGSFXOK; break; @@ -767,11 +768,12 @@ nm_parse(const char *ifname, struct nm_desc *d, char * snprintf(errmsg, MAXERRMSG, "double setting of memid"); goto fail; } - num = strtol(port, (char **), 10); + num = strtol(port, , 10); if (num <= 0) { snprintf(errmsg, MAXERRMSG, "invalid memid %ld, must be >0", num); goto fail; } + port = tmp; nr_arg2 = num; p_state = P_RNGSFXOK; break; @@ -1054,7 +1056,7 @@ nm_inject(struct nm_desc *d, const void *buf, size_t s ring->slot[i].flags = NS_MOREFRAG; nm_pkt_copy(buf, NETMAP_BUF(ring, idx), ring->nr_buf_size); i = nm_ring_next(ring, i); - buf = (char *)buf + ring->nr_buf_size; + buf = (const char *)buf + ring->nr_buf_size; } idx = ring->slot[i].buf_idx; ring->slot[i].len = rem; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r366495 - stable/12/tools/tools/netmap
Author: vmaffione Date: Tue Oct 6 19:10:32 2020 New Revision: 366495 URL: https://svnweb.freebsd.org/changeset/base/366495 Log: MFC r366387 netmap: pkt-gen: minor corrections to documentation Submitted by: Brian Poole Modified: stable/12/tools/tools/netmap/pkt-gen.8 stable/12/tools/tools/netmap/pkt-gen.c Directory Properties: stable/12/ (props changed) Modified: stable/12/tools/tools/netmap/pkt-gen.8 == --- stable/12/tools/tools/netmap/pkt-gen.8 Tue Oct 6 18:13:15 2020 (r366494) +++ stable/12/tools/tools/netmap/pkt-gen.8 Tue Oct 6 19:10:32 2020 (r366495) @@ -95,7 +95,7 @@ for server-side ping-pong operation. .It Fl n Ar count Number of iterations of the .Nm -function, with 0 meaning infinite). +function (with 0 meaning infinite). In case of .Cm tx or @@ -147,10 +147,10 @@ is larger than one, each thread handles a single TX ri .Cm tx mode), a single RX ring (in .Cm rx -mode), or a TX/RX ring couple. +mode), or a TX/RX ring pair. The number of .Ar threads -must be less or equal than the number of TX (or RX) ring available +must be less than or equal to the number of TX (or RX) ring available in the device specified by .Ar interface . .It Fl T Ar report_ms @@ -158,7 +158,7 @@ Number of milliseconds between reports. .It Fl w Ar wait_for_link_time Number of seconds to wait before starting the .Nm -function, useuful to make sure that the network link is up. +function, useful to make sure that the network link is up. A network device driver may take some time to enter netmap mode, or to create a new transmit/receive ring pair when .Xr netmap 4 @@ -168,7 +168,7 @@ Packet transmission rate. Not setting the packet transmission rate tells .Nm to transmit packets as quickly as possible. -On servers from 2010 on-wards +On servers from 2010 onward .Xr netmap 4 is able to completely use all of the bandwidth of a 10 or 40Gbps link, so this option should be used unless your intention is to saturate the link. @@ -231,7 +231,7 @@ This adds 4 bytes of CRC and 20 bytes of framing to ea .It Fl C Ar tx_slots Ns Oo Cm \&, Ns Ar rx_slots Ns Oo Cm \&, Ns Ar tx_rings Ns Oo Cm \&, Ns Ar rx_rings Oc Oc Oc Configuration in terms of number of rings and slots to be used when opening the netmap port. -Such configuration has effect on software ports +Such configuration has an effect on software ports created on the fly, such as VALE ports and netmap pipes. The configuration may consist of 1 to 4 numbers separated by commas: .Dq tx_slots,rx_slots,tx_rings,rx_rings . Modified: stable/12/tools/tools/netmap/pkt-gen.c == --- stable/12/tools/tools/netmap/pkt-gen.c Tue Oct 6 18:13:15 2020 (r366494) +++ stable/12/tools/tools/netmap/pkt-gen.c Tue Oct 6 19:10:32 2020 (r366495) @@ -275,7 +275,7 @@ struct glob_arg { #define OPT_TS 16 /* add a timestamp */ #define OPT_INDIRECT 32 /* use indirect buffers, tx only */ #define OPT_DUMP 64 /* dump rx/tx traffic */ -#define OPT_RUBBISH256 /* send wathever the buffers contain */ +#define OPT_RUBBISH256 /* send whatever the buffers contain */ #define OPT_RANDOM_SRC 512 #define OPT_RANDOM_DST 1024 #define OPT_PPS_STATS 2048 @@ -2360,7 +2360,7 @@ usage(int errcode) " for client-side ping-pong operation, and pong for server-side ping-pong operation.\n" "\n" " -n count\n" -" Number of iterations of the pkt-gen function, with 0 meaning infinite). In case of tx or rx,\n" +" Number of iterations of the pkt-gen function (with 0 meaning infinite). In case of tx or rx,\n" " count is the number of packets to receive or transmit. In case of ping or pong, count is the\n" " number of ping-pong transactions.\n" "\n" @@ -2397,20 +2397,20 @@ usage(int errcode) " -p threads\n" " Number of threads to use. By default, only a single thread is used to handle all the netmap\n" " rings. If threads is larger than one, each thread handles a single TX ring (in tx mode), a\n" -" single RX ring (in rx mode), or a TX/RX ring couple. The number of threads must be less or\n" -" equal than the number of TX (or RX) ring available in the device specified by interface.\n" +" single RX ring (in rx mode), or a TX/RX ring pair. The number of threads must be less than or\n" +" equal to the number of TX (or RX) rings available in the device specified by interface.\n" "\n" " -T report_ms\n" " Number of milliseconds between reports.\n" "\n" " -w wait_for_link_time\n" -" Number of seconds to wait before starting the pkt-gen function, useuful to make sure that the\n" +" Number of seconds to wait before starting the
svn commit: r366394 - head/tools/tools/netmap
Author: vmaffione Date: Sat Oct 3 13:27:12 2020 New Revision: 366394 URL: https://svnweb.freebsd.org/changeset/base/366394 Log: netmap: tools: extend CFLAGS after including bsd.prog.mk MFC after:1 week Modified: head/tools/tools/netmap/Makefile Modified: head/tools/tools/netmap/Makefile == --- head/tools/tools/netmap/MakefileSat Oct 3 13:19:48 2020 (r366393) +++ head/tools/tools/netmap/MakefileSat Oct 3 13:27:12 2020 (r366394) @@ -7,9 +7,10 @@ PROGS = pkt-gen nmreplay bridge lb CLEANFILES = $(PROGS) *.o MAN= -CFLAGS += -Werror -Wall -CFLAGS += -Wextra +.include +.include + LDFLAGS += -lpthread .ifdef WITHOUT_PCAP CFLAGS += -DNO_PCAP @@ -17,9 +18,6 @@ CFLAGS += -DNO_PCAP LDFLAGS += -lpcap .endif LDFLAGS += -lm # used by nmreplay - -.include -.include CFLAGS += -Wno-cast-align ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r366393 - head/tools/tools/netmap
Author: vmaffione Date: Sat Oct 3 13:19:48 2020 New Revision: 366393 URL: https://svnweb.freebsd.org/changeset/base/366393 Log: netmap: tools: fix several compiler warnings MFC after:1 week Modified: head/tools/tools/netmap/Makefile head/tools/tools/netmap/bridge.c head/tools/tools/netmap/ctrs.h head/tools/tools/netmap/lb.c head/tools/tools/netmap/nmreplay.c head/tools/tools/netmap/pkt-gen.c head/tools/tools/netmap/pkt_hash.c Modified: head/tools/tools/netmap/Makefile == --- head/tools/tools/netmap/MakefileSat Oct 3 13:01:07 2020 (r366392) +++ head/tools/tools/netmap/MakefileSat Oct 3 13:19:48 2020 (r366393) @@ -21,6 +21,8 @@ LDFLAGS += -lm # used by nmreplay .include .include +CFLAGS += -Wno-cast-align + all: $(PROGS) pkt-gen: pkt-gen.o Modified: head/tools/tools/netmap/bridge.c == --- head/tools/tools/netmap/bridge.cSat Oct 3 13:01:07 2020 (r366392) +++ head/tools/tools/netmap/bridge.cSat Oct 3 13:19:48 2020 (r366393) @@ -14,7 +14,7 @@ #include #include -int verbose = 0; +static int verbose = 0; static int do_abort = 0; static int zerocopy = 1; /* enable zerocopy if possible */ @@ -31,7 +31,7 @@ sigint_h(int sig) /* * how many packets on this set of queues ? */ -int +static int pkt_queued(struct nm_desc *d, int tx) { u_int i, tot = 0; Modified: head/tools/tools/netmap/ctrs.h == --- head/tools/tools/netmap/ctrs.h Sat Oct 3 13:01:07 2020 (r366392) +++ head/tools/tools/netmap/ctrs.h Sat Oct 3 13:19:48 2020 (r366393) @@ -18,12 +18,12 @@ struct my_ctrs { * Caller has to make sure that the buffer is large enough. */ static const char * -norm2(char *buf, double val, char *fmt, int normalize) +norm2(char *buf, double val, const char *fmt, int normalize) { - char *units[] = { "", "K", "M", "G", "T" }; + const char *units[] = { "", "K", "M", "G", "T" }; u_int i; if (normalize) - for (i = 0; val >=1000 && i < sizeof(units)/sizeof(char *) - 1; i++) + for (i = 0; val >=1000 && i < sizeof(units)/sizeof(const char *) - 1; i++) val /= 1000; else i=0; Modified: head/tools/tools/netmap/lb.c == --- head/tools/tools/netmap/lb.cSat Oct 3 13:01:07 2020 (r366392) +++ head/tools/tools/netmap/lb.cSat Oct 3 13:19:48 2020 (r366393) @@ -89,7 +89,7 @@ struct compact_ipv6_hdr { #define BUF_REVOKE 100 #define STAT_MSG_MAXSIZE 1024 -struct { +static struct { char ifname[MAX_IFNAMELEN]; char base_name[MAX_IFNAMELEN]; int netmap_fd; @@ -115,7 +115,7 @@ struct overflow_queue { uint32_t size; }; -struct overflow_queue *freeq; +static struct overflow_queue *freeq; static inline int oq_full(struct overflow_queue *q) @@ -160,12 +160,12 @@ oq_deq(struct overflow_queue *q) static volatile int do_abort = 0; -uint64_t dropped = 0; -uint64_t forwarded = 0; -uint64_t received_bytes = 0; -uint64_t received_pkts = 0; -uint64_t non_ip = 0; -uint32_t freeq_n = 0; +static uint64_t dropped = 0; +static uint64_t forwarded = 0; +static uint64_t received_bytes = 0; +static uint64_t received_pkts = 0; +static uint64_t non_ip = 0; +static uint32_t freeq_n = 0; struct port_des { char interface[MAX_PORTNAMELEN]; @@ -178,7 +178,7 @@ struct port_des { struct group_des *group; }; -struct port_des *ports; +static struct port_des *ports; /* each group of pipes receives all the packets */ struct group_des { @@ -190,7 +190,7 @@ struct group_des { int custom_port; }; -struct group_des *groups; +static struct group_des *groups; /* statistcs */ struct counters { @@ -205,7 +205,7 @@ struct counters { #define COUNTERS_FULL 1 }; -struct counters counters_buf; +static struct counters counters_buf; static void * print_stats(void *arg) @@ -387,7 +387,7 @@ static void sigint_h(int sig) signal(SIGINT, SIG_DFL); } -void usage() +static void usage() { printf("usage: lb [options]\n"); printf("where options are:\n"); @@ -404,9 +404,9 @@ void usage() } static int -parse_pipes(char *spec) +parse_pipes(const char *spec) { - char *end = index(spec, ':'); + const char *end = index(spec, ':'); static int max_groups = 0; struct group_des *g; @@ -458,7 +458,8 @@ parse_pipes(char *spec) } /* complete the initialization of the groups data structure */ -void init_groups(void) +static void +init_groups(void) { int i, j, t = 0; struct group_des *g = NULL; @@ -484,7 +485,8 @@ void init_groups(void) * chain headed by g. *
svn commit: r366389 - in head: share/man/man4 tools/tools/netmap
Author: vmaffione Date: Sat Oct 3 09:36:33 2020 New Revision: 366389 URL: https://svnweb.freebsd.org/changeset/base/366389 Log: netmap: minor documentation fix Also update date of pkt-gen.8 (not done in r366387). Submitted by: milosz.kaniew...@gmail.com MFC after:3 days Modified: head/share/man/man4/netmap.4 head/tools/tools/netmap/pkt-gen.8 Modified: head/share/man/man4/netmap.4 == --- head/share/man/man4/netmap.4Sat Oct 3 09:33:29 2020 (r366388) +++ head/share/man/man4/netmap.4Sat Oct 3 09:36:33 2020 (r366389) @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 6, 2020 +.Dd October 3, 2020 .Dt NETMAP 4 .Os .Sh NAME @@ -1052,7 +1052,7 @@ void receiver(void) for (;;) { poll(, 1, -1); while ( (buf = nm_nextpkt(d, )) ) - consume_pkt(buf, h->len); + consume_pkt(buf, h.len); } nm_close(d); } Modified: head/tools/tools/netmap/pkt-gen.8 == --- head/tools/tools/netmap/pkt-gen.8 Sat Oct 3 09:33:29 2020 (r366388) +++ head/tools/tools/netmap/pkt-gen.8 Sat Oct 3 09:36:33 2020 (r366389) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 31, 2018 +.Dd October 3, 2020 .Dt PKT-GEN 8 .Os .Sh NAME ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r366388 - head/sys/net
Author: vmaffione Date: Sat Oct 3 09:33:29 2020 New Revision: 366388 URL: https://svnweb.freebsd.org/changeset/base/366388 Log: netmap: fix constness warnings generated by "-Wcast-qual" Submitted by: milosz.kaniew...@gmail.com MFC after:3 days Modified: head/sys/net/netmap_user.h Modified: head/sys/net/netmap_user.h == --- head/sys/net/netmap_user.h Sat Oct 3 09:23:34 2020(r366387) +++ head/sys/net/netmap_user.h Sat Oct 3 09:33:29 2020(r366388) @@ -290,7 +290,7 @@ struct nm_desc { * when the descriptor is open correctly, d->self == d * Eventually we should also use some magic number. */ -#define P2NMD(p) ((struct nm_desc *)(p)) +#define P2NMD(p) ((const struct nm_desc *)(p)) #define IS_NETMAP_DESC(d) ((d) && P2NMD(d)->self == P2NMD(d)) #define NETMAP_FD(d) (P2NMD(d)->fd) @@ -616,7 +616,7 @@ nm_parse(const char *ifname, struct nm_desc *d, char * const char *vpname = NULL; u_int namelen; uint32_t nr_ringid = 0, nr_flags; - char errmsg[MAXERRMSG] = ""; + char errmsg[MAXERRMSG] = "", *tmp; long num; uint16_t nr_arg2 = 0; enum { P_START, P_RNGSFXOK, P_GETNUM, P_FLAGS, P_FLAGSOK, P_MEMID } p_state; @@ -713,12 +713,13 @@ nm_parse(const char *ifname, struct nm_desc *d, char * port++; break; case P_GETNUM: - num = strtol(port, (char **), 10); + num = strtol(port, , 10); if (num < 0 || num >= NETMAP_RING_MASK) { snprintf(errmsg, MAXERRMSG, "'%ld' out of range [0, %d)", num, NETMAP_RING_MASK); goto fail; } + port = tmp; nr_ringid = num & NETMAP_RING_MASK; p_state = P_RNGSFXOK; break; @@ -760,11 +761,12 @@ nm_parse(const char *ifname, struct nm_desc *d, char * snprintf(errmsg, MAXERRMSG, "double setting of memid"); goto fail; } - num = strtol(port, (char **), 10); + num = strtol(port, , 10); if (num <= 0) { snprintf(errmsg, MAXERRMSG, "invalid memid %ld, must be >0", num); goto fail; } + port = tmp; nr_arg2 = num; p_state = P_RNGSFXOK; break; @@ -1044,7 +1046,7 @@ nm_inject(struct nm_desc *d, const void *buf, size_t s ring->slot[i].flags = NS_MOREFRAG; nm_pkt_copy(buf, NETMAP_BUF(ring, idx), ring->nr_buf_size); i = nm_ring_next(ring, i); - buf = (char *)buf + ring->nr_buf_size; + buf = (const char *)buf + ring->nr_buf_size; } idx = ring->slot[i].buf_idx; ring->slot[i].len = rem; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r366387 - head/tools/tools/netmap
Author: vmaffione Date: Sat Oct 3 09:23:34 2020 New Revision: 366387 URL: https://svnweb.freebsd.org/changeset/base/366387 Log: netmap: pkt-gen: minor corrections to documentation Submitted by: Brian Poole MFC after:3 days Modified: head/tools/tools/netmap/pkt-gen.8 head/tools/tools/netmap/pkt-gen.c Modified: head/tools/tools/netmap/pkt-gen.8 == --- head/tools/tools/netmap/pkt-gen.8 Sat Oct 3 08:31:28 2020 (r366386) +++ head/tools/tools/netmap/pkt-gen.8 Sat Oct 3 09:23:34 2020 (r366387) @@ -95,7 +95,7 @@ for server-side ping-pong operation. .It Fl n Ar count Number of iterations of the .Nm -function, with 0 meaning infinite). +function (with 0 meaning infinite). In case of .Cm tx or @@ -147,10 +147,10 @@ is larger than one, each thread handles a single TX ri .Cm tx mode), a single RX ring (in .Cm rx -mode), or a TX/RX ring couple. +mode), or a TX/RX ring pair. The number of .Ar threads -must be less or equal than the number of TX (or RX) ring available +must be less than or equal to the number of TX (or RX) ring available in the device specified by .Ar interface . .It Fl T Ar report_ms @@ -158,7 +158,7 @@ Number of milliseconds between reports. .It Fl w Ar wait_for_link_time Number of seconds to wait before starting the .Nm -function, useuful to make sure that the network link is up. +function, useful to make sure that the network link is up. A network device driver may take some time to enter netmap mode, or to create a new transmit/receive ring pair when .Xr netmap 4 @@ -168,7 +168,7 @@ Packet transmission rate. Not setting the packet transmission rate tells .Nm to transmit packets as quickly as possible. -On servers from 2010 on-wards +On servers from 2010 onward .Xr netmap 4 is able to completely use all of the bandwidth of a 10 or 40Gbps link, so this option should be used unless your intention is to saturate the link. @@ -231,7 +231,7 @@ This adds 4 bytes of CRC and 20 bytes of framing to ea .It Fl C Ar tx_slots Ns Oo Cm \&, Ns Ar rx_slots Ns Oo Cm \&, Ns Ar tx_rings Ns Oo Cm \&, Ns Ar rx_rings Oc Oc Oc Configuration in terms of number of rings and slots to be used when opening the netmap port. -Such configuration has effect on software ports +Such configuration has an effect on software ports created on the fly, such as VALE ports and netmap pipes. The configuration may consist of 1 to 4 numbers separated by commas: .Dq tx_slots,rx_slots,tx_rings,rx_rings . Modified: head/tools/tools/netmap/pkt-gen.c == --- head/tools/tools/netmap/pkt-gen.c Sat Oct 3 08:31:28 2020 (r366386) +++ head/tools/tools/netmap/pkt-gen.c Sat Oct 3 09:23:34 2020 (r366387) @@ -275,7 +275,7 @@ struct glob_arg { #define OPT_TS 16 /* add a timestamp */ #define OPT_INDIRECT 32 /* use indirect buffers, tx only */ #define OPT_DUMP 64 /* dump rx/tx traffic */ -#define OPT_RUBBISH256 /* send wathever the buffers contain */ +#define OPT_RUBBISH256 /* send whatever the buffers contain */ #define OPT_RANDOM_SRC 512 #define OPT_RANDOM_DST 1024 #define OPT_PPS_STATS 2048 @@ -2360,7 +2360,7 @@ usage(int errcode) " for client-side ping-pong operation, and pong for server-side ping-pong operation.\n" "\n" " -n count\n" -" Number of iterations of the pkt-gen function, with 0 meaning infinite). In case of tx or rx,\n" +" Number of iterations of the pkt-gen function (with 0 meaning infinite). In case of tx or rx,\n" " count is the number of packets to receive or transmit. In case of ping or pong, count is the\n" " number of ping-pong transactions.\n" "\n" @@ -2397,20 +2397,20 @@ usage(int errcode) " -p threads\n" " Number of threads to use. By default, only a single thread is used to handle all the netmap\n" " rings. If threads is larger than one, each thread handles a single TX ring (in tx mode), a\n" -" single RX ring (in rx mode), or a TX/RX ring couple. The number of threads must be less or\n" -" equal than the number of TX (or RX) ring available in the device specified by interface.\n" +" single RX ring (in rx mode), or a TX/RX ring pair. The number of threads must be less than or\n" +" equal to the number of TX (or RX) rings available in the device specified by interface.\n" "\n" " -T report_ms\n" " Number of milliseconds between reports.\n" "\n" " -w wait_for_link_time\n" -" Number of seconds to wait before starting the pkt-gen function, useuful to make sure that the\n" +" Number of seconds to wait before starting the pkt-gen function, useful to make sure that the\n" " network link is up. A network device
svn commit: r366130 - stable/12/lib/libnetmap
Author: vmaffione Date: Thu Sep 24 20:01:31 2020 New Revision: 366130 URL: https://svnweb.freebsd.org/changeset/base/366130 Log: MFC r366011 libnetmap: fix cast from uint64_t to void* We use uintptr_t as an intermediate cast to avoid compiler warnings on 32 bit architectures. Reported by:adrian Modified: stable/12/lib/libnetmap/libnetmap.h stable/12/lib/libnetmap/nmport.c Directory Properties: stable/12/ (props changed) Modified: stable/12/lib/libnetmap/libnetmap.h == --- stable/12/lib/libnetmap/libnetmap.h Thu Sep 24 19:59:29 2020 (r366129) +++ stable/12/lib/libnetmap/libnetmap.h Thu Sep 24 20:01:31 2020 (r366130) @@ -554,9 +554,9 @@ struct nmreq_option *nmreq_find_option(struct nmreq_he void nmreq_free_options(struct nmreq_header *); const char* nmreq_option_name(uint32_t); #define nmreq_foreach_option(h_, o_) \ - for ((o_) = (struct nmreq_option *)((h_)->nr_options);\ + for ((o_) = (struct nmreq_option *)((uintptr_t)((h_)->nr_options));\ (o_) != NULL;\ -(o_) = (struct nmreq_option *)((o_)->nro_next)) +(o_) = (struct nmreq_option *)((uintptr_t)((o_)->nro_next))) /* nmctx manipulation */ Modified: stable/12/lib/libnetmap/nmport.c == --- stable/12/lib/libnetmap/nmport.cThu Sep 24 19:59:29 2020 (r366129) +++ stable/12/lib/libnetmap/nmport.cThu Sep 24 20:01:31 2020 (r366130) @@ -614,7 +614,7 @@ nmport_mmap(struct nmport_d *d) } memset(m, 0, sizeof(*m)); if (d->extmem != NULL) { - m->mem = (void *)d->extmem->nro_usrptr; + m->mem = (void *)((uintptr_t)d->extmem->nro_usrptr); m->size = d->extmem->nro_info.nr_memsize; m->is_extmem = 1; } else { ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r366014 - in stable/12/sys: dev/bnxt dev/vmware/vmxnet3 net
Author: vmaffione Date: Tue Sep 22 21:43:43 2020 New Revision: 366014 URL: https://svnweb.freebsd.org/changeset/base/366014 Log: MFC r365061 iflib: leave only 1 receive descriptor unused The pidx argument of isc_rxd_flush() indicates which is the last valid receive descriptor to be used by the NIC. However, current code has multiple issues: - Intel drivers write pidx to their RDT register, which means that NICs will only use the descriptors up to pidx-1 (modulo ring size N), and won't actually use the one pointed by pidx. This does not break reception, but it is anyway confusing and suboptimal (the NIC will actually see only N-2 descriptors as available, rather than N-1). Other drivers (if_vmx, if_bnxt, if_mgb) adhere to this semantic. - The semantic used by Intel (RDT is one descriptor past the last valid one) is used by most (if not all) NICs, and it is also used on the TX side (also in iflib). Since iflib is not currently using this semantic for RX, it must decrement fl->ifl_pidx (modulo N) before calling isc_rxd_flush(), and then the per-driver callback implementation must increment the index again (to match the real semantic). This is confusing and suboptimal. - The iflib refill function is also called at initialization. However, in case the ring size is smaller than 128 (e.g. if_mgb), the refill function will actually prepare all the receive descriptors (N), without leaving one unused, as most of NICs assume (e.g. to avoid RDT to overrun RDH). I can speculate that the code looks like this right now because this issue showed up during testing (e.g. with if_mgb), and it was easy to workaround by decrementing pidx before isc_rxd_flush(). The goal of this change is to simplify the code (removing a bunch of instructions from the RX fast path), and to make the semantic of isc_rxd_flush() consistent across drivers. To achieve this, we: - change the semantics of the pidx argument to the usual one (that is the index one past the last valid one), so that both iflib and drivers avoid the decrement/increment dance. - fix the initialization code to prepare at most N-1 descriptors. Reviewed by:markj Differential Revision: https://reviews.freebsd.org/D26191 Modified: stable/12/sys/dev/bnxt/bnxt_txrx.c stable/12/sys/dev/vmware/vmxnet3/if_vmx.c stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/bnxt/bnxt_txrx.c == --- stable/12/sys/dev/bnxt/bnxt_txrx.c Tue Sep 22 21:16:03 2020 (r366013) +++ stable/12/sys/dev/bnxt/bnxt_txrx.c Tue Sep 22 21:43:43 2020 (r366014) @@ -316,10 +316,9 @@ bnxt_isc_rxd_flush(void *sc, uint16_t rxqid, uint8_t f if (softc->rx_cp_rings[rxqid].cons != UINT32_MAX) BNXT_CP_IDX_DISABLE_DB(>rx_cp_rings[rxqid].ring, softc->rx_cp_rings[rxqid].cons); - /* We're given the last filled RX buffer here, not the next empty one */ - BNXT_RX_DB(rx_ring, RING_NEXT(rx_ring, pidx)); + BNXT_RX_DB(rx_ring, pidx); /* TODO: Cumulus+ doesn't need the double doorbell */ - BNXT_RX_DB(rx_ring, RING_NEXT(rx_ring, pidx)); + BNXT_RX_DB(rx_ring, pidx); return; } Modified: stable/12/sys/dev/vmware/vmxnet3/if_vmx.c == --- stable/12/sys/dev/vmware/vmxnet3/if_vmx.c Tue Sep 22 21:16:03 2020 (r366013) +++ stable/12/sys/dev/vmware/vmxnet3/if_vmx.c Tue Sep 22 21:43:43 2020 (r366014) @@ -1744,13 +1744,6 @@ vmxnet3_isc_rxd_flush(void *vsc, uint16_t rxqid, uint8 else r = VMXNET3_BAR0_RXH2(rxqid); - /* -* pidx is the index of the last descriptor with a buffer the device -* can use, and the device needs to be told which index is one past -* that. -*/ - if (++pidx == rxr->vxrxr_ndesc) - pidx = 0; vmxnet3_write_bar0(sc, r, pidx); } Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Tue Sep 22 21:16:03 2020(r366013) +++ stable/12/sys/net/iflib.c Tue Sep 22 21:43:43 2020(r366014) @@ -2030,7 +2030,8 @@ _rxq_refill_cb(void *arg, bus_dma_segment_t *segs, int * @count: the number of new buffers to allocate * * (Re)populate an rxq free-buffer list with up to @count new packet buffers. - * The caller must assure that @count does not exceed the queue's capacity. + * The caller must assure that @count does not exceed the queue's capacity + * minus one (since we always leave a descriptor unavailable). */ static uint8_t iflib_fl_refill(if_ctx_t ctx, iflib_fl_t fl, int count) @@ -2045,6 +2046,8 @@ iflib_fl_refill(if_ctx_t
svn commit: r366013 - in stable/12: lib lib/libnetmap share/mk
Author: vmaffione Date: Tue Sep 22 21:16:03 2020 New Revision: 366013 URL: https://svnweb.freebsd.org/changeset/base/366013 Log: MFC r364936, r365023 lib: add libnetmap This changeset introduces the new libnetmap library for writing netmap applications. Before libnetmap, applications could either use the kernel API directly (e.g. NIOCREGIF/NIOCCTRL) or the simple header-only-library netmap_user.h (e.g. nm_open(), nm_close(), nm_mmap() etc.) The new library offers more functionalities than netmap_user.h: - Support for complex netmap options, such as external memory allocators or per-buffer offsets. This opens the way to future extensions. - More flexibility in the netmap port bind options, such as non-numeric names for pipes, or the ability to specify the netmap allocator that must be used for a given port. - Automatic tracking of the netmap memory regions in use across the open ports. At the moment there is no man page, but the libnetmap.h header file has in-depth documentation. Reviewed by:hrs Differential Revision: https://reviews.freebsd.org/D26171 Added: stable/12/lib/libnetmap/ - copied from r364936, head/lib/libnetmap/ Modified: stable/12/lib/Makefile stable/12/lib/libnetmap/nmctx-pthreads.c stable/12/lib/libnetmap/nmctx.c stable/12/lib/libnetmap/nmport.c stable/12/lib/libnetmap/nmreq.c stable/12/share/mk/bsd.libnames.mk stable/12/share/mk/src.libnames.mk Directory Properties: stable/12/ (props changed) Modified: stable/12/lib/Makefile == --- stable/12/lib/Makefile Tue Sep 22 21:13:26 2020(r366012) +++ stable/12/lib/Makefile Tue Sep 22 21:16:03 2020(r366013) @@ -66,6 +66,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \ libmt \ lib80211 \ libnetbsd \ + libnetmap \ libnv \ libopenbsd \ libopie \ Modified: stable/12/lib/libnetmap/nmctx-pthreads.c == --- head/lib/libnetmap/nmctx-pthreads.c Fri Aug 28 20:03:54 2020 (r364936) +++ stable/12/lib/libnetmap/nmctx-pthreads.cTue Sep 22 21:16:03 2020 (r366013) @@ -1,4 +1,34 @@ -/* $FreeBSD$ */ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (C) 2018 Universita` di Pisa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + #include #include #include Modified: stable/12/lib/libnetmap/nmctx.c == --- head/lib/libnetmap/nmctx.c Fri Aug 28 20:03:54 2020(r364936) +++ stable/12/lib/libnetmap/nmctx.c Tue Sep 22 21:16:03 2020 (r366013) @@ -1,4 +1,34 @@ -/* $FreeBSD$ */ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (C) 2018 Universita` di Pisa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF
svn commit: r366011 - head/lib/libnetmap
Author: vmaffione Date: Tue Sep 22 20:20:43 2020 New Revision: 366011 URL: https://svnweb.freebsd.org/changeset/base/366011 Log: libnetmap: fix cast from uint64_t to void* We use uintptr_t as an intermediate cast to avoid compiler warnings on 32 bit architectures. Reported by: adrian MFC after:3 days Modified: head/lib/libnetmap/libnetmap.h head/lib/libnetmap/nmport.c Modified: head/lib/libnetmap/libnetmap.h == --- head/lib/libnetmap/libnetmap.h Tue Sep 22 20:04:57 2020 (r366010) +++ head/lib/libnetmap/libnetmap.h Tue Sep 22 20:20:43 2020 (r366011) @@ -554,9 +554,9 @@ struct nmreq_option *nmreq_find_option(struct nmreq_he void nmreq_free_options(struct nmreq_header *); const char* nmreq_option_name(uint32_t); #define nmreq_foreach_option(h_, o_) \ - for ((o_) = (struct nmreq_option *)((h_)->nr_options);\ + for ((o_) = (struct nmreq_option *)((uintptr_t)((h_)->nr_options));\ (o_) != NULL;\ -(o_) = (struct nmreq_option *)((o_)->nro_next)) +(o_) = (struct nmreq_option *)((uintptr_t)((o_)->nro_next))) /* nmctx manipulation */ Modified: head/lib/libnetmap/nmport.c == --- head/lib/libnetmap/nmport.c Tue Sep 22 20:04:57 2020(r366010) +++ head/lib/libnetmap/nmport.c Tue Sep 22 20:20:43 2020(r366011) @@ -614,7 +614,7 @@ nmport_mmap(struct nmport_d *d) } memset(m, 0, sizeof(*m)); if (d->extmem != NULL) { - m->mem = (void *)d->extmem->nro_usrptr; + m->mem = (void *)((uintptr_t)d->extmem->nro_usrptr); m->size = d->extmem->nro_info.nr_memsize; m->is_extmem = 1; } else { ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r365066 - stable/12/sys/net
Author: vmaffione Date: Tue Sep 1 20:58:23 2020 New Revision: 365066 URL: https://svnweb.freebsd.org/changeset/base/365066 Log: r364770 iflib: netmap: publish all the receive buffer At initialization time, the netmap RX refill function used to prepare the NIC RX ring with N-1 buffers rather than N (with N equal to the number of descriptors in the NIC RX ring). This is not how netmap is supposed to work, as it would keep kring->nr_hwcur not in sync with the NIC "next index to refill" (i.e., fl->ifl_pidx). Instead we prepare N buffers, although we still publish (with isc_rxd_flush()) only the first N-1 buffers, to avoid the NIC producer pointer to overrun the NIC consumer pointer (for NICs where this is a real issue, e.g. Intel ones). Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Tue Sep 1 20:50:16 2020(r365065) +++ stable/12/sys/net/iflib.c Tue Sep 1 20:58:23 2020(r365066) @@ -837,7 +837,6 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring { struct netmap_adapter *na = kring->na; u_int const lim = kring->nkr_num_slots - 1; - u_int head = kring->rhead; u_int nm_i = kring->nr_hwcur; struct netmap_ring *ring = kring->ring; bus_dmamap_t *map; @@ -845,39 +844,46 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring if_ctx_t ctx = rxq->ifr_ctx; iflib_fl_t fl = >ifr_fl[0]; u_int nic_i_first, nic_i; - int i; + int i, n; #if IFLIB_DEBUG_COUNTERS int rf_count = 0; #endif /* -* Netmap requires that we leave (at least) one free slot -* in the ring, so that it can distinguish between an empty -* ring (nr_hwcur == nr_hwtail, i.e. all the buffers owned by the -* user) and a full ring (nr_hwtail == (nr_hwcur - 1) mod N, i.e. -* all the buffers owned by the kernel). -* We thus set head (the refill limit) to nr_hwcur - 1 -* at initialization. The rest of the code will then make sure -* than nr_hwtail never overcomes nr_hwcur. +* This function is used both at initialization and in rxsync. +* At initialization we need to prepare (with isc_rxd_refill()) +* all the (N) netmap buffers in the ring, in such a way to keep +* fl->ifl_pidx and kring->nr_hwcur in sync (except for +* kring->nkr_hwofs); at rxsync time, both indexes point to the +* next buffer to be refilled. +* In any case we publish (with isc_rxd_flush()) up to +* (fl->ifl_pidx - 1) % N (included), to avoid the NIC tail/prod +* pointer to overrun the head/cons pointer, although this is +* not necessary for some NICs (e.g. vmx). */ - if (__predict_false(init)) { - head = nm_prev(nm_i, lim); - } else if (nm_i == head) { - /* Nothing to do. We can leave early. */ - return (0); + if (__predict_false(init)) + n = kring->nkr_num_slots; + else { + n = kring->rhead - nm_i; + if (n == 0) + return (0); /* Nothing to do. */ + if (n < 0) + n += kring->nkr_num_slots; } + /* Start to refill from nr_hwcur, publishing n buffers. */ iru_init(, rxq, 0 /* flid */); map = fl->ifl_sds.ifsd_map; - nic_i = netmap_idx_k2n(kring, nm_i); + nic_i = fl->ifl_pidx; + MPASS(nic_i == netmap_idx_k2n(kring, nm_i)); DBG_COUNTER_INC(fl_refills); - while (nm_i != head) { + while (n > 0) { #if IFLIB_DEBUG_COUNTERS if (++rf_count == 9) DBG_COUNTER_INC(fl_refills_large); #endif nic_i_first = nic_i; - for (i = 0; i < IFLIB_MAX_RX_REFRESH && nm_i != head; i++) { + for (i = 0; n > 0 && i < IFLIB_MAX_RX_REFRESH; n--, i++) { struct netmap_slot *slot = >slot[nm_i]; void *addr = PNMB(na, slot, >ifl_bus_addrs[i]); @@ -908,11 +914,11 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring iru.iru_count = i; ctx->isc_rxd_refill(ctx->ifc_softc, ); } - kring->nr_hwcur = head; + fl->ifl_pidx = nic_i; + MPASS(!init || nm_i == 0); + MPASS(nm_i == kring->rhead); + kring->nr_hwcur = nm_i; - /* The pidx argument of isc_rxd_flush() is the index of the last valid -* slot in the free list ring. We need therefore to decrement nic_i, -* similarly to what happens in iflib_fl_refill() for ifl_pidx. */ bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); ctx->isc_rxd_flush(ctx->ifc_softc,
svn commit: r365065 - stable/12/sys/net
Author: vmaffione Date: Tue Sep 1 20:50:16 2020 New Revision: 365065 URL: https://svnweb.freebsd.org/changeset/base/365065 Log: MFC r364655 iflib: fix isc_rxd_flush call in netmap_fl_refill() The semantic of the pidx argument of isc_rxd_flush() is the last valid index of in the free list, rather than the next index to be published. However, netmap was still using the old convention. While there, also refactor the netmap_fl_refill() to simplify a little bit and add an assertion. Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Tue Sep 1 20:47:59 2020(r365064) +++ stable/12/sys/net/iflib.c Tue Sep 1 20:50:16 2020(r365065) @@ -762,7 +762,7 @@ iflib_num_tx_descs(if_ctx_t ctx) MODULE_DEPEND(iflib, netmap, 1, 1, 1); -static int netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, bool init); +static int netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, bool init); /* * device-specific sysctl variables: @@ -833,33 +833,43 @@ iflib_netmap_register(struct netmap_adapter *na, int o } static int -netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, bool init) +netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, bool init) { struct netmap_adapter *na = kring->na; u_int const lim = kring->nkr_num_slots - 1; u_int head = kring->rhead; + u_int nm_i = kring->nr_hwcur; struct netmap_ring *ring = kring->ring; bus_dmamap_t *map; struct if_rxd_update iru; if_ctx_t ctx = rxq->ifr_ctx; iflib_fl_t fl = >ifr_fl[0]; - uint32_t nic_i_first, nic_i; + u_int nic_i_first, nic_i; int i; #if IFLIB_DEBUG_COUNTERS int rf_count = 0; #endif - if (nm_i == head && __predict_true(!init)) + /* +* Netmap requires that we leave (at least) one free slot +* in the ring, so that it can distinguish between an empty +* ring (nr_hwcur == nr_hwtail, i.e. all the buffers owned by the +* user) and a full ring (nr_hwtail == (nr_hwcur - 1) mod N, i.e. +* all the buffers owned by the kernel). +* We thus set head (the refill limit) to nr_hwcur - 1 +* at initialization. The rest of the code will then make sure +* than nr_hwtail never overcomes nr_hwcur. +*/ + if (__predict_false(init)) { + head = nm_prev(nm_i, lim); + } else if (nm_i == head) { + /* Nothing to do. We can leave early. */ return (0); + } iru_init(, rxq, 0 /* flid */); map = fl->ifl_sds.ifsd_map; nic_i = netmap_idx_k2n(kring, nm_i); - /* -* IMPORTANT: we must leave one free slot in the ring, -* so move head back by one unit -*/ - head = nm_prev(head, lim); DBG_COUNTER_INC(fl_refills); while (nm_i != head) { #if IFLIB_DEBUG_COUNTERS @@ -900,9 +910,13 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring } kring->nr_hwcur = head; + /* The pidx argument of isc_rxd_flush() is the index of the last valid +* slot in the free list ring. We need therefore to decrement nic_i, +* similarly to what happens in iflib_fl_refill() for ifl_pidx. */ bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i); + ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, + nm_prev(nic_i, lim)); DBG_COUNTER_INC(rxd_flush); return (0); @@ -1132,6 +1146,7 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl nic_i = fl->ifl_cidx; nm_i = netmap_idx_n2k(kring, nic_i); + MPASS(nm_i == kring->nr_hwtail); for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { rxd_info_zero(); ri.iri_frags = rxq->ifr_frags; @@ -1170,9 +1185,9 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl * nic_i is the index in the NIC ring, and * nm_i == (nic_i + kring->nkr_hwofs) % ring_size */ - nm_i = kring->nr_hwcur; + netmap_fl_refill(rxq, kring, false); - return (netmap_fl_refill(rxq, kring, nm_i, false)); + return (0); } static void @@ -1244,14 +1259,12 @@ iflib_netmap_rxq_init(if_ctx_t ctx, iflib_rxq_t rxq) struct netmap_adapter *na = NA(ctx->ifc_ifp); struct netmap_kring *kring; struct netmap_slot *slot; - uint32_t nm_i; slot = netmap_reset(na, NR_RX, rxq->ifr_id, 0); if (slot == NULL) return (0); kring = na->rx_rings[rxq->ifr_id]; -
svn commit: r365064 - stable/12/sys/net
Author: vmaffione Date: Tue Sep 1 20:47:59 2020 New Revision: 365064 URL: https://svnweb.freebsd.org/changeset/base/365064 Log: MFC r364165 iflib: netmap: improve rxsync to support IFLIB_HAS_RXCQ For drivers with IFLIB_HAS_RXCQ set, there is a separate completion queue. In this case, the netmap rxsync routine needs to update rxq->ifr_cq_cidx in the same way it is updated by iflib_rxeof(). This improves the situation for vmx(4) and bnxt(4) drivers, which use iflib and have the IFLIB_HAS_RXCQ bit set. PR: 248494 Modified: stable/12/sys/net/iflib.c stable/12/sys/net/iflib.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Tue Sep 1 20:45:33 2020(r365063) +++ stable/12/sys/net/iflib.c Tue Sep 1 20:47:59 2020(r365064) @@ -425,7 +425,7 @@ struct iflib_rxq { uint64_tifr_rx_irq; /* * If there is a separate completion queue (IFLIB_HAS_RXCQ), this is -* the command queue consumer index. Otherwise it's unused. +* the completion queue consumer index. Otherwise it's unused. */ qidx_t ifr_cq_cidx; uint16_tifr_id; @@ -1082,9 +1082,12 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; if_ctx_t ctx = ifp->if_softc; + if_shared_ctx_t sctx = ctx->ifc_sctx; + if_softc_ctx_t scctx = >ifc_softc_ctx; iflib_rxq_t rxq = >ifc_rxqs[kring->ring_id]; iflib_fl_t fl = >ifr_fl[0]; struct if_rxd_info ri; + qidx_t *cidxp; /* * netmap only uses free list 0, to avoid out of order consumption @@ -1098,40 +1101,56 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl * First part: import newly received packets. * * nm_i is the index of the next free slot in the netmap ring, -* nic_i is the index of the next received packet in the NIC ring, -* and they may differ in case if_init() has been called while +* nic_i is the index of the next received packet in the NIC ring +* (or in the free list 0 if IFLIB_HAS_RXCQ is set), and they may +* differ in case if_init() has been called while * in netmap mode. For the receive ring we have * -* nic_i = rxr->next_check; +* nic_i = fl->ifl_cidx; * nm_i = kring->nr_hwtail (previous) * and * nm_i == (nic_i + kring->nkr_hwofs) % ring_size * -* rxr->next_check is set to 0 on a ring reinit +* fl->ifl_cidx is set to 0 on a ring reinit */ if (netmap_no_pendintr || force_update) { uint32_t hwtail_lim = nm_prev(kring->nr_hwcur, lim); + bool have_rxcq = sctx->isc_flags & IFLIB_HAS_RXCQ; int crclen = iflib_crcstrip ? 0 : 4; int error, avail; + /* +* For the free list consumer index, we use the same +* logic as in iflib_rxeof(). +*/ + if (have_rxcq) + cidxp = >ifr_cq_cidx; + else + cidxp = >ifl_cidx; + avail = ctx->isc_rxd_available(ctx->ifc_softc, + rxq->ifr_id, *cidxp, USHRT_MAX); + nic_i = fl->ifl_cidx; nm_i = netmap_idx_n2k(kring, nic_i); - avail = ctx->isc_rxd_available(ctx->ifc_softc, - rxq->ifr_id, nic_i, USHRT_MAX); for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { rxd_info_zero(); ri.iri_frags = rxq->ifr_frags; ri.iri_qsidx = kring->ring_id; ri.iri_ifp = ctx->ifc_ifp; - ri.iri_cidx = nic_i; + ri.iri_cidx = *cidxp; error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, ); ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen; ring->slot[nm_i].flags = 0; + if (have_rxcq) { + *cidxp = ri.iri_cidx; + while (*cidxp >= scctx->isc_nrxd[0]) + *cidxp -= scctx->isc_nrxd[0]; + } bus_dmamap_sync(fl->ifl_buf_tag, fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD); nm_i = nm_next(nm_i, lim); - nic_i = nm_next(nic_i, lim); + fl->ifl_cidx = nic_i = nm_next(nic_i, lim); } if (n) { /* update the state variables */ if (netmap_no_pendintr &&
svn commit: r365063 - stable/12/sys/net
Author: vmaffione Date: Tue Sep 1 20:45:33 2020 New Revision: 365063 URL: https://svnweb.freebsd.org/changeset/base/365063 Log: MFC r364164 iflib: refactor netmap_fl_refill and fix off-by-one issue First, fix the initialization of the fl->ifl_rxd_idxs array, which was affected by an off-by-one bug. Once there, refactor the function to use better names for local variables, optimize the variable assignments, and merge the bus_dmamap_sync() inner loop with the outer one. PR: 248494 Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Tue Sep 1 20:42:48 2020(r365062) +++ stable/12/sys/net/iflib.c Tue Sep 1 20:45:33 2020(r365063) @@ -843,39 +843,41 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring struct if_rxd_update iru; if_ctx_t ctx = rxq->ifr_ctx; iflib_fl_t fl = >ifr_fl[0]; - uint32_t refill_pidx, nic_i; + uint32_t nic_i_first, nic_i; + int i; #if IFLIB_DEBUG_COUNTERS int rf_count = 0; #endif if (nm_i == head && __predict_true(!init)) - return 0; + return (0); + iru_init(, rxq, 0 /* flid */); map = fl->ifl_sds.ifsd_map; - refill_pidx = netmap_idx_k2n(kring, nm_i); + nic_i = netmap_idx_k2n(kring, nm_i); /* * IMPORTANT: we must leave one free slot in the ring, * so move head back by one unit */ head = nm_prev(head, lim); - nic_i = UINT_MAX; DBG_COUNTER_INC(fl_refills); while (nm_i != head) { #if IFLIB_DEBUG_COUNTERS if (++rf_count == 9) DBG_COUNTER_INC(fl_refills_large); #endif - for (int tmp_pidx = 0; tmp_pidx < IFLIB_MAX_RX_REFRESH && nm_i != head; tmp_pidx++) { + nic_i_first = nic_i; + for (i = 0; i < IFLIB_MAX_RX_REFRESH && nm_i != head; i++) { struct netmap_slot *slot = >slot[nm_i]; - void *addr = PNMB(na, slot, >ifl_bus_addrs[tmp_pidx]); - uint32_t nic_i_dma = refill_pidx; - nic_i = netmap_idx_k2n(kring, nm_i); + void *addr = PNMB(na, slot, >ifl_bus_addrs[i]); - MPASS(tmp_pidx < IFLIB_MAX_RX_REFRESH); + MPASS(i < IFLIB_MAX_RX_REFRESH); if (addr == NETMAP_BUF_BASE(na)) /* bad buf */ return netmap_ring_reinit(kring); + fl->ifl_rxd_idxs[i] = nic_i; + if (__predict_false(init)) { netmap_load_map(na, fl->ifl_buf_tag, map[nic_i], addr); @@ -884,33 +886,25 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring netmap_reload_map(na, fl->ifl_buf_tag, map[nic_i], addr); } + bus_dmamap_sync(fl->ifl_buf_tag, map[nic_i], + BUS_DMASYNC_PREREAD); slot->flags &= ~NS_BUF_CHANGED; nm_i = nm_next(nm_i, lim); - fl->ifl_rxd_idxs[tmp_pidx] = nic_i = nm_next(nic_i, lim); - if (nm_i != head && tmp_pidx < IFLIB_MAX_RX_REFRESH-1) - continue; - - iru.iru_pidx = refill_pidx; - iru.iru_count = tmp_pidx+1; - ctx->isc_rxd_refill(ctx->ifc_softc, ); - refill_pidx = nic_i; - for (int n = 0; n < iru.iru_count; n++) { - bus_dmamap_sync(fl->ifl_buf_tag, map[nic_i_dma], - BUS_DMASYNC_PREREAD); - /* XXX - change this to not use the netmap func*/ - nic_i_dma = nm_next(nic_i_dma, lim); - } + nic_i = nm_next(nic_i, lim); } + + iru.iru_pidx = nic_i_first; + iru.iru_count = i; + ctx->isc_rxd_refill(ctx->ifc_softc, ); } kring->nr_hwcur = head; bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - if (__predict_true(nic_i != UINT_MAX)) { - ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i); - DBG_COUNTER_INC(rxd_flush); - } + ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i); + DBG_COUNTER_INC(rxd_flush); + return (0); } ___ svn-src-all@freebsd.org mailing list
svn commit: r365061 - in head/sys: dev/bnxt dev/mgb dev/vmware/vmxnet3 net
Author: vmaffione Date: Tue Sep 1 20:41:47 2020 New Revision: 365061 URL: https://svnweb.freebsd.org/changeset/base/365061 Log: iflib: leave only 1 receive descriptor unused The pidx argument of isc_rxd_flush() indicates which is the last valid receive descriptor to be used by the NIC. However, current code has multiple issues: - Intel drivers write pidx to their RDT register, which means that NICs will only use the descriptors up to pidx-1 (modulo ring size N), and won't actually use the one pointed by pidx. This does not break reception, but it is anyway confusing and suboptimal (the NIC will actually see only N-2 descriptors as available, rather than N-1). Other drivers (if_vmx, if_bnxt, if_mgb) adhere to this semantic). - The semantic used by Intel (RDT is one descriptor past the last valid one) is used by most (if not all) NICs, and it is also used on the TX side (also in iflib). Since iflib is not currently using this semantic for RX, it must decrement fl->ifl_pidx (modulo N) before calling isc_rxd_flush(), and then the per-driver callback implementation must increment the index again (to match the real semantic). This is confusing and suboptimal. - The iflib refill function is also called at initialization. However, in case the ring size is smaller than 128 (e.g. if_mgb), the refill function will actually prepare all the receive descriptors (N), without leaving one unused, as most of NICs assume (e.g. to avoid RDT to overrun RDH). I can speculate that the code looks like this right now because this issue showed up during testing (e.g. with if_mgb), and it was easy to workaround by decrementing pidx before isc_rxd_flush(). The goal of this change is to simplify the code (removing a bunch of instructions from the RX fast path), and to make the semantic of isc_rxd_flush() consistent across drivers. To achieve this, we: - change the semantics of the pidx argument to the usual one (that is the index one past the last valid one), so that both iflib and drivers avoid the decrement/increment dance. - fix the initialization code to prepare at most N-1 descriptors. Reviewed by: markj MFC after:2 weeks Differential Revision:https://reviews.freebsd.org/D26191 Modified: head/sys/dev/bnxt/bnxt_txrx.c head/sys/dev/mgb/if_mgb.c head/sys/dev/mgb/if_mgb.h head/sys/dev/vmware/vmxnet3/if_vmx.c head/sys/net/iflib.c Modified: head/sys/dev/bnxt/bnxt_txrx.c == --- head/sys/dev/bnxt/bnxt_txrx.c Tue Sep 1 20:13:50 2020 (r365060) +++ head/sys/dev/bnxt/bnxt_txrx.c Tue Sep 1 20:41:47 2020 (r365061) @@ -316,10 +316,9 @@ bnxt_isc_rxd_flush(void *sc, uint16_t rxqid, uint8_t f if (softc->rx_cp_rings[rxqid].cons != UINT32_MAX) BNXT_CP_IDX_DISABLE_DB(>rx_cp_rings[rxqid].ring, softc->rx_cp_rings[rxqid].cons); - /* We're given the last filled RX buffer here, not the next empty one */ - BNXT_RX_DB(rx_ring, RING_NEXT(rx_ring, pidx)); + BNXT_RX_DB(rx_ring, pidx); /* TODO: Cumulus+ doesn't need the double doorbell */ - BNXT_RX_DB(rx_ring, RING_NEXT(rx_ring, pidx)); + BNXT_RX_DB(rx_ring, pidx); return; } Modified: head/sys/dev/mgb/if_mgb.c == --- head/sys/dev/mgb/if_mgb.c Tue Sep 1 20:13:50 2020(r365060) +++ head/sys/dev/mgb/if_mgb.c Tue Sep 1 20:41:47 2020(r365061) @@ -1191,7 +1191,12 @@ mgb_isc_rxd_flush(void *xsc, uint16_t rxqid, uint8_t f sc = xsc; KASSERT(rxqid == 0, ("tried to flush RX Channel %d.\n", rxqid)); - sc->rx_ring_data.last_tail = pidx; + /* +* According to the programming guide, last_tail must be set to +* the last valid RX descriptor, rather than to the one past that. +* Note that this is not true for the TX ring! +*/ + sc->rx_ring_data.last_tail = MGB_PREV_RING_IDX(pidx); CSR_WRITE_REG(sc, MGB_DMA_RX_TAIL(rxqid), sc->rx_ring_data.last_tail); return; } Modified: head/sys/dev/mgb/if_mgb.h == --- head/sys/dev/mgb/if_mgb.h Tue Sep 1 20:13:50 2020(r365060) +++ head/sys/dev/mgb/if_mgb.h Tue Sep 1 20:41:47 2020(r365061) @@ -178,7 +178,8 @@ #define MGB_DESC_GET_FRAME_LEN(_desc) \ (((_desc)->ctl & MGB_DESC_FRAME_LEN_MASK) >> 16) -#define MGB_NEXT_RING_IDX(_idx)(((_idx) + 1) % MGB_DMA_RING_SIZE) +#define MGB_NEXT_RING_IDX(_idx)(((_idx) == MGB_DMA_RING_SIZE - 1) ? 0 : ((_idx_) + 1)) +#define MGB_PREV_RING_IDX(_idx)(((_idx) == 0) ? (MGB_DMA_RING_SIZE - 1) : ((_idx_) - 1)) #define
svn commit: r365023 - head/lib/libnetmap
Author: vmaffione Date: Tue Sep 1 06:06:32 2020 New Revision: 365023 URL: https://svnweb.freebsd.org/changeset/base/365023 Log: lib: libnetmap: add missing copyright headers MFC after:2 weeks Modified: head/lib/libnetmap/nmctx-pthreads.c head/lib/libnetmap/nmctx.c head/lib/libnetmap/nmport.c head/lib/libnetmap/nmreq.c Modified: head/lib/libnetmap/nmctx-pthreads.c == --- head/lib/libnetmap/nmctx-pthreads.c Tue Sep 1 04:37:55 2020 (r365022) +++ head/lib/libnetmap/nmctx-pthreads.c Tue Sep 1 06:06:32 2020 (r365023) @@ -1,4 +1,34 @@ -/* $FreeBSD$ */ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (C) 2018 Universita` di Pisa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + #include #include #include Modified: head/lib/libnetmap/nmctx.c == --- head/lib/libnetmap/nmctx.c Tue Sep 1 04:37:55 2020(r365022) +++ head/lib/libnetmap/nmctx.c Tue Sep 1 06:06:32 2020(r365023) @@ -1,4 +1,34 @@ -/* $FreeBSD$ */ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (C) 2018 Universita` di Pisa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + #include #include #include Modified: head/lib/libnetmap/nmport.c == --- head/lib/libnetmap/nmport.c Tue Sep 1 04:37:55 2020(r365022) +++ head/lib/libnetmap/nmport.c Tue Sep 1 06:06:32 2020(r365023) @@ -1,4 +1,34 @@ -/* $FreeBSD$ */ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (C) 2018 Universita` di Pisa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND
svn commit: r364936 - in head: lib lib/libnetmap share/mk
Author: vmaffione Date: Fri Aug 28 20:03:54 2020 New Revision: 364936 URL: https://svnweb.freebsd.org/changeset/base/364936 Log: lib: add libnetmap This changeset introduces the new libnetmap library for writing netmap applications. Before libnetmap, applications could either use the kernel API directly (e.g. NIOCREGIF/NIOCCTRL) or the simple header-only-library netmap_user.h (e.g. nm_open(), nm_close(), nm_mmap() etc.) The new library offers more functionalities than netmap_user.h: - Support for complex netmap options, such as external memory allocators or per-buffer offsets. This opens the way to future extensions. - More flexibility in the netmap port bind options, such as non-numeric names for pipes, or the ability to specify the netmap allocator that must be used for a given port. - Automatic tracking of the netmap memory regions in use across the open ports. At the moment there is no man page, but the libnetmap.h header file has in-depth documentation. Reviewed by: hrs MFC after:2 weeks Differential Revision:https://reviews.freebsd.org/D26171 Added: head/lib/libnetmap/ head/lib/libnetmap/Makefile (contents, props changed) head/lib/libnetmap/libnetmap.h (contents, props changed) head/lib/libnetmap/nmctx-pthreads.c (contents, props changed) head/lib/libnetmap/nmctx.c (contents, props changed) head/lib/libnetmap/nmport.c (contents, props changed) head/lib/libnetmap/nmreq.c (contents, props changed) Modified: head/lib/Makefile head/share/mk/bsd.libnames.mk head/share/mk/src.libnames.mk Modified: head/lib/Makefile == --- head/lib/Makefile Fri Aug 28 19:59:02 2020(r364935) +++ head/lib/Makefile Fri Aug 28 20:03:54 2020(r364936) @@ -71,6 +71,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \ libmt \ lib80211 \ libnetbsd \ + libnetmap \ libnv \ libopenbsd \ libopie \ Added: head/lib/libnetmap/Makefile == --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libnetmap/Makefile Fri Aug 28 20:03:54 2020(r364936) @@ -0,0 +1,16 @@ +# +# $FreeBSD$ +# + +.include + +PACKAGE= lib${LIB} +LIB= netmap +SRCS= nmctx.c nmport.c \ + nmctx-pthreads.c nmreq.c +INCS= libnetmap.h +#MAN= libnetmap.3 +CFLAGS+= -I${SRCTOP}/sys/net -I${.CURDIR} +WARNS?=2 + +.include Added: head/lib/libnetmap/libnetmap.h == --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libnetmap/libnetmap.h Fri Aug 28 20:03:54 2020 (r364936) @@ -0,0 +1,660 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (C) 2018 Universita` di Pisa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * $FreeBSD$ + */ + +#ifndef LIBNETMAP_H_ +#define LIBNETMAP_H_ +/* if thread-safety is not needed, define LIBNETMAP_NOTHREADSAFE before including + * this file. + */ + +/* NOTE: we include net/netmap_user.h without defining NETMAP_WITH_LIBS, which + * is deprecated. If you still need it, please define NETMAP_WITH_LIBS and + * include net/netmap_user.h before including this file. + */ +#include + +struct nmctx; +struct nmport_d; +struct nmem_d; + +/* + * A port open specification (portspec for brevity) has the following syntax + * (square brackets delimit optional parts): + * + *
svn commit: r364878 - stable/12/sys/dev/e1000
Author: vmaffione Date: Thu Aug 27 19:12:39 2020 New Revision: 364878 URL: https://svnweb.freebsd.org/changeset/base/364878 Log: MFC r363995 em(4): honor vlanhwtag offload The FreeBSD em driver fails to properly reset the VME flag in the e1000 CTRL register oneg the following ifconfig command ifconfig em1 -vlanhwtag Tested on the e1000 device emulated by QEMU, and on a real NIC (chip=0x10d38086). PR: 236584 Submitted by:mu...@sunnyvalley.io Reported by: mu...@sunnyvalley.io Differential Revision: https://reviews.freebsd.org/D25286 Modified: stable/12/sys/dev/e1000/if_em.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/e1000/if_em.c == --- stable/12/sys/dev/e1000/if_em.c Thu Aug 27 17:46:13 2020 (r364877) +++ stable/12/sys/dev/e1000/if_em.c Thu Aug 27 19:12:39 2020 (r364878) @@ -1330,6 +1330,11 @@ em_if_init(if_ctx_t ctx) ctrl |= E1000_CTRL_VME; E1000_WRITE_REG(>hw, E1000_CTRL, ctrl); } + } else { + u32 ctrl; + ctrl = E1000_READ_REG(>hw, E1000_CTRL); + ctrl &= ~E1000_CTRL_VME; + E1000_WRITE_REG(>hw, E1000_CTRL, ctrl); } /* Don't lose promiscuous settings */ ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r364879 - stable/11/sys/dev/e1000
Author: vmaffione Date: Thu Aug 27 19:15:09 2020 New Revision: 364879 URL: https://svnweb.freebsd.org/changeset/base/364879 Log: MFC r363995 em(4): honor vlanhwtag offload The FreeBSD em driver fails to properly reset the VME flag in the e1000 CTRL register oneg the following ifconfig command ifconfig em1 -vlanhwtag Tested on the e1000 device emulated by QEMU, and on a real NIC (chip=0x10d38086). PR: 236584 Submitted by:mu...@sunnyvalley.io Reported by: mu...@sunnyvalley.io Differential Revision: https://reviews.freebsd.org/D25286 Modified: stable/11/sys/dev/e1000/if_em.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/e1000/if_em.c == --- stable/11/sys/dev/e1000/if_em.c Thu Aug 27 19:12:39 2020 (r364878) +++ stable/11/sys/dev/e1000/if_em.c Thu Aug 27 19:15:09 2020 (r364879) @@ -1451,6 +1451,11 @@ em_init_locked(struct adapter *adapter) ctrl |= E1000_CTRL_VME; E1000_WRITE_REG(>hw, E1000_CTRL, ctrl); } + } else { + u32 ctrl; + ctrl = E1000_READ_REG(>hw, E1000_CTRL); + ctrl &= ~E1000_CTRL_VME; + E1000_WRITE_REG(>hw, E1000_CTRL, ctrl); } /* Don't lose promiscuous settings */ ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r364770 - head/sys/net
Author: vmaffione Date: Tue Aug 25 15:19:45 2020 New Revision: 364770 URL: https://svnweb.freebsd.org/changeset/base/364770 Log: iflib: netmap: publish all the receive buffer At initialization time, the netmap RX refill function used to prepare the NIC RX ring with N-1 buffers rather than N (with N equal to the number of descriptors in the NIC RX ring). This is not how netmap is supposed to work, as it would keep kring->nr_hwcur not in sync with the NIC "next index to refill" (i.e., fl->ifl_pidx). Instead we prepare N buffers, although we still publish (with isc_rxd_flush()) only the first N-1 buffers, to avoid the NIC producer pointer to overrun the NIC consumer pointer (for NICs where this is a real issue, e.g. Intel ones). MFC after:2 weeks Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cTue Aug 25 14:18:50 2020(r364769) +++ head/sys/net/iflib.cTue Aug 25 15:19:45 2020(r364770) @@ -832,7 +832,6 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring { struct netmap_adapter *na = kring->na; u_int const lim = kring->nkr_num_slots - 1; - u_int head = kring->rhead; u_int nm_i = kring->nr_hwcur; struct netmap_ring *ring = kring->ring; bus_dmamap_t *map; @@ -840,39 +839,46 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring if_ctx_t ctx = rxq->ifr_ctx; iflib_fl_t fl = >ifr_fl[0]; u_int nic_i_first, nic_i; - int i; + int i, n; #if IFLIB_DEBUG_COUNTERS int rf_count = 0; #endif /* -* Netmap requires that we leave (at least) one free slot -* in the ring, so that it can distinguish between an empty -* ring (nr_hwcur == nr_hwtail, i.e. all the buffers owned by the -* user) and a full ring (nr_hwtail == (nr_hwcur - 1) mod N, i.e. -* all the buffers owned by the kernel). -* We thus set head (the refill limit) to nr_hwcur - 1 -* at initialization. The rest of the code will then make sure -* than nr_hwtail never overcomes nr_hwcur. +* This function is used both at initialization and in rxsync. +* At initialization we need to prepare (with isc_rxd_refill()) +* all the (N) netmap buffers in the ring, in such a way to keep +* fl->ifl_pidx and kring->nr_hwcur in sync (except for +* kring->nkr_hwofs); at rxsync time, both indexes point to the +* next buffer to be refilled. +* In any case we publish (with isc_rxd_flush()) up to +* (fl->ifl_pidx - 1) % N (included), to avoid the NIC tail/prod +* pointer to overrun the head/cons pointer, although this is +* not necessary for some NICs (e.g. vmx). */ - if (__predict_false(init)) { - head = nm_prev(nm_i, lim); - } else if (nm_i == head) { - /* Nothing to do. We can leave early. */ - return (0); + if (__predict_false(init)) + n = kring->nkr_num_slots; + else { + n = kring->rhead - nm_i; + if (n == 0) + return (0); /* Nothing to do. */ + if (n < 0) + n += kring->nkr_num_slots; } + /* Start to refill from nr_hwcur, publishing n buffers. */ iru_init(, rxq, 0 /* flid */); map = fl->ifl_sds.ifsd_map; - nic_i = netmap_idx_k2n(kring, nm_i); + nic_i = fl->ifl_pidx; + MPASS(nic_i == netmap_idx_k2n(kring, nm_i)); DBG_COUNTER_INC(fl_refills); - while (nm_i != head) { + while (n > 0) { #if IFLIB_DEBUG_COUNTERS if (++rf_count == 9) DBG_COUNTER_INC(fl_refills_large); #endif nic_i_first = nic_i; - for (i = 0; i < IFLIB_MAX_RX_REFRESH && nm_i != head; i++) { + for (i = 0; n > 0 && i < IFLIB_MAX_RX_REFRESH; n--, i++) { struct netmap_slot *slot = >slot[nm_i]; void *addr = PNMB(na, slot, >ifl_bus_addrs[i]); @@ -903,11 +909,11 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring iru.iru_count = i; ctx->isc_rxd_refill(ctx->ifc_softc, ); } - kring->nr_hwcur = head; + fl->ifl_pidx = nic_i; + MPASS(!init || nm_i == 0); + MPASS(nm_i == kring->rhead); + kring->nr_hwcur = nm_i; - /* The pidx argument of isc_rxd_flush() is the index of the last valid -* slot in the free list ring. We need therefore to decrement nic_i, -* similarly to what happens in iflib_fl_refill() for ifl_pidx. */ bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id,
svn commit: r364756 - stable/11/sys/dev/netmap
Author: vmaffione Date: Tue Aug 25 11:12:30 2020 New Revision: 364756 URL: https://svnweb.freebsd.org/changeset/base/364756 Log: MFC r364341 netmap: fix parsing of legacy nmr->nr_ringid Code was checking for NETMAP_{SW,HW}_RING in req->nr_ringid which had already been masked by NETMAP_RING_MASK. Therefore, the comparisons always failed and set NR_REG_ALL_NIC. Check against the original nmr structure. Submitted by: bpo...@packetforensics.com Reported by:bpo...@packetforensics.com Reviewed by:giuseppe.letti...@unipi.it Approved by:vmaffione Modified: stable/11/sys/dev/netmap/netmap_legacy.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/netmap/netmap_legacy.c == --- stable/11/sys/dev/netmap/netmap_legacy.cTue Aug 25 11:10:37 2020 (r364755) +++ stable/11/sys/dev/netmap/netmap_legacy.cTue Aug 25 11:12:30 2020 (r364756) @@ -71,9 +71,9 @@ nmreq_register_from_legacy(struct nmreq *nmr, struct n /* Convert the older nmr->nr_ringid (original * netmap control API) to nmr->nr_flags. */ u_int regmode = NR_REG_DEFAULT; - if (req->nr_ringid & NETMAP_SW_RING) { + if (nmr->nr_ringid & NETMAP_SW_RING) { regmode = NR_REG_SW; - } else if (req->nr_ringid & NETMAP_HW_RING) { + } else if (nmr->nr_ringid & NETMAP_HW_RING) { regmode = NR_REG_ONE_NIC; } else { regmode = NR_REG_ALL_NIC; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r364755 - stable/12/sys/dev/netmap
Author: vmaffione Date: Tue Aug 25 11:10:37 2020 New Revision: 364755 URL: https://svnweb.freebsd.org/changeset/base/364755 Log: MFC r364341 netmap: fix parsing of legacy nmr->nr_ringid Code was checking for NETMAP_{SW,HW}_RING in req->nr_ringid which had already been masked by NETMAP_RING_MASK. Therefore, the comparisons always failed and set NR_REG_ALL_NIC. Check against the original nmr structure. Submitted by: bpo...@packetforensics.com Reported by:bpo...@packetforensics.com Reviewed by:giuseppe.letti...@unipi.it Approved by:vmaffione This line, and those below, will be ignored-- > Description of fields to fill in above: 76 columns --| > PR: If and which Problem Report is related. > Submitted by: If someone else sent in the change. > Reported by: If someone else reported the issue. > Reviewed by: If someone else reviewed your modification. > Approved by: If you needed approval for this commit. > Obtained from:If the change is from a third party. > MFC after:N [day[s]|week[s]|month[s]]. Request a reminder email. > MFH: Ports tree branch name. Request approval for merge. > Relnotes: Set to 'yes' for mention in release notes. > Security: Vulnerability reference (one per line) or description. > Sponsored by: If the change was sponsored by an organization. > Pull Request: https://github.com/freebsd/freebsd/pull/### (*full* GitHub URL needed). > Differential Revision:https://reviews.freebsd.org/D### (*full* phabric URL needed). > Empty fields above will be automatically removed. _M . Msys/dev/netmap/netmap_legacy.c Modified: stable/12/sys/dev/netmap/netmap_legacy.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/netmap/netmap_legacy.c == --- stable/12/sys/dev/netmap/netmap_legacy.cTue Aug 25 09:42:03 2020 (r364754) +++ stable/12/sys/dev/netmap/netmap_legacy.cTue Aug 25 11:10:37 2020 (r364755) @@ -76,9 +76,9 @@ nmreq_register_from_legacy(struct nmreq *nmr, struct n /* Convert the older nmr->nr_ringid (original * netmap control API) to nmr->nr_flags. */ u_int regmode = NR_REG_DEFAULT; - if (req->nr_ringid & NETMAP_SW_RING) { + if (nmr->nr_ringid & NETMAP_SW_RING) { regmode = NR_REG_SW; - } else if (req->nr_ringid & NETMAP_HW_RING) { + } else if (nmr->nr_ringid & NETMAP_HW_RING) { regmode = NR_REG_ONE_NIC; } else { regmode = NR_REG_ALL_NIC; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r364731 - head/sys/dev/netmap
Author: vmaffione Date: Mon Aug 24 20:28:21 2020 New Revision: 364731 URL: https://svnweb.freebsd.org/changeset/base/364731 Log: netmap: use FreeBSD guards for epoch calls EPOCH calls are FreeBSD specific. Use guards to protect these, so that the code can compile under Linux. MFC after:1 week Modified: head/sys/dev/netmap/netmap.c Modified: head/sys/dev/netmap/netmap.c == --- head/sys/dev/netmap/netmap.cMon Aug 24 20:23:34 2020 (r364730) +++ head/sys/dev/netmap/netmap.cMon Aug 24 20:28:21 2020 (r364731) @@ -1149,11 +1149,13 @@ netmap_dtor(void *data) static void netmap_send_up(struct ifnet *dst, struct mbq *q) { - struct epoch_tracker et; struct mbuf *m; struct mbuf *head = NULL, *prev = NULL; +#ifdef __FreeBSD__ + struct epoch_tracker et; NET_EPOCH_ENTER(et); +#endif /* __FreeBSD__ */ /* Send packets up, outside the lock; head/prev machinery * is only useful for Windows. */ while ((m = mbq_dequeue(q)) != NULL) { @@ -1165,7 +1167,9 @@ netmap_send_up(struct ifnet *dst, struct mbq *q) } if (head) nm_os_send_up(dst, NULL, head); +#ifdef __FreeBSD__ NET_EPOCH_EXIT(et); +#endif /* __FreeBSD__ */ mbq_fini(q); } ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r364655 - head/sys/net
Author: vmaffione Date: Mon Aug 24 11:44:20 2020 New Revision: 364655 URL: https://svnweb.freebsd.org/changeset/base/364655 Log: iflib: fix isc_rxd_flush call in netmap_fl_refill() The semantic of the pidx argument of isc_rxd_flush() is the last valid index of in the free list, rather than the next index to be published. However, netmap was still using the old convention. While there, also refactor the netmap_fl_refill() to simplify a little bit and add an assertion. MFC after:2 weeks Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cMon Aug 24 10:46:09 2020(r364654) +++ head/sys/net/iflib.cMon Aug 24 11:44:20 2020(r364655) @@ -757,7 +757,7 @@ iflib_num_tx_descs(if_ctx_t ctx) MODULE_DEPEND(iflib, netmap, 1, 1, 1); -static int netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, bool init); +static int netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, bool init); /* * device-specific sysctl variables: @@ -828,33 +828,43 @@ iflib_netmap_register(struct netmap_adapter *na, int o } static int -netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, bool init) +netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, bool init) { struct netmap_adapter *na = kring->na; u_int const lim = kring->nkr_num_slots - 1; u_int head = kring->rhead; + u_int nm_i = kring->nr_hwcur; struct netmap_ring *ring = kring->ring; bus_dmamap_t *map; struct if_rxd_update iru; if_ctx_t ctx = rxq->ifr_ctx; iflib_fl_t fl = >ifr_fl[0]; - uint32_t nic_i_first, nic_i; + u_int nic_i_first, nic_i; int i; #if IFLIB_DEBUG_COUNTERS int rf_count = 0; #endif - if (nm_i == head && __predict_true(!init)) + /* +* Netmap requires that we leave (at least) one free slot +* in the ring, so that it can distinguish between an empty +* ring (nr_hwcur == nr_hwtail, i.e. all the buffers owned by the +* user) and a full ring (nr_hwtail == (nr_hwcur - 1) mod N, i.e. +* all the buffers owned by the kernel). +* We thus set head (the refill limit) to nr_hwcur - 1 +* at initialization. The rest of the code will then make sure +* than nr_hwtail never overcomes nr_hwcur. +*/ + if (__predict_false(init)) { + head = nm_prev(nm_i, lim); + } else if (nm_i == head) { + /* Nothing to do. We can leave early. */ return (0); + } iru_init(, rxq, 0 /* flid */); map = fl->ifl_sds.ifsd_map; nic_i = netmap_idx_k2n(kring, nm_i); - /* -* IMPORTANT: we must leave one free slot in the ring, -* so move head back by one unit -*/ - head = nm_prev(head, lim); DBG_COUNTER_INC(fl_refills); while (nm_i != head) { #if IFLIB_DEBUG_COUNTERS @@ -895,9 +905,13 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring } kring->nr_hwcur = head; + /* The pidx argument of isc_rxd_flush() is the index of the last valid +* slot in the free list ring. We need therefore to decrement nic_i, +* similarly to what happens in iflib_fl_refill() for ifl_pidx. */ bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i); + ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, + nm_prev(nic_i, lim)); DBG_COUNTER_INC(rxd_flush); return (0); @@ -1127,6 +1141,7 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl nic_i = fl->ifl_cidx; nm_i = netmap_idx_n2k(kring, nic_i); + MPASS(nm_i == kring->nr_hwtail); for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { rxd_info_zero(); ri.iri_frags = rxq->ifr_frags; @@ -1165,9 +1180,9 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl * nic_i is the index in the NIC ring, and * nm_i == (nic_i + kring->nkr_hwofs) % ring_size */ - nm_i = kring->nr_hwcur; + netmap_fl_refill(rxq, kring, false); - return (netmap_fl_refill(rxq, kring, nm_i, false)); + return (0); } static void @@ -1239,14 +1254,12 @@ iflib_netmap_rxq_init(if_ctx_t ctx, iflib_rxq_t rxq) struct netmap_adapter *na = NA(ctx->ifc_ifp); struct netmap_kring *kring; struct netmap_slot *slot; - uint32_t nm_i; slot = netmap_reset(na, NR_RX, rxq->ifr_id, 0); if (slot == NULL) return (0); kring = na->rx_rings[rxq->ifr_id]; - nm_i = netmap_idx_n2k(kring, 0); -
svn commit: r364452 - stable/12/sys/net
Author: vmaffione Date: Fri Aug 21 07:54:16 2020 New Revision: 364452 URL: https://svnweb.freebsd.org/changeset/base/364452 Log: MFC r363997 iflib: netmap: drop redundant check The validity of head is already checked by nm_rxsync_prologue(). Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Fri Aug 21 07:52:56 2020(r364451) +++ stable/12/sys/net/iflib.c Fri Aug 21 07:54:16 2020(r364452) @@ -1085,16 +1085,12 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl uint32_t nic_i; /* index into the NIC ring */ u_int n; u_int const lim = kring->nkr_num_slots - 1; - u_int const head = kring->rhead; int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; if_ctx_t ctx = ifp->if_softc; iflib_rxq_t rxq = >ifc_rxqs[kring->ring_id]; iflib_fl_t fl = >ifr_fl[0]; struct if_rxd_info ri; - - if (head > lim) - return netmap_ring_reinit(kring); /* * netmap only uses free list 0, to avoid out of order consumption ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r364451 - stable/12/sys/net
Author: vmaffione Date: Fri Aug 21 07:52:56 2020 New Revision: 364451 URL: https://svnweb.freebsd.org/changeset/base/364451 Log: MFC r363996 iflib: netmap: don't increment ifl_cidx on the wrong free list Netmap only uses free list 0 to keep it consistent with its one-to-one mapping between each netmap ring and a device RX (or TX) queue. However, the current iflib_netmap_rxsync() routine was mistakenly updating the ifl_cidx field of both free lists. PR: 248494 Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Fri Aug 21 07:03:54 2020(r364450) +++ stable/12/sys/net/iflib.c Fri Aug 21 07:52:56 2020(r364451) @@ -1081,28 +1081,28 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl struct netmap_adapter *na = kring->na; struct netmap_ring *ring = kring->ring; if_t ifp = na->ifp; - iflib_fl_t fl; uint32_t nm_i; /* index into the netmap ring */ uint32_t nic_i; /* index into the NIC ring */ - u_int i, n; + u_int n; u_int const lim = kring->nkr_num_slots - 1; u_int const head = kring->rhead; int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; - struct if_rxd_info ri; if_ctx_t ctx = ifp->if_softc; iflib_rxq_t rxq = >ifc_rxqs[kring->ring_id]; + iflib_fl_t fl = >ifr_fl[0]; + struct if_rxd_info ri; + if (head > lim) return netmap_ring_reinit(kring); /* -* XXX netmap_fl_refill() only ever (re)fills free list 0 so far. +* netmap only uses free list 0, to avoid out of order consumption +* of receive buffers */ - for (i = 0, fl = rxq->ifr_fl; i < rxq->ifr_nfl; i++, fl++) { - bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - } + bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); /* * First part: import newly received packets. @@ -1124,38 +1124,35 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl int crclen = iflib_crcstrip ? 0 : 4; int error, avail; - for (i = 0; i < rxq->ifr_nfl; i++) { - fl = >ifr_fl[i]; - nic_i = fl->ifl_cidx; - nm_i = netmap_idx_n2k(kring, nic_i); - avail = ctx->isc_rxd_available(ctx->ifc_softc, - rxq->ifr_id, nic_i, USHRT_MAX); - for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { - rxd_info_zero(); - ri.iri_frags = rxq->ifr_frags; - ri.iri_qsidx = kring->ring_id; - ri.iri_ifp = ctx->ifc_ifp; - ri.iri_cidx = nic_i; + nic_i = fl->ifl_cidx; + nm_i = netmap_idx_n2k(kring, nic_i); + avail = ctx->isc_rxd_available(ctx->ifc_softc, + rxq->ifr_id, nic_i, USHRT_MAX); + for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { + rxd_info_zero(); + ri.iri_frags = rxq->ifr_frags; + ri.iri_qsidx = kring->ring_id; + ri.iri_ifp = ctx->ifc_ifp; + ri.iri_cidx = nic_i; - error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, ); - ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen; - ring->slot[nm_i].flags = 0; - bus_dmamap_sync(fl->ifl_buf_tag, - fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD); - nm_i = nm_next(nm_i, lim); - nic_i = nm_next(nic_i, lim); + error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, ); + ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen; + ring->slot[nm_i].flags = 0; + bus_dmamap_sync(fl->ifl_buf_tag, + fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD); + nm_i = nm_next(nm_i, lim); + nic_i = nm_next(nic_i, lim); + } + if (n) { /* update the state variables */ + if (netmap_no_pendintr && !force_update) { + /* diagnostics */ + iflib_rx_miss ++; + iflib_rx_miss_bufs += n; } -
svn commit: r364341 - head/sys/dev/netmap
Author: vmaffione Date: Tue Aug 18 08:03:28 2020 New Revision: 364341 URL: https://svnweb.freebsd.org/changeset/base/364341 Log: netmap: fix parsing of legacy nmr->nr_ringid Code was checking for NETMAP_{SW,HW}_RING in req->nr_ringid which had already been masked by NETMAP_RING_MASK. Therefore, the comparisons always failed and set NR_REG_ALL_NIC. Check against the original nmr structure. Submitted by: bpo...@packetforensics.com Reported by: bpo...@packetforensics.com Reviewed by: giuseppe.letti...@unipi.it Approved by: vmaffione MFC after:1 week Modified: head/sys/dev/netmap/netmap_legacy.c Modified: head/sys/dev/netmap/netmap_legacy.c == --- head/sys/dev/netmap/netmap_legacy.c Tue Aug 18 07:23:47 2020 (r364340) +++ head/sys/dev/netmap/netmap_legacy.c Tue Aug 18 08:03:28 2020 (r364341) @@ -76,9 +76,9 @@ nmreq_register_from_legacy(struct nmreq *nmr, struct n /* Convert the older nmr->nr_ringid (original * netmap control API) to nmr->nr_flags. */ u_int regmode = NR_REG_DEFAULT; - if (req->nr_ringid & NETMAP_SW_RING) { + if (nmr->nr_ringid & NETMAP_SW_RING) { regmode = NR_REG_SW; - } else if (req->nr_ringid & NETMAP_HW_RING) { + } else if (nmr->nr_ringid & NETMAP_HW_RING) { regmode = NR_REG_ONE_NIC; } else { regmode = NR_REG_ALL_NIC; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r364165 - head/sys/net
Author: vmaffione Date: Wed Aug 12 14:45:31 2020 New Revision: 364165 URL: https://svnweb.freebsd.org/changeset/base/364165 Log: iflib: netmap: improve rxsync to support IFLIB_HAS_RXCQ For drivers with IFLIB_HAS_RXCQ set, there is a separate completion queue. In this case, the netmap rxsync routine needs to update rxq->ifr_cq_cidx in the same way it is updated by iflib_rxeof(). This improves the situation for vmx(4) and bnxt(4) drivers, which use iflib and have the IFLIB_HAS_RXCQ bit set. PR: 248494 MFC after:3 weeks Modified: head/sys/net/iflib.c head/sys/net/iflib.h Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cWed Aug 12 14:17:38 2020(r364164) +++ head/sys/net/iflib.cWed Aug 12 14:45:31 2020(r364165) @@ -424,7 +424,7 @@ struct iflib_rxq { struct pfil_head*pfil; /* * If there is a separate completion queue (IFLIB_HAS_RXCQ), this is -* the command queue consumer index. Otherwise it's unused. +* the completion queue consumer index. Otherwise it's unused. */ qidx_t ifr_cq_cidx; uint16_tifr_id; @@ -1077,9 +1077,12 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; if_ctx_t ctx = ifp->if_softc; + if_shared_ctx_t sctx = ctx->ifc_sctx; + if_softc_ctx_t scctx = >ifc_softc_ctx; iflib_rxq_t rxq = >ifc_rxqs[kring->ring_id]; iflib_fl_t fl = >ifr_fl[0]; struct if_rxd_info ri; + qidx_t *cidxp; /* * netmap only uses free list 0, to avoid out of order consumption @@ -1093,40 +1096,56 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl * First part: import newly received packets. * * nm_i is the index of the next free slot in the netmap ring, -* nic_i is the index of the next received packet in the NIC ring, -* and they may differ in case if_init() has been called while +* nic_i is the index of the next received packet in the NIC ring +* (or in the free list 0 if IFLIB_HAS_RXCQ is set), and they may +* differ in case if_init() has been called while * in netmap mode. For the receive ring we have * -* nic_i = rxr->next_check; +* nic_i = fl->ifl_cidx; * nm_i = kring->nr_hwtail (previous) * and * nm_i == (nic_i + kring->nkr_hwofs) % ring_size * -* rxr->next_check is set to 0 on a ring reinit +* fl->ifl_cidx is set to 0 on a ring reinit */ if (netmap_no_pendintr || force_update) { uint32_t hwtail_lim = nm_prev(kring->nr_hwcur, lim); + bool have_rxcq = sctx->isc_flags & IFLIB_HAS_RXCQ; int crclen = iflib_crcstrip ? 0 : 4; int error, avail; + /* +* For the free list consumer index, we use the same +* logic as in iflib_rxeof(). +*/ + if (have_rxcq) + cidxp = >ifr_cq_cidx; + else + cidxp = >ifl_cidx; + avail = ctx->isc_rxd_available(ctx->ifc_softc, + rxq->ifr_id, *cidxp, USHRT_MAX); + nic_i = fl->ifl_cidx; nm_i = netmap_idx_n2k(kring, nic_i); - avail = ctx->isc_rxd_available(ctx->ifc_softc, - rxq->ifr_id, nic_i, USHRT_MAX); for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { rxd_info_zero(); ri.iri_frags = rxq->ifr_frags; ri.iri_qsidx = kring->ring_id; ri.iri_ifp = ctx->ifc_ifp; - ri.iri_cidx = nic_i; + ri.iri_cidx = *cidxp; error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, ); ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen; ring->slot[nm_i].flags = 0; + if (have_rxcq) { + *cidxp = ri.iri_cidx; + while (*cidxp >= scctx->isc_nrxd[0]) + *cidxp -= scctx->isc_nrxd[0]; + } bus_dmamap_sync(fl->ifl_buf_tag, fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD); nm_i = nm_next(nm_i, lim); - nic_i = nm_next(nic_i, lim); + fl->ifl_cidx = nic_i = nm_next(nic_i, lim); } if (n) { /* update the state variables */ if (netmap_no_pendintr && !force_update) { @@ -1134,7 +1153,6 @@ iflib_netmap_rxsync(struct
svn commit: r364164 - head/sys/net
Author: vmaffione Date: Wed Aug 12 14:17:38 2020 New Revision: 364164 URL: https://svnweb.freebsd.org/changeset/base/364164 Log: iflib: refactor netmap_fl_refill and fix off-by-one issue First, fix the initialization of the fl->ifl_rxd_idxs array, which was affected by an off-by-one bug. Once there, refactor the function to use better names for local variables, optimize the variable assignments, and merge the bus_dmamap_sync() inner loop with the outer one. PR: 248494 MFC after:3 weeks Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cWed Aug 12 12:11:44 2020(r364163) +++ head/sys/net/iflib.cWed Aug 12 14:17:38 2020(r364164) @@ -838,39 +838,41 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring struct if_rxd_update iru; if_ctx_t ctx = rxq->ifr_ctx; iflib_fl_t fl = >ifr_fl[0]; - uint32_t refill_pidx, nic_i; + uint32_t nic_i_first, nic_i; + int i; #if IFLIB_DEBUG_COUNTERS int rf_count = 0; #endif if (nm_i == head && __predict_true(!init)) - return 0; + return (0); + iru_init(, rxq, 0 /* flid */); map = fl->ifl_sds.ifsd_map; - refill_pidx = netmap_idx_k2n(kring, nm_i); + nic_i = netmap_idx_k2n(kring, nm_i); /* * IMPORTANT: we must leave one free slot in the ring, * so move head back by one unit */ head = nm_prev(head, lim); - nic_i = UINT_MAX; DBG_COUNTER_INC(fl_refills); while (nm_i != head) { #if IFLIB_DEBUG_COUNTERS if (++rf_count == 9) DBG_COUNTER_INC(fl_refills_large); #endif - for (int tmp_pidx = 0; tmp_pidx < IFLIB_MAX_RX_REFRESH && nm_i != head; tmp_pidx++) { + nic_i_first = nic_i; + for (i = 0; i < IFLIB_MAX_RX_REFRESH && nm_i != head; i++) { struct netmap_slot *slot = >slot[nm_i]; - void *addr = PNMB(na, slot, >ifl_bus_addrs[tmp_pidx]); - uint32_t nic_i_dma = refill_pidx; - nic_i = netmap_idx_k2n(kring, nm_i); + void *addr = PNMB(na, slot, >ifl_bus_addrs[i]); - MPASS(tmp_pidx < IFLIB_MAX_RX_REFRESH); + MPASS(i < IFLIB_MAX_RX_REFRESH); if (addr == NETMAP_BUF_BASE(na)) /* bad buf */ return netmap_ring_reinit(kring); + fl->ifl_rxd_idxs[i] = nic_i; + if (__predict_false(init)) { netmap_load_map(na, fl->ifl_buf_tag, map[nic_i], addr); @@ -879,33 +881,25 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring netmap_reload_map(na, fl->ifl_buf_tag, map[nic_i], addr); } + bus_dmamap_sync(fl->ifl_buf_tag, map[nic_i], + BUS_DMASYNC_PREREAD); slot->flags &= ~NS_BUF_CHANGED; nm_i = nm_next(nm_i, lim); - fl->ifl_rxd_idxs[tmp_pidx] = nic_i = nm_next(nic_i, lim); - if (nm_i != head && tmp_pidx < IFLIB_MAX_RX_REFRESH-1) - continue; - - iru.iru_pidx = refill_pidx; - iru.iru_count = tmp_pidx+1; - ctx->isc_rxd_refill(ctx->ifc_softc, ); - refill_pidx = nic_i; - for (int n = 0; n < iru.iru_count; n++) { - bus_dmamap_sync(fl->ifl_buf_tag, map[nic_i_dma], - BUS_DMASYNC_PREREAD); - /* XXX - change this to not use the netmap func*/ - nic_i_dma = nm_next(nic_i_dma, lim); - } + nic_i = nm_next(nic_i, lim); } + + iru.iru_pidx = nic_i_first; + iru.iru_count = i; + ctx->isc_rxd_refill(ctx->ifc_softc, ); } kring->nr_hwcur = head; bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - if (__predict_true(nic_i != UINT_MAX)) { - ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i); - DBG_COUNTER_INC(rxd_flush); - } + ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i); + DBG_COUNTER_INC(rxd_flush); + return (0); } ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send
svn commit: r364085 - stable/12/sys/net
Author: vmaffione Date: Mon Aug 10 17:53:09 2020 New Revision: 364085 URL: https://svnweb.freebsd.org/changeset/base/364085 Log: MFC r363378 iflib: initialize netmap with the correct number of descriptors In case the network device has a RX or TX control queue, the correct number of TX/RX descriptors is contained in the second entry of the isc_ntxd (or isc_nrxd) array, rather than in the first entry. This case is correctly handled by iflib_device_register() and iflib_pseudo_register(), but not by iflib_netmap_attach(). If the first entry is larger than the second, this can result in a panic. This change fixes the bug by introducing two helper functions that also lead to some code simplification. PR: 247647 Differential Revision: https://reviews.freebsd.org/D25541 Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Mon Aug 10 17:35:58 2020(r364084) +++ stable/12/sys/net/iflib.c Mon Aug 10 17:53:09 2020(r364085) @@ -735,6 +735,26 @@ MTX_SYSINIT(iflib_cpu_offset, _offset_mtx, "iflib_ NETDUMP_DEFINE(iflib); +static int +iflib_num_rx_descs(if_ctx_t ctx) +{ + if_softc_ctx_t scctx = >ifc_softc_ctx; + if_shared_ctx_t sctx = ctx->ifc_sctx; + uint16_t first_rxq = (sctx->isc_flags & IFLIB_HAS_RXCQ) ? 1 : 0; + + return scctx->isc_nrxd[first_rxq]; +} + +static int +iflib_num_tx_descs(if_ctx_t ctx) +{ + if_softc_ctx_t scctx = >ifc_softc_ctx; + if_shared_ctx_t sctx = ctx->ifc_sctx; + uint16_t first_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0; + + return scctx->isc_ntxd[first_txq]; +} + #ifdef DEV_NETMAP #include #include @@ -1170,7 +1190,6 @@ static int iflib_netmap_attach(if_ctx_t ctx) { struct netmap_adapter na; - if_softc_ctx_t scctx = >ifc_softc_ctx; bzero(, sizeof(na)); @@ -1179,8 +1198,8 @@ iflib_netmap_attach(if_ctx_t ctx) MPASS(ctx->ifc_softc_ctx.isc_ntxqsets); MPASS(ctx->ifc_softc_ctx.isc_nrxqsets); - na.num_tx_desc = scctx->isc_ntxd[0]; - na.num_rx_desc = scctx->isc_nrxd[0]; + na.num_tx_desc = iflib_num_tx_descs(ctx); + na.num_rx_desc = iflib_num_rx_descs(ctx); na.nm_txsync = iflib_netmap_txsync; na.nm_rxsync = iflib_netmap_rxsync; na.nm_register = iflib_netmap_register; @@ -4570,7 +4589,7 @@ iflib_device_register(device_t dev, void *sc, if_share kobjop_desc_t kobj_desc; kobj_method_t *kobj_method; int err, msix, rid; - uint16_t main_rxq, main_txq; + int num_txd, num_rxd; ctx = malloc(sizeof(* ctx), M_IFLIB, M_WAITOK|M_ZERO); @@ -4615,21 +4634,20 @@ iflib_device_register(device_t dev, void *sc, if_share if (scctx->isc_nrxqsets == 0 || (scctx->isc_nrxqsets_max && scctx->isc_nrxqsets_max < scctx->isc_nrxqsets)) scctx->isc_nrxqsets = scctx->isc_nrxqsets_max; - main_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0; - main_rxq = (sctx->isc_flags & IFLIB_HAS_RXCQ) ? 1 : 0; + num_txd = iflib_num_tx_descs(ctx); + num_rxd = iflib_num_rx_descs(ctx); /* XXX change for per-queue sizes */ device_printf(dev, "Using %d TX descriptors and %d RX descriptors\n", - scctx->isc_ntxd[main_txq], scctx->isc_nrxd[main_rxq]); + num_txd, num_rxd); - if (scctx->isc_tx_nsegments > scctx->isc_ntxd[main_txq] / - MAX_SINGLE_PACKET_FRACTION) - scctx->isc_tx_nsegments = max(1, scctx->isc_ntxd[main_txq] / + if (scctx->isc_tx_nsegments > num_txd / MAX_SINGLE_PACKET_FRACTION) + scctx->isc_tx_nsegments = max(1, num_txd / MAX_SINGLE_PACKET_FRACTION); - if (scctx->isc_tx_tso_segments_max > scctx->isc_ntxd[main_txq] / + if (scctx->isc_tx_tso_segments_max > num_txd / MAX_SINGLE_PACKET_FRACTION) scctx->isc_tx_tso_segments_max = max(1, - scctx->isc_ntxd[main_txq] / MAX_SINGLE_PACKET_FRACTION); + num_txd / MAX_SINGLE_PACKET_FRACTION); /* TSO parameters - dig these out of the data sheet - simply correspond to tag setup */ if (if_getcapabilities(ifp) & IFCAP_TSO) { @@ -4817,14 +4835,13 @@ int iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp, struct iflib_cloneattach_ctx *clctx) { + int num_txd, num_rxd; int err; if_ctx_t ctx; if_t ifp; if_softc_ctx_t scctx; int i; void *sc; - uint16_t main_txq; - uint16_t main_rxq; ctx = malloc(sizeof(*ctx), M_IFLIB, M_WAITOK|M_ZERO); sc = malloc(sctx->isc_driver->size, M_IFLIB, M_WAITOK|M_ZERO); @@ -4912,21 +4929,20 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sc
svn commit: r363997 - head/sys/net
Author: vmaffione Date: Thu Aug 6 21:37:38 2020 New Revision: 363997 URL: https://svnweb.freebsd.org/changeset/base/363997 Log: iflib: netmap: drop redundant check The validity of head is already checked by nm_rxsync_prologue(). MFC after:2 weeks Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cThu Aug 6 21:32:25 2020(r363996) +++ head/sys/net/iflib.cThu Aug 6 21:37:38 2020(r363997) @@ -1080,16 +1080,12 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl uint32_t nic_i; /* index into the NIC ring */ u_int n; u_int const lim = kring->nkr_num_slots - 1; - u_int const head = kring->rhead; int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; if_ctx_t ctx = ifp->if_softc; iflib_rxq_t rxq = >ifc_rxqs[kring->ring_id]; iflib_fl_t fl = >ifr_fl[0]; struct if_rxd_info ri; - - if (head > lim) - return netmap_ring_reinit(kring); /* * netmap only uses free list 0, to avoid out of order consumption ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r363996 - head/sys/net
Author: vmaffione Date: Thu Aug 6 21:32:25 2020 New Revision: 363996 URL: https://svnweb.freebsd.org/changeset/base/363996 Log: iflib: netmap: don't increment ifl_cidx on the wrong free list Netmap only uses free list 0 to keep it consistent with its one-to-one mapping between each netmap ring and a device RX (or TX) queue. However, the current iflib_netmap_rxsync() routine was mistakenly updating the ifl_cidx field of both free lists. PR: 248494 MFC after:2 weeks Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cThu Aug 6 21:01:26 2020(r363995) +++ head/sys/net/iflib.cThu Aug 6 21:32:25 2020(r363996) @@ -1076,28 +1076,28 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl struct netmap_adapter *na = kring->na; struct netmap_ring *ring = kring->ring; if_t ifp = na->ifp; - iflib_fl_t fl; uint32_t nm_i; /* index into the netmap ring */ uint32_t nic_i; /* index into the NIC ring */ - u_int i, n; + u_int n; u_int const lim = kring->nkr_num_slots - 1; u_int const head = kring->rhead; int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; - struct if_rxd_info ri; if_ctx_t ctx = ifp->if_softc; iflib_rxq_t rxq = >ifc_rxqs[kring->ring_id]; + iflib_fl_t fl = >ifr_fl[0]; + struct if_rxd_info ri; + if (head > lim) return netmap_ring_reinit(kring); /* -* XXX netmap_fl_refill() only ever (re)fills free list 0 so far. +* netmap only uses free list 0, to avoid out of order consumption +* of receive buffers */ - for (i = 0, fl = rxq->ifr_fl; i < rxq->ifr_nfl; i++, fl++) { - bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - } + bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); /* * First part: import newly received packets. @@ -1119,38 +1119,35 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl int crclen = iflib_crcstrip ? 0 : 4; int error, avail; - for (i = 0; i < rxq->ifr_nfl; i++) { - fl = >ifr_fl[i]; - nic_i = fl->ifl_cidx; - nm_i = netmap_idx_n2k(kring, nic_i); - avail = ctx->isc_rxd_available(ctx->ifc_softc, - rxq->ifr_id, nic_i, USHRT_MAX); - for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { - rxd_info_zero(); - ri.iri_frags = rxq->ifr_frags; - ri.iri_qsidx = kring->ring_id; - ri.iri_ifp = ctx->ifc_ifp; - ri.iri_cidx = nic_i; + nic_i = fl->ifl_cidx; + nm_i = netmap_idx_n2k(kring, nic_i); + avail = ctx->isc_rxd_available(ctx->ifc_softc, + rxq->ifr_id, nic_i, USHRT_MAX); + for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { + rxd_info_zero(); + ri.iri_frags = rxq->ifr_frags; + ri.iri_qsidx = kring->ring_id; + ri.iri_ifp = ctx->ifc_ifp; + ri.iri_cidx = nic_i; - error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, ); - ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen; - ring->slot[nm_i].flags = 0; - bus_dmamap_sync(fl->ifl_buf_tag, - fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD); - nm_i = nm_next(nm_i, lim); - nic_i = nm_next(nic_i, lim); + error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, ); + ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen; + ring->slot[nm_i].flags = 0; + bus_dmamap_sync(fl->ifl_buf_tag, + fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD); + nm_i = nm_next(nm_i, lim); + nic_i = nm_next(nic_i, lim); + } + if (n) { /* update the state variables */ + if (netmap_no_pendintr && !force_update) { + /* diagnostics */ + iflib_rx_miss ++; + iflib_rx_miss_bufs += n; } - if (n) { /* update the state variables */ -
svn commit: r363995 - head/sys/dev/e1000
Author: vmaffione Date: Thu Aug 6 21:01:26 2020 New Revision: 363995 URL: https://svnweb.freebsd.org/changeset/base/363995 Log: em(4): honor vlanhwtag offload The FreeBSD em driver fails to properly reset the VME flag in the e1000 CTRL register oneg the following ifconfig command ifconfig em1 -vlanhwtag Tested on the e1000 device emulated by QEMU, and on a real NIC (chip=0x10d38086). PR: 236584 Submitted by: mu...@sunnyvalley.io Reported by: mu...@sunnyvalley.io MFC after:3 weeks Differential Revision:https://reviews.freebsd.org/D25286 Modified: head/sys/dev/e1000/if_em.c Modified: head/sys/dev/e1000/if_em.c == --- head/sys/dev/e1000/if_em.c Thu Aug 6 20:55:18 2020(r363994) +++ head/sys/dev/e1000/if_em.c Thu Aug 6 21:01:26 2020(r363995) @@ -1334,6 +1334,11 @@ em_if_init(if_ctx_t ctx) ctrl |= E1000_CTRL_VME; E1000_WRITE_REG(>hw, E1000_CTRL, ctrl); } + } else { + u32 ctrl; + ctrl = E1000_READ_REG(>hw, E1000_CTRL); + ctrl &= ~E1000_CTRL_VME; + E1000_WRITE_REG(>hw, E1000_CTRL, ctrl); } /* Don't lose promiscuous settings */ ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r363378 - head/sys/net
Author: vmaffione Date: Mon Jul 20 21:08:56 2020 New Revision: 363378 URL: https://svnweb.freebsd.org/changeset/base/363378 Log: iflib: initialize netmap with the correct number of descriptors In case the network device has a RX or TX control queue, the correct number of TX/RX descriptors is contained in the second entry of the isc_ntxd (or isc_nrxd) array, rather than in the first entry. This case is correctly handled by iflib_device_register() and iflib_pseudo_register(), but not by iflib_netmap_attach(). If the first entry is larger than the second, this can result in a panic. This change fixes the bug by introducing two helper functions that also lead to some code simplification. PR: 247647 MFC after:3 weeks Differential Revision:https://reviews.freebsd.org/D25541 Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cMon Jul 20 20:36:32 2020(r363377) +++ head/sys/net/iflib.cMon Jul 20 21:08:56 2020(r363378) @@ -730,6 +730,26 @@ MTX_SYSINIT(iflib_cpu_offset, _offset_mtx, "iflib_ DEBUGNET_DEFINE(iflib); +static int +iflib_num_rx_descs(if_ctx_t ctx) +{ + if_softc_ctx_t scctx = >ifc_softc_ctx; + if_shared_ctx_t sctx = ctx->ifc_sctx; + uint16_t first_rxq = (sctx->isc_flags & IFLIB_HAS_RXCQ) ? 1 : 0; + + return scctx->isc_nrxd[first_rxq]; +} + +static int +iflib_num_tx_descs(if_ctx_t ctx) +{ + if_softc_ctx_t scctx = >ifc_softc_ctx; + if_shared_ctx_t sctx = ctx->ifc_sctx; + uint16_t first_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0; + + return scctx->isc_ntxd[first_txq]; +} + #ifdef DEV_NETMAP #include #include @@ -1165,7 +1185,6 @@ static int iflib_netmap_attach(if_ctx_t ctx) { struct netmap_adapter na; - if_softc_ctx_t scctx = >ifc_softc_ctx; bzero(, sizeof(na)); @@ -1174,8 +1193,8 @@ iflib_netmap_attach(if_ctx_t ctx) MPASS(ctx->ifc_softc_ctx.isc_ntxqsets); MPASS(ctx->ifc_softc_ctx.isc_nrxqsets); - na.num_tx_desc = scctx->isc_ntxd[0]; - na.num_rx_desc = scctx->isc_nrxd[0]; + na.num_tx_desc = iflib_num_tx_descs(ctx); + na.num_rx_desc = iflib_num_rx_descs(ctx); na.nm_txsync = iflib_netmap_txsync; na.nm_rxsync = iflib_netmap_rxsync; na.nm_register = iflib_netmap_register; @@ -4590,7 +4609,7 @@ iflib_device_register(device_t dev, void *sc, if_share kobjop_desc_t kobj_desc; kobj_method_t *kobj_method; int err, msix, rid; - uint16_t main_rxq, main_txq; + int num_txd, num_rxd; ctx = malloc(sizeof(* ctx), M_IFLIB, M_WAITOK|M_ZERO); @@ -4640,21 +4659,20 @@ iflib_device_register(device_t dev, void *sc, if_share if (scctx->isc_nrxqsets == 0 || (scctx->isc_nrxqsets_max && scctx->isc_nrxqsets_max < scctx->isc_nrxqsets)) scctx->isc_nrxqsets = scctx->isc_nrxqsets_max; - main_txq = (sctx->isc_flags & IFLIB_HAS_TXCQ) ? 1 : 0; - main_rxq = (sctx->isc_flags & IFLIB_HAS_RXCQ) ? 1 : 0; + num_txd = iflib_num_tx_descs(ctx); + num_rxd = iflib_num_rx_descs(ctx); /* XXX change for per-queue sizes */ device_printf(dev, "Using %d TX descriptors and %d RX descriptors\n", - scctx->isc_ntxd[main_txq], scctx->isc_nrxd[main_rxq]); + num_txd, num_rxd); - if (scctx->isc_tx_nsegments > scctx->isc_ntxd[main_txq] / - MAX_SINGLE_PACKET_FRACTION) - scctx->isc_tx_nsegments = max(1, scctx->isc_ntxd[main_txq] / + if (scctx->isc_tx_nsegments > num_txd / MAX_SINGLE_PACKET_FRACTION) + scctx->isc_tx_nsegments = max(1, num_txd / MAX_SINGLE_PACKET_FRACTION); - if (scctx->isc_tx_tso_segments_max > scctx->isc_ntxd[main_txq] / + if (scctx->isc_tx_tso_segments_max > num_txd / MAX_SINGLE_PACKET_FRACTION) scctx->isc_tx_tso_segments_max = max(1, - scctx->isc_ntxd[main_txq] / MAX_SINGLE_PACKET_FRACTION); + num_txd / MAX_SINGLE_PACKET_FRACTION); /* TSO parameters - dig these out of the data sheet - simply correspond to tag setup */ if (if_getcapabilities(ifp) & IFCAP_TSO) { @@ -4831,14 +4849,13 @@ int iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp, struct iflib_cloneattach_ctx *clctx) { + int num_txd, num_rxd; int err; if_ctx_t ctx; if_t ifp; if_softc_ctx_t scctx; int i; void *sc; - uint16_t main_txq; - uint16_t main_rxq; ctx = malloc(sizeof(*ctx), M_IFLIB, M_WAITOK|M_ZERO); sc = malloc(sctx->isc_driver->size, M_IFLIB, M_WAITOK|M_ZERO); @@ -4924,21 +4941,20 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sc if (scctx->isc_nrxqsets == 0 ||
svn commit: r363083 - stable/12/sys/net
Author: vmaffione Date: Fri Jul 10 18:30:53 2020 New Revision: 363083 URL: https://svnweb.freebsd.org/changeset/base/363083 Log: MFC r362622 iflib: netmap: add support for partial ring openings Reviewed by:gallatin Differential Revision: https://reviews.freebsd.org/D25254 Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Fri Jul 10 18:19:04 2020(r363082) +++ stable/12/sys/net/iflib.c Fri Jul 10 18:30:53 2020(r363083) @@ -1194,7 +1194,7 @@ iflib_netmap_attach(if_ctx_t ctx) return (netmap_attach()); } -static void +static int iflib_netmap_txq_init(if_ctx_t ctx, iflib_txq_t txq) { struct netmap_adapter *na = NA(ctx->ifc_ifp); @@ -1202,7 +1202,7 @@ iflib_netmap_txq_init(if_ctx_t ctx, iflib_txq_t txq) slot = netmap_reset(na, NR_TX, txq->ift_id, 0); if (slot == NULL) - return; + return (0); for (int i = 0; i < ctx->ifc_softc_ctx.isc_ntxd[0]; i++) { /* @@ -1216,21 +1216,24 @@ iflib_netmap_txq_init(if_ctx_t ctx, iflib_txq_t txq) netmap_load_map(na, txq->ift_buf_tag, txq->ift_sds.ifsd_map[i], NMB(na, slot + si)); } + return (1); } -static void +static int iflib_netmap_rxq_init(if_ctx_t ctx, iflib_rxq_t rxq) { struct netmap_adapter *na = NA(ctx->ifc_ifp); - struct netmap_kring *kring = na->rx_rings[rxq->ifr_id]; + struct netmap_kring *kring; struct netmap_slot *slot; uint32_t nm_i; slot = netmap_reset(na, NR_RX, rxq->ifr_id, 0); if (slot == NULL) - return; + return (0); + kring = na->rx_rings[rxq->ifr_id]; nm_i = netmap_idx_n2k(kring, 0); netmap_fl_refill(rxq, kring, nm_i, true); + return (1); } static void @@ -1261,8 +1264,8 @@ iflib_netmap_timer_adjust(if_ctx_t ctx, iflib_txq_t tx #define iflib_netmap_detach(ifp) netmap_detach(ifp) #else -#define iflib_netmap_txq_init(ctx, txq) -#define iflib_netmap_rxq_init(ctx, rxq) +#define iflib_netmap_txq_init(ctx, txq) (0) +#define iflib_netmap_rxq_init(ctx, rxq) (0) #define iflib_netmap_detach(ifp) #define iflib_netmap_attach(ctx) (0) @@ -2417,10 +2420,8 @@ iflib_init_locked(if_ctx_t ctx) IFDI_INIT(ctx); MPASS(if_getdrvflags(ifp) == i); for (i = 0, rxq = ctx->ifc_rxqs; i < sctx->isc_nrxqsets; i++, rxq++) { - /* XXX this should really be done on a per-queue basis */ - if (if_getcapenable(ifp) & IFCAP_NETMAP) { - MPASS(rxq->ifr_id == i); - iflib_netmap_rxq_init(ctx, rxq); + if (iflib_netmap_rxq_init(ctx, rxq) > 0) { + /* This rxq is in netmap mode. Skip normal init. */ continue; } for (j = 0, fl = rxq->ifr_fl; j < rxq->ifr_nfl; j++, fl++) { ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r363082 - stable/12/sys/net
Author: vmaffione Date: Fri Jul 10 18:19:04 2020 New Revision: 363082 URL: https://svnweb.freebsd.org/changeset/base/363082 Log: MFC r362633, r362633 iflib: netmap: add per-tx-queue netmap support Reviewed by:gallatin Differential Revision: https://reviews.freebsd.org/D25253 Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Fri Jul 10 17:42:22 2020(r363081) +++ stable/12/sys/net/iflib.c Fri Jul 10 18:19:04 2020(r363082) @@ -1240,7 +1240,9 @@ iflib_netmap_timer_adjust(if_ctx_t ctx, iflib_txq_t tx uint16_t txqid; txqid = txq->ift_id; - kring = NA(ctx->ifc_ifp)->tx_rings[txqid]; + kring = netmap_kring_on(NA(ctx->ifc_ifp), txqid, NR_TX); + if (kring == NULL) + return; if (kring->nr_hwcur != nm_next(kring->nr_hwtail, kring->nkr_num_slots - 1)) { bus_dmamap_sync(txq->ift_ifdi->idi_tag, txq->ift_ifdi->idi_map, @@ -3737,28 +3739,18 @@ _task_fn_tx(void *context) { iflib_txq_t txq = context; if_ctx_t ctx = txq->ift_ctx; -#if defined(ALTQ) || defined(DEV_NETMAP) if_t ifp = ctx->ifc_ifp; -#endif int abdicate = ctx->ifc_sysctl_tx_abdicate; #ifdef IFLIB_DIAGNOSTICS txq->ift_cpu_exec_count[curcpu]++; #endif - if (!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING)) + if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING)) return; #ifdef DEV_NETMAP - if (if_getcapenable(ifp) & IFCAP_NETMAP) { - bus_dmamap_sync(txq->ift_ifdi->idi_tag, txq->ift_ifdi->idi_map, - BUS_DMASYNC_POSTREAD); - if (ctx->isc_txd_credits_update(ctx->ifc_softc, txq->ift_id, false)) - netmap_tx_irq(ifp, txq->ift_id); - if (ctx->ifc_flags & IFC_LEGACY) - IFDI_INTR_ENABLE(ctx); - else - IFDI_TX_QUEUE_INTR_ENABLE(ctx, txq->ift_id); - return; - } + if ((if_getcapenable(ifp) & IFCAP_NETMAP) && + netmap_tx_irq(ifp, txq->ift_id)) + goto skip_ifmp; #endif #ifdef ALTQ if (ALTQ_IS_ENABLED(>if_snd)) @@ -3773,6 +3765,9 @@ _task_fn_tx(void *context) */ if (abdicate) ifmp_ring_check_drainage(txq->ift_br, TX_BATCH_SIZE); +#ifdef DEV_NETMAP +skip_ifmp: +#endif if (ctx->ifc_flags & IFC_LEGACY) IFDI_INTR_ENABLE(ctx); else ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362856 - stable/12/sys/dev/virtio/network
Author: vmaffione Date: Wed Jul 1 19:42:23 2020 New Revision: 362856 URL: https://svnweb.freebsd.org/changeset/base/362856 Log: MFC r362204 if_vtnet: let vtnet_rx_vq_intr() and vtnet_rxq_tq_intr() share code Since the two functions are similar, introduce a common function (vtnet_rx_vq_process()) to share common code. This also improves locking, by ensuring vrxs_rescheduled is accessed under the RXQ lock, and taskqueue_enqueue() is not called under the lock (therefore avoiding a spurious duplicate lock warning). Reported by:jrtc27 Modified: stable/12/sys/dev/virtio/network/if_vtnet.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/virtio/network/if_vtnet.c == --- stable/12/sys/dev/virtio/network/if_vtnet.c Wed Jul 1 19:41:10 2020 (r362855) +++ stable/12/sys/dev/virtio/network/if_vtnet.c Wed Jul 1 19:42:23 2020 (r362856) @@ -127,6 +127,7 @@ static int vtnet_rxq_merged_eof(struct vtnet_rxq *, st static voidvtnet_rxq_input(struct vtnet_rxq *, struct mbuf *, struct virtio_net_hdr *); static int vtnet_rxq_eof(struct vtnet_rxq *); +static voidvtnet_rx_vq_process(struct vtnet_rxq *rxq, int tries); static voidvtnet_rx_vq_intr(void *); static voidvtnet_rxq_tq_intr(void *, int); @@ -1847,20 +1848,17 @@ vtnet_rxq_eof(struct vtnet_rxq *rxq) } static void -vtnet_rx_vq_intr(void *xrxq) +vtnet_rx_vq_process(struct vtnet_rxq *rxq, int tries) { struct vtnet_softc *sc; - struct vtnet_rxq *rxq; struct ifnet *ifp; - int tries, more; + int more; #ifdef DEV_NETMAP int nmirq; #endif /* DEV_NETMAP */ - rxq = xrxq; sc = rxq->vtnrx_sc; ifp = sc->vtnet_ifp; - tries = 0; if (__predict_false(rxq->vtnrx_id >= sc->vtnet_act_vq_pairs)) { /* @@ -1908,58 +1906,32 @@ again: * This is an occasional condition or race (when !more), * so retry a few times before scheduling the taskqueue. */ - if (tries++ < VTNET_INTR_DISABLE_RETRIES) + if (tries-- > 0) goto again; - VTNET_RXQ_UNLOCK(rxq); rxq->vtnrx_stats.vrxs_rescheduled++; + VTNET_RXQ_UNLOCK(rxq); taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); } else VTNET_RXQ_UNLOCK(rxq); } static void -vtnet_rxq_tq_intr(void *xrxq, int pending) +vtnet_rx_vq_intr(void *xrxq) { - struct vtnet_softc *sc; struct vtnet_rxq *rxq; - struct ifnet *ifp; - int more; -#ifdef DEV_NETMAP - int nmirq; -#endif /* DEV_NETMAP */ rxq = xrxq; - sc = rxq->vtnrx_sc; - ifp = sc->vtnet_ifp; + vtnet_rx_vq_process(rxq, VTNET_INTR_DISABLE_RETRIES); +} - VTNET_RXQ_LOCK(rxq); +static void +vtnet_rxq_tq_intr(void *xrxq, int pending) +{ + struct vtnet_rxq *rxq; -#ifdef DEV_NETMAP - nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, ); - if (nmirq != NM_IRQ_PASS) { - VTNET_RXQ_UNLOCK(rxq); - if (nmirq == NM_IRQ_RESCHED) { - taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); - } - return; - } -#endif /* DEV_NETMAP */ - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - VTNET_RXQ_UNLOCK(rxq); - return; - } - - more = vtnet_rxq_eof(rxq); - if (more || vtnet_rxq_enable_intr(rxq) != 0) { - if (!more) - vtnet_rxq_disable_intr(rxq); - rxq->vtnrx_stats.vrxs_rescheduled++; - taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); - } - - VTNET_RXQ_UNLOCK(rxq); + rxq = xrxq; + vtnet_rx_vq_process(rxq, 0); } static int ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362810 - stable/12/sys/net
Author: vmaffione Date: Tue Jun 30 19:34:36 2020 New Revision: 362810 URL: https://svnweb.freebsd.org/changeset/base/362810 Log: MFC r362553 iflib: netmap: fix rsync index overrun In the current iflib_netmap_rxsync, there is nothing that prevents kring->nr_hwtail to overrun kring->nr_hwcur during the descriptor import phase. This may cause errors in netmap applications, such as: em1 RX0: fail 'head < kring->nr_hwcur || head > kring->nr_hwtail' h 795 c 795 t 282 rh 795 rc 795 rt 282 hc 282 ht 282 Reviewed by:gallatin Differential Revision: https://reviews.freebsd.org/D25252 Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Tue Jun 30 18:08:59 2020(r362809) +++ stable/12/sys/net/iflib.c Tue Jun 30 19:34:36 2020(r362810) @@ -1104,6 +1104,7 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl * rxr->next_check is set to 0 on a ring reinit */ if (netmap_no_pendintr || force_update) { + uint32_t hwtail_lim = nm_prev(kring->nr_hwcur, lim); int crclen = iflib_crcstrip ? 0 : 4; int error, avail; @@ -1113,7 +1114,7 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl nm_i = netmap_idx_n2k(kring, nic_i); avail = ctx->isc_rxd_available(ctx->ifc_softc, rxq->ifr_id, nic_i, USHRT_MAX); - for (n = 0; avail > 0; n++, avail--) { + for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { rxd_info_zero(); ri.iri_frags = rxq->ifr_frags; ri.iri_qsidx = kring->ring_id; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362633 - head/sys/net
Author: vmaffione Date: Thu Jun 25 20:43:21 2020 New Revision: 362633 URL: https://svnweb.freebsd.org/changeset/base/362633 Log: iflib: fix compilation issue introduced in r362621 The ifp local variable is useful even without netmap and altq, as it is used to check for IFF_DRV_RUNNING. MFC after:2 weeks Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cThu Jun 25 20:31:06 2020(r362632) +++ head/sys/net/iflib.cThu Jun 25 20:43:21 2020(r362633) @@ -3751,9 +3751,7 @@ _task_fn_tx(void *context) { iflib_txq_t txq = context; if_ctx_t ctx = txq->ift_ctx; -#if defined(ALTQ) || defined(DEV_NETMAP) if_t ifp = ctx->ifc_ifp; -#endif int abdicate = ctx->ifc_sysctl_tx_abdicate; #ifdef IFLIB_DIAGNOSTICS ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362622 - head/sys/net
Author: vmaffione Date: Thu Jun 25 19:44:24 2020 New Revision: 362622 URL: https://svnweb.freebsd.org/changeset/base/362622 Log: iflib: netmap: add support for partial ring openings Reviewed by: gallatin MFC after:2 weeks Differential Revision:https://reviews.freebsd.org/D25254 Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cThu Jun 25 19:35:43 2020(r362621) +++ head/sys/net/iflib.cThu Jun 25 19:44:24 2020(r362622) @@ -1189,7 +1189,7 @@ iflib_netmap_attach(if_ctx_t ctx) return (netmap_attach()); } -static void +static int iflib_netmap_txq_init(if_ctx_t ctx, iflib_txq_t txq) { struct netmap_adapter *na = NA(ctx->ifc_ifp); @@ -1197,7 +1197,7 @@ iflib_netmap_txq_init(if_ctx_t ctx, iflib_txq_t txq) slot = netmap_reset(na, NR_TX, txq->ift_id, 0); if (slot == NULL) - return; + return (0); for (int i = 0; i < ctx->ifc_softc_ctx.isc_ntxd[0]; i++) { /* @@ -1211,21 +1211,24 @@ iflib_netmap_txq_init(if_ctx_t ctx, iflib_txq_t txq) netmap_load_map(na, txq->ift_buf_tag, txq->ift_sds.ifsd_map[i], NMB(na, slot + si)); } + return (1); } -static void +static int iflib_netmap_rxq_init(if_ctx_t ctx, iflib_rxq_t rxq) { struct netmap_adapter *na = NA(ctx->ifc_ifp); - struct netmap_kring *kring = na->rx_rings[rxq->ifr_id]; + struct netmap_kring *kring; struct netmap_slot *slot; uint32_t nm_i; slot = netmap_reset(na, NR_RX, rxq->ifr_id, 0); if (slot == NULL) - return; + return (0); + kring = na->rx_rings[rxq->ifr_id]; nm_i = netmap_idx_n2k(kring, 0); netmap_fl_refill(rxq, kring, nm_i, true); + return (1); } static void @@ -1256,8 +1259,8 @@ iflib_netmap_timer_adjust(if_ctx_t ctx, iflib_txq_t tx #define iflib_netmap_detach(ifp) netmap_detach(ifp) #else -#define iflib_netmap_txq_init(ctx, txq) -#define iflib_netmap_rxq_init(ctx, rxq) +#define iflib_netmap_txq_init(ctx, txq) (0) +#define iflib_netmap_rxq_init(ctx, rxq) (0) #define iflib_netmap_detach(ifp) #define iflib_netmap_attach(ctx) (0) @@ -2368,10 +2371,8 @@ iflib_init_locked(if_ctx_t ctx) IFDI_INIT(ctx); MPASS(if_getdrvflags(ifp) == i); for (i = 0, rxq = ctx->ifc_rxqs; i < sctx->isc_nrxqsets; i++, rxq++) { - /* XXX this should really be done on a per-queue basis */ - if (if_getcapenable(ifp) & IFCAP_NETMAP) { - MPASS(rxq->ifr_id == i); - iflib_netmap_rxq_init(ctx, rxq); + if (iflib_netmap_rxq_init(ctx, rxq) > 0) { + /* This rxq is in netmap mode. Skip normal init. */ continue; } for (j = 0, fl = rxq->ifr_fl; j < rxq->ifr_nfl; j++, fl++) { ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362621 - head/sys/net
Author: vmaffione Date: Thu Jun 25 19:35:43 2020 New Revision: 362621 URL: https://svnweb.freebsd.org/changeset/base/362621 Log: iflib: netmap: add per-tx-queue netmap support Reviewed by: gallatin MFC after:2 weeks Differential Revision:https://reviews.freebsd.org/D25253 Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cThu Jun 25 19:35:37 2020(r362620) +++ head/sys/net/iflib.cThu Jun 25 19:35:43 2020(r362621) @@ -1235,7 +1235,9 @@ iflib_netmap_timer_adjust(if_ctx_t ctx, iflib_txq_t tx uint16_t txqid; txqid = txq->ift_id; - kring = NA(ctx->ifc_ifp)->tx_rings[txqid]; + kring = netmap_kring_on(NA(ctx->ifc_ifp), txqid, NR_TX); + if (kring == NULL) + return; if (kring->nr_hwcur != nm_next(kring->nr_hwtail, kring->nkr_num_slots - 1)) { bus_dmamap_sync(txq->ift_ifdi->idi_tag, txq->ift_ifdi->idi_map, @@ -3756,20 +3758,12 @@ _task_fn_tx(void *context) #ifdef IFLIB_DIAGNOSTICS txq->ift_cpu_exec_count[curcpu]++; #endif - if (!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING)) + if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING)) return; #ifdef DEV_NETMAP - if (if_getcapenable(ifp) & IFCAP_NETMAP) { - bus_dmamap_sync(txq->ift_ifdi->idi_tag, txq->ift_ifdi->idi_map, - BUS_DMASYNC_POSTREAD); - if (ctx->isc_txd_credits_update(ctx->ifc_softc, txq->ift_id, false)) - netmap_tx_irq(ifp, txq->ift_id); - if (ctx->ifc_flags & IFC_LEGACY) - IFDI_INTR_ENABLE(ctx); - else - IFDI_TX_QUEUE_INTR_ENABLE(ctx, txq->ift_id); - return; - } + if ((if_getcapenable(ifp) & IFCAP_NETMAP) && + netmap_tx_irq(ifp, txq->ift_id)) + goto skip_ifmp; #endif #ifdef ALTQ if (ALTQ_IS_ENABLED(>if_snd)) @@ -3784,6 +3778,9 @@ _task_fn_tx(void *context) */ if (abdicate) ifmp_ring_check_drainage(txq->ift_br, TX_BATCH_SIZE); +#ifdef DEV_NETMAP +skip_ifmp: +#endif if (ctx->ifc_flags & IFC_LEGACY) IFDI_INTR_ENABLE(ctx); else ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362556 - stable/12/sys/net
Author: vmaffione Date: Tue Jun 23 20:48:43 2020 New Revision: 362556 URL: https://svnweb.freebsd.org/changeset/base/362556 Log: MFC r361982 iflib: netmap: honor netmap_irx_irq return values In the receive interrupt routine, always call netmap_rx_irq(). The latter function will return != NM_IRQ_PASS if netmap is not active on that specific receive queue, so that the driver can go on with iflib_rxeof(). Note that netmap supports partial opening, where only a subset of the RX or TX rings can be open in netmap mode. Checking the IFCAP_NETMAP flag is not enough to make sure that the queue is indeed in netmap mode. Moreover, in case netmap_rx_irq() returns NM_IRQ_RESCHED, it means that netmap expects the driver to call netmap_rx_irq() again as soon as possible. Currently, this may happen when the device is attached to a VALE switch. Reviewed by:gallatin Differential Revision: https://reviews.freebsd.org/D25167 Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Tue Jun 23 20:44:05 2020(r362555) +++ stable/12/sys/net/iflib.c Tue Jun 23 20:48:43 2020(r362556) @@ -3785,6 +3785,10 @@ _task_fn_rx(void *context) if_ctx_t ctx = rxq->ifr_ctx; uint8_t more; uint16_t budget; +#ifdef DEV_NETMAP + u_int work = 0; + int nmirq; +#endif #ifdef IFLIB_DIAGNOSTICS rxq->ifr_cpu_exec_count[curcpu]++; @@ -3793,12 +3797,10 @@ _task_fn_rx(void *context) if (__predict_false(!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING))) return; #ifdef DEV_NETMAP - if (if_getcapenable(ctx->ifc_ifp) & IFCAP_NETMAP) { - u_int work = 0; - if (netmap_rx_irq(ctx->ifc_ifp, rxq->ifr_id, )) { - more = 0; - goto skip_rxeof; - } + nmirq = netmap_rx_irq(ctx->ifc_ifp, rxq->ifr_id, ); + if (nmirq != NM_IRQ_PASS) { + more = (nmirq == NM_IRQ_RESCHED) ? IFLIB_RXEOF_MORE : 0; + goto skip_rxeof; } #endif budget = ctx->ifc_sysctl_rx_budget; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362555 - stable/12/sys/net
Author: vmaffione Date: Tue Jun 23 20:44:05 2020 New Revision: 362555 URL: https://svnweb.freebsd.org/changeset/base/362555 Log: MFC r362185 iflib: netmap: enter/exit netmap mode after device stops Avoid possible race conditions by calling nm_set_native_flags() and nm_clear_native_flags() only after the device has been stopped. Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c == --- stable/12/sys/net/iflib.c Tue Jun 23 20:41:10 2020(r362554) +++ stable/12/sys/net/iflib.c Tue Jun 23 20:44:05 2020(r362555) @@ -793,13 +793,19 @@ iflib_netmap_register(struct netmap_adapter *na, int o if (!CTX_IS_VF(ctx)) IFDI_CRCSTRIP_SET(ctx, onoff, iflib_crcstrip); - /* enable or disable flags and callbacks in na and ifp */ + iflib_stop(ctx); + + /* +* Enable (or disable) netmap flags, and intercept (or restore) +* ifp->if_transmit. This is done once the device has been stopped +* to prevent race conditions. +*/ if (onoff) { nm_set_native_flags(na); } else { nm_clear_native_flags(na); } - iflib_stop(ctx); + iflib_init_locked(ctx); IFDI_CRCSTRIP_SET(ctx, onoff, iflib_crcstrip); // XXX why twice ? status = ifp->if_drv_flags & IFF_DRV_RUNNING ? 0 : 1; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362554 - in stable/12/sys/dev: netmap virtio/network
Author: vmaffione Date: Tue Jun 23 20:41:10 2020 New Revision: 362554 URL: https://svnweb.freebsd.org/changeset/base/362554 Log: MFC r362183 netmap: vtnet: fix races in vtnet_netmap_reg() The nm_register callback needs to call nm_set_native_flags() or nm_clear_native_flags() once the device has been stopped. However, in the current implementation this is not true, as the device is stopped by vtnet_init_locked(). This causes race conditions where the driver crashes as soon as it dequeues netmap buffers assuming they are mbufs (or the other way around). To fix the issue, we extend vtnet_init_locked() with a second argument that, if not zero, will set/clear the netmap flags. This results in a huge simplification of the nm_register callback itself. Also, use netmap_reset() to check if a ring is going to be re-initialized in netmap mode. Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h stable/12/sys/dev/virtio/network/if_vtnet.c stable/12/sys/dev/virtio/network/if_vtnetvar.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h == --- stable/12/sys/dev/netmap/if_vtnet_netmap.h Tue Jun 23 20:23:56 2020 (r362553) +++ stable/12/sys/dev/netmap/if_vtnet_netmap.h Tue Jun 23 20:41:10 2020 (r362554) @@ -39,52 +39,18 @@ vtnet_netmap_reg(struct netmap_adapter *na, int state) { struct ifnet *ifp = na->ifp; struct vtnet_softc *sc = ifp->if_softc; - int success; - int i; - /* Drain the taskqueues to make sure that there are no worker threads -* accessing the virtqueues. */ - vtnet_drain_taskqueues(sc); - + /* +* Trigger a device reinit, asking vtnet_init_locked() to +* also enter or exit netmap mode. +*/ VTNET_CORE_LOCK(sc); - - /* We need nm_netmap_on() to return true when called by -* vtnet_init_locked() below. */ - if (state) - nm_set_native_flags(na); - - /* We need to trigger a device reset in order to unexpose guest buffers -* published to the host. */ - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - /* Get pending used buffers. The way they are freed depends on whether -* they are netmap buffer or they are mbufs. We can tell apart the two -* cases by looking at kring->nr_mode, before this is possibly updated -* in the loop below. */ - for (i = 0; i < sc->vtnet_act_vq_pairs; i++) { - struct vtnet_txq *txq = >vtnet_txqs[i]; - struct vtnet_rxq *rxq = >vtnet_rxqs[i]; - - VTNET_TXQ_LOCK(txq); - vtnet_txq_free_mbufs(txq); - VTNET_TXQ_UNLOCK(txq); - - VTNET_RXQ_LOCK(rxq); - vtnet_rxq_free_mbufs(rxq); - VTNET_RXQ_UNLOCK(rxq); - } - vtnet_init_locked(sc); - success = (ifp->if_drv_flags & IFF_DRV_RUNNING) ? 0 : ENXIO; - - if (state) { - netmap_krings_mode_commit(na, state); - } else { - nm_clear_native_flags(na); - netmap_krings_mode_commit(na, state); - } - + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + vtnet_init_locked(sc, state ? VTNET_INIT_NETMAP_ENTER + : VTNET_INIT_NETMAP_EXIT); VTNET_CORE_UNLOCK(sc); - return success; + return 0; } @@ -245,15 +211,13 @@ vtnet_netmap_rxq_populate(struct vtnet_rxq *rxq) { struct netmap_adapter *na = NA(rxq->vtnrx_sc->vtnet_ifp); struct netmap_kring *kring; + struct netmap_slot *slot; int error; - if (!nm_native_on(na) || rxq->vtnrx_id >= na->num_rx_rings) + slot = netmap_reset(na, NR_RX, rxq->vtnrx_id, 0); + if (slot == NULL) return -1; - kring = na->rx_rings[rxq->vtnrx_id]; - if (!(nm_kring_pending_on(kring) || - kring->nr_pending_mode == NKR_NETMAP_ON)) - return -1; /* Expose all the RX netmap buffers we can. In case of no indirect * buffers, the number of netmap slots in the RX ring matches the Modified: stable/12/sys/dev/virtio/network/if_vtnet.c == --- stable/12/sys/dev/virtio/network/if_vtnet.c Tue Jun 23 20:23:56 2020 (r362553) +++ stable/12/sys/dev/virtio/network/if_vtnet.c Tue Jun 23 20:41:10 2020 (r362554) @@ -180,7 +180,7 @@ static int vtnet_init_tx_queues(struct vtnet_softc *); static int vtnet_init_rxtx_queues(struct vtnet_softc *); static voidvtnet_set_active_vq_pairs(struct vtnet_softc *); static int vtnet_reinit(struct vtnet_softc *); -static voidvtnet_init_locked(struct vtnet_softc *); +static voidvtnet_init_locked(struct vtnet_softc *, int); static voidvtnet_init(void *); static void
svn commit: r362553 - head/sys/net
Author: vmaffione Date: Tue Jun 23 20:23:56 2020 New Revision: 362553 URL: https://svnweb.freebsd.org/changeset/base/362553 Log: iflib: netmap: fix rsync index overrun In the current iflib_netmap_rxsync, there is nothing that prevents kring->nr_hwtail to overrun kring->nr_hwcur during the descriptor import phase. This may cause errors in netmap applications, such as: em1 RX0: fail 'head < kring->nr_hwcur || head > kring->nr_hwtail' h 795 c 795 t 282 rh 795 rc 795 rt 282 hc 282 ht 282 Reviewed by: gallatin MFC after:1 week Differential Revision:https://reviews.freebsd.org/D25252 Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cTue Jun 23 20:02:55 2020(r362552) +++ head/sys/net/iflib.cTue Jun 23 20:23:56 2020(r362553) @@ -1099,6 +1099,7 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl * rxr->next_check is set to 0 on a ring reinit */ if (netmap_no_pendintr || force_update) { + uint32_t hwtail_lim = nm_prev(kring->nr_hwcur, lim); int crclen = iflib_crcstrip ? 0 : 4; int error, avail; @@ -1108,7 +1109,7 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int fl nm_i = netmap_idx_n2k(kring, nic_i); avail = ctx->isc_rxd_available(ctx->ifc_softc, rxq->ifr_id, nic_i, USHRT_MAX); - for (n = 0; avail > 0; n++, avail--) { + for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { rxd_info_zero(); ri.iri_frags = rxq->ifr_frags; ri.iri_qsidx = kring->ring_id; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362304 - in stable/12/sys/dev: netmap virtio/network
Author: vmaffione Date: Thu Jun 18 10:03:17 2020 New Revision: 362304 URL: https://svnweb.freebsd.org/changeset/base/362304 Log: MFC r362076 netmap: introduce netmap_kring_on() This function returns NULL if the ring identified by queue id and direction is in netmap mode. Otherwise return the corresponding kring. Use this function to replace vtnet_netmap_queue_on(). Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h stable/12/sys/dev/netmap/netmap_kern.h stable/12/sys/dev/virtio/network/if_vtnet.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h == --- stable/12/sys/dev/netmap/if_vtnet_netmap.h Thu Jun 18 08:38:54 2020 (r362303) +++ stable/12/sys/dev/netmap/if_vtnet_netmap.h Thu Jun 18 10:03:17 2020 (r362304) @@ -33,25 +33,6 @@ #include /* vtophys ? */ #include -/* - * Return 1 if the queue identified by 't' and 'idx' is in netmap mode. - */ -static int -vtnet_netmap_queue_on(struct vtnet_softc *sc, enum txrx t, int idx) -{ - struct netmap_adapter *na = NA(sc->vtnet_ifp); - - if (!nm_native_on(na)) - return 0; - - if (t == NR_RX) - return !!(idx < na->num_rx_rings && - na->rx_rings[idx]->nr_mode == NKR_NETMAP_ON); - - return !!(idx < na->num_tx_rings && - na->tx_rings[idx]->nr_mode == NKR_NETMAP_ON); -} - /* Register and unregister. */ static int vtnet_netmap_reg(struct netmap_adapter *na, int state) Modified: stable/12/sys/dev/netmap/netmap_kern.h == --- stable/12/sys/dev/netmap/netmap_kern.h Thu Jun 18 08:38:54 2020 (r362303) +++ stable/12/sys/dev/netmap/netmap_kern.h Thu Jun 18 10:03:17 2020 (r362304) @@ -1353,6 +1353,24 @@ nm_native_on(struct netmap_adapter *na) return nm_netmap_on(na) && (na->na_flags & NAF_NATIVE); } +static inline struct netmap_kring * +netmap_kring_on(struct netmap_adapter *na, u_int q, enum txrx t) +{ + struct netmap_kring *kring = NULL; + + if (!nm_native_on(na)) + return NULL; + + if (t == NR_RX && q < na->num_rx_rings) + kring = na->rx_rings[q]; + else if (t == NR_TX && q < na->num_tx_rings) + kring = na->tx_rings[q]; + else + return NULL; + + return (kring->nr_mode == NKR_NETMAP_ON) ? kring : NULL; +} + static inline int nm_iszombie(struct netmap_adapter *na) { Modified: stable/12/sys/dev/virtio/network/if_vtnet.c == --- stable/12/sys/dev/virtio/network/if_vtnet.c Thu Jun 18 08:38:54 2020 (r362303) +++ stable/12/sys/dev/virtio/network/if_vtnet.c Thu Jun 18 10:03:17 2020 (r362304) @@ -1227,17 +1227,17 @@ vtnet_rxq_free_mbufs(struct vtnet_rxq *rxq) struct mbuf *m; int last; #ifdef DEV_NETMAP - int netmap_bufs = vtnet_netmap_queue_on(rxq->vtnrx_sc, NR_RX, - rxq->vtnrx_id); + struct netmap_kring *kring = netmap_kring_on(NA(rxq->vtnrx_sc->vtnet_ifp), + rxq->vtnrx_id, NR_RX); #else /* !DEV_NETMAP */ - int netmap_bufs = 0; + void *kring = NULL; #endif /* !DEV_NETMAP */ vq = rxq->vtnrx_vq; last = 0; while ((m = virtqueue_drain(vq, )) != NULL) { - if (!netmap_bufs) + if (kring == NULL) m_freem(m); } @@ -2007,17 +2007,17 @@ vtnet_txq_free_mbufs(struct vtnet_txq *txq) struct vtnet_tx_header *txhdr; int last; #ifdef DEV_NETMAP - int netmap_bufs = vtnet_netmap_queue_on(txq->vtntx_sc, NR_TX, - txq->vtntx_id); + struct netmap_kring *kring = netmap_kring_on(NA(txq->vtntx_sc->vtnet_ifp), + txq->vtntx_id, NR_TX); #else /* !DEV_NETMAP */ - int netmap_bufs = 0; + void *kring = NULL; #endif /* !DEV_NETMAP */ vq = txq->vtntx_vq; last = 0; while ((txhdr = virtqueue_drain(vq, )) != NULL) { - if (!netmap_bufs) { + if (kring == NULL) { m_freem(txhdr->vth_mbuf); uma_zfree(vtnet_tx_header_zone, txhdr); } ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362204 - head/sys/dev/virtio/network
Author: vmaffione Date: Mon Jun 15 19:46:34 2020 New Revision: 362204 URL: https://svnweb.freebsd.org/changeset/base/362204 Log: if_vtnet: let vtnet_rx_vq_intr() and vtnet_rxq_tq_intr() share code Since the two functions are similar, introduce a common function (vtnet_rx_vq_process()) to share common code. This also improves locking, by ensuring vrxs_rescheduled is accessed under the RXQ lock, and taskqueue_enqueue() is not called under the lock (therefore avoiding a spurious duplicate lock warning). Reported by: jrtc27 MFC after:2 weeks Modified: head/sys/dev/virtio/network/if_vtnet.c Modified: head/sys/dev/virtio/network/if_vtnet.c == --- head/sys/dev/virtio/network/if_vtnet.c Mon Jun 15 19:38:48 2020 (r362203) +++ head/sys/dev/virtio/network/if_vtnet.c Mon Jun 15 19:46:34 2020 (r362204) @@ -128,6 +128,7 @@ static int vtnet_rxq_merged_eof(struct vtnet_rxq *, st static voidvtnet_rxq_input(struct vtnet_rxq *, struct mbuf *, struct virtio_net_hdr *); static int vtnet_rxq_eof(struct vtnet_rxq *); +static voidvtnet_rx_vq_process(struct vtnet_rxq *rxq, int tries); static voidvtnet_rx_vq_intr(void *); static voidvtnet_rxq_tq_intr(void *, int); @@ -1915,20 +1916,17 @@ vtnet_rxq_eof(struct vtnet_rxq *rxq) } static void -vtnet_rx_vq_intr(void *xrxq) +vtnet_rx_vq_process(struct vtnet_rxq *rxq, int tries) { struct vtnet_softc *sc; - struct vtnet_rxq *rxq; struct ifnet *ifp; - int tries, more; + int more; #ifdef DEV_NETMAP int nmirq; #endif /* DEV_NETMAP */ - rxq = xrxq; sc = rxq->vtnrx_sc; ifp = sc->vtnet_ifp; - tries = 0; if (__predict_false(rxq->vtnrx_id >= sc->vtnet_act_vq_pairs)) { /* @@ -1976,58 +1974,32 @@ again: * This is an occasional condition or race (when !more), * so retry a few times before scheduling the taskqueue. */ - if (tries++ < VTNET_INTR_DISABLE_RETRIES) + if (tries-- > 0) goto again; - VTNET_RXQ_UNLOCK(rxq); rxq->vtnrx_stats.vrxs_rescheduled++; + VTNET_RXQ_UNLOCK(rxq); taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); } else VTNET_RXQ_UNLOCK(rxq); } static void -vtnet_rxq_tq_intr(void *xrxq, int pending) +vtnet_rx_vq_intr(void *xrxq) { - struct vtnet_softc *sc; struct vtnet_rxq *rxq; - struct ifnet *ifp; - int more; -#ifdef DEV_NETMAP - int nmirq; -#endif /* DEV_NETMAP */ rxq = xrxq; - sc = rxq->vtnrx_sc; - ifp = sc->vtnet_ifp; + vtnet_rx_vq_process(rxq, VTNET_INTR_DISABLE_RETRIES); +} - VTNET_RXQ_LOCK(rxq); +static void +vtnet_rxq_tq_intr(void *xrxq, int pending) +{ + struct vtnet_rxq *rxq; -#ifdef DEV_NETMAP - nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, ); - if (nmirq != NM_IRQ_PASS) { - VTNET_RXQ_UNLOCK(rxq); - if (nmirq == NM_IRQ_RESCHED) { - taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); - } - return; - } -#endif /* DEV_NETMAP */ - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - VTNET_RXQ_UNLOCK(rxq); - return; - } - - more = vtnet_rxq_eof(rxq); - if (more || vtnet_rxq_enable_intr(rxq) != 0) { - if (!more) - vtnet_rxq_disable_intr(rxq); - rxq->vtnrx_stats.vrxs_rescheduled++; - taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); - } - - VTNET_RXQ_UNLOCK(rxq); + rxq = xrxq; + vtnet_rx_vq_process(rxq, 0); } static int ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
Re: svn commit: r361944 - in head/sys/dev/virtio: . network
Il giorno lun 15 giu 2020 alle ore 00:05 Jessica Clarke ha scritto: > On 14 Jun 2020, at 22:22, Tom Jones wrote: > > On Sun, Jun 14, 2020 at 09:56:03PM +0100, Jessica Clarke wrote: > >> On 14 Jun 2020, at 20:51, Tom Jones wrote: > >>> On Mon, Jun 08, 2020 at 09:51:36PM +, Jessica Clarke wrote: > Author: jrtc27 > Date: Mon Jun 8 21:51:36 2020 > New Revision: 361944 > URL: https://svnweb.freebsd.org/changeset/base/361944 > > Log: > virtio: Support non-legacy network device and queue > > The non-legacy interface always defines num_buffers in the header, > regardless of whether VIRTIO_NET_F_MRG_RXBUF, just leaving it unused. > We > also need to ensure our virtqueue doesn't filter out > VIRTIO_F_VERSION_1 > during negotiation, as it supports non-legacy transports just fine. > This > fixes network packet transmission on TinyEMU. > > Reviewed by: br, brooks (mentor), jhb (mentor) > Approved by: br, brooks (mentor), jhb (mentor) > Differential Revision: https://reviews.freebsd.org/D25132 > > Modified: > head/sys/dev/virtio/network/if_vtnet.c > head/sys/dev/virtio/network/if_vtnetvar.h > head/sys/dev/virtio/virtio.c > head/sys/dev/virtio/virtqueue.c > > >>> > >>> Hi Jessica, > >>> > >>> After updating my current bhyve vm today (on a 12.1 host), networking > no longer > >>> works. Reverting this commit seems to resolve the issue. I think vtnet > is not > >>> passing enough data up to the ip layer. > >>> > >>> If I capture on the tap interface for the vm I see arp requests and arp > >>> replies, however kern.msgbuf is full of: > >>> > >>> <5>arp: short packet received on vtnet0 > >>> > >>> and netstat does not see any replies to arp requests: > >>> > >>> root@freebsd-current:~ # netstat -s -p arp > >>> arp: > >>> 11 ARP requests sent > >>> 0 ARP requests failed to sent > >>> 0 ARP replies sent > >>> 0 ARP requests received > >>> 0 ARP replies received > >>> 0 ARP packets received > >>> 24 total packets dropped due to no ARP entry > >>> 2 ARP entrys timed out > >>> 0 Duplicate IPs seen > >>> > >>> If I set up an arp entry manually I can see ICMP echo requests and > responses on > >>> the tap interface, but the vm does not see the responses. > >>> > >>> root@freebsd-current:~ # netstat -s -p ip > >>> ip: > >>> 7 total packets received > >>> 0 bad header checksums > >>> 0 with size smaller than minimum > >>> 7 with data size < data length > >>> 0 with ip length > max ip packet size > >>> 0 with header length < data size > >>> 0 with data length < header length > >>> > >>> The line > >>> > >>> 7 with data size < data length > >>> > >>> makes me think that vtnet is truncating packets. > >>> > >>> markj pointed me at this bug in irc which might also be related: > >>> > >>> https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=247242 > >> > >> Hi Tom, > >> Sorry about that; it seems bhyve hits the "legacy and no MrgRxBuf" > >> case. Could you please try the patch below? > >> > >> Jess > >> > > > > This changed fixed the issue for me. Please feel free to add > > > > Tested By: thj > > > > when you commit. > > Great, thanks for the report. > > > In testing I this lor went by, I wonder if this is something you care > about: > > > > acquiring duplicate lock of same type: "vtnet0-rx0" > > 1st vtnet0-rx0 @ > /usr/home/tj/code/freebsd/projects/review-D25220/sys/dev/virtio/network/if_vtnet.c:1780 > > 2nd vtnet0-rx0 @ > /usr/home/tj/code/freebsd/projects/review-D25220/sys/kern/subr_taskqueue.c:281 > > stack backtrace: > > #0 0x80c32881 at witness_debugger+0x71 > > #1 0x80ba3e54 at __mtx_lock_flags+0x94 > > #2 0x80c24bd2 at taskqueue_enqueue+0x42 > > #3 0x80a1af99 at vtnet_rxq_tq_intr+0xb9 > > #4 0x80c2520a at taskqueue_run_locked+0xaa > > #5 0x80c26284 at taskqueue_thread_loop+0x94 > > #6 0x80b830e0 at fork_exit+0x80 > > #7 0x81040eae at fork_trampoline+0xe > > Hm, I think that's just a false-positive, because if_vtnet constructs > the taskqueue using the same name as its own internal mutexes. Though > the locking around vtnet_rx_vq_intr and vtnet_rxq_tq_intr is a bit > fishy given they're rather similar yet inconsistent. I would imagine > rxq->vtnrx_stats.vrxs_rescheduled is supposed to be protected by that > mutex, but wouldn't like to say whether taskqueue_enqueue needs to be. > Vincenzo, you recently touched code around there, perhaps you could be > persuaded to have a quick look?.. > Yes, you are right on both. There is also code duplication that can be easily removed. I will fix that. Cheers, Vincenzo > > Jess > > ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to
Re: svn commit: r361944 - in head/sys/dev/virtio: . network
You may already know that, but FreeBSD-CURRENT supports mergeable rx buffers as of r358180. Cheers, Vincenzo Il giorno dom 14 giu 2020 alle ore 22:56 Jessica Clarke ha scritto: > On 14 Jun 2020, at 20:51, Tom Jones wrote: > > On Mon, Jun 08, 2020 at 09:51:36PM +, Jessica Clarke wrote: > >> Author: jrtc27 > >> Date: Mon Jun 8 21:51:36 2020 > >> New Revision: 361944 > >> URL: https://svnweb.freebsd.org/changeset/base/361944 > >> > >> Log: > >> virtio: Support non-legacy network device and queue > >> > >> The non-legacy interface always defines num_buffers in the header, > >> regardless of whether VIRTIO_NET_F_MRG_RXBUF, just leaving it unused. > We > >> also need to ensure our virtqueue doesn't filter out VIRTIO_F_VERSION_1 > >> during negotiation, as it supports non-legacy transports just fine. > This > >> fixes network packet transmission on TinyEMU. > >> > >> Reviewed by:br, brooks (mentor), jhb (mentor) > >> Approved by:br, brooks (mentor), jhb (mentor) > >> Differential Revision: https://reviews.freebsd.org/D25132 > >> > >> Modified: > >> head/sys/dev/virtio/network/if_vtnet.c > >> head/sys/dev/virtio/network/if_vtnetvar.h > >> head/sys/dev/virtio/virtio.c > >> head/sys/dev/virtio/virtqueue.c > >> > > > > Hi Jessica, > > > > After updating my current bhyve vm today (on a 12.1 host), networking no > longer > > works. Reverting this commit seems to resolve the issue. I think vtnet > is not > > passing enough data up to the ip layer. > > > > If I capture on the tap interface for the vm I see arp requests and arp > > replies, however kern.msgbuf is full of: > > > > <5>arp: short packet received on vtnet0 > > > > and netstat does not see any replies to arp requests: > > > > root@freebsd-current:~ # netstat -s -p arp > > arp: > >11 ARP requests sent > >0 ARP requests failed to sent > >0 ARP replies sent > >0 ARP requests received > >0 ARP replies received > >0 ARP packets received > >24 total packets dropped due to no ARP entry > >2 ARP entrys timed out > >0 Duplicate IPs seen > > > > If I set up an arp entry manually I can see ICMP echo requests and > responses on > > the tap interface, but the vm does not see the responses. > > > > root@freebsd-current:~ # netstat -s -p ip > > ip: > >7 total packets received > >0 bad header checksums > >0 with size smaller than minimum > >7 with data size < data length > >0 with ip length > max ip packet size > >0 with header length < data size > >0 with data length < header length > > > > The line > > > >7 with data size < data length > > > > makes me think that vtnet is truncating packets. > > > > markj pointed me at this bug in irc which might also be related: > > > > https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=247242 > > Hi Tom, > Sorry about that; it seems bhyve hits the "legacy and no MrgRxBuf" > case. Could you please try the patch below? > > Jess > > diff --git a/sys/dev/virtio/network/if_vtnet.c > b/sys/dev/virtio/network/if_vtnet.c > index 7a0859cc0eb1..7e10b75f7f66 100644 > --- a/sys/dev/virtio/network/if_vtnet.c > +++ b/sys/dev/virtio/network/if_vtnet.c > @@ -1819,9 +1819,10 @@ vtnet_rxq_eof(struct vtnet_rxq *rxq) > adjsz = sizeof(struct vtnet_rx_header); > /* > * Account for our pad inserted between the header > - * and the actual start of the frame. > + * and the actual start of the frame. This includes > + * the unused num_buffers when using a legacy device. > */ > -len += VTNET_RX_HEADER_PAD; > +len += adjsz - sc->vtnet_hdr_size; > } else { > mhdr = mtod(m, struct virtio_net_hdr_mrg_rxbuf *); > nbufs = mhdr->num_buffers; > > ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362185 - head/sys/net
Author: vmaffione Date: Sun Jun 14 21:07:12 2020 New Revision: 362185 URL: https://svnweb.freebsd.org/changeset/base/362185 Log: iflib: netmap: enter/exit netmap mode after device stops Avoid possible race conditions by calling nm_set_native_flags() and nm_clear_native_flags() only after the device has been stopped. MFC after:1 week Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cSun Jun 14 20:57:24 2020(r362184) +++ head/sys/net/iflib.cSun Jun 14 21:07:12 2020(r362185) @@ -788,13 +788,19 @@ iflib_netmap_register(struct netmap_adapter *na, int o if (!CTX_IS_VF(ctx)) IFDI_CRCSTRIP_SET(ctx, onoff, iflib_crcstrip); - /* enable or disable flags and callbacks in na and ifp */ + iflib_stop(ctx); + + /* +* Enable (or disable) netmap flags, and intercept (or restore) +* ifp->if_transmit. This is done once the device has been stopped +* to prevent race conditions. +*/ if (onoff) { nm_set_native_flags(na); } else { nm_clear_native_flags(na); } - iflib_stop(ctx); + iflib_init_locked(ctx); IFDI_CRCSTRIP_SET(ctx, onoff, iflib_crcstrip); // XXX why twice ? status = ifp->if_drv_flags & IFF_DRV_RUNNING ? 0 : 1; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362183 - in head/sys/dev: netmap virtio/network
Author: vmaffione Date: Sun Jun 14 20:47:31 2020 New Revision: 362183 URL: https://svnweb.freebsd.org/changeset/base/362183 Log: netmap: vtnet: fix races in vtnet_netmap_reg() The nm_register callback needs to call nm_set_native_flags() or nm_clear_native_flags() once the device has been stopped. However, in the current implementation this is not true, as the device is stopped by vtnet_init_locked(). This causes race conditions where the driver crashes as soon as it dequeues netmap buffers assuming they are mbufs (or the other way around). To fix the issue, we extend vtnet_init_locked() with a second argument that, if not zero, will set/clear the netmap flags. This results in a huge simplification of the nm_register callback itself. Also, use netmap_reset() to check if a ring is going to be re-initialized in netmap mode. MFC after:1 week Modified: head/sys/dev/netmap/if_vtnet_netmap.h head/sys/dev/virtio/network/if_vtnet.c head/sys/dev/virtio/network/if_vtnetvar.h Modified: head/sys/dev/netmap/if_vtnet_netmap.h == --- head/sys/dev/netmap/if_vtnet_netmap.h Sun Jun 14 19:41:24 2020 (r362182) +++ head/sys/dev/netmap/if_vtnet_netmap.h Sun Jun 14 20:47:31 2020 (r362183) @@ -39,52 +39,18 @@ vtnet_netmap_reg(struct netmap_adapter *na, int state) { struct ifnet *ifp = na->ifp; struct vtnet_softc *sc = ifp->if_softc; - int success; - int i; - /* Drain the taskqueues to make sure that there are no worker threads -* accessing the virtqueues. */ - vtnet_drain_taskqueues(sc); - + /* +* Trigger a device reinit, asking vtnet_init_locked() to +* also enter or exit netmap mode. +*/ VTNET_CORE_LOCK(sc); - - /* We need nm_netmap_on() to return true when called by -* vtnet_init_locked() below. */ - if (state) - nm_set_native_flags(na); - - /* We need to trigger a device reset in order to unexpose guest buffers -* published to the host. */ - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - /* Get pending used buffers. The way they are freed depends on whether -* they are netmap buffer or they are mbufs. We can tell apart the two -* cases by looking at kring->nr_mode, before this is possibly updated -* in the loop below. */ - for (i = 0; i < sc->vtnet_act_vq_pairs; i++) { - struct vtnet_txq *txq = >vtnet_txqs[i]; - struct vtnet_rxq *rxq = >vtnet_rxqs[i]; - - VTNET_TXQ_LOCK(txq); - vtnet_txq_free_mbufs(txq); - VTNET_TXQ_UNLOCK(txq); - - VTNET_RXQ_LOCK(rxq); - vtnet_rxq_free_mbufs(rxq); - VTNET_RXQ_UNLOCK(rxq); - } - vtnet_init_locked(sc); - success = (ifp->if_drv_flags & IFF_DRV_RUNNING) ? 0 : ENXIO; - - if (state) { - netmap_krings_mode_commit(na, state); - } else { - nm_clear_native_flags(na); - netmap_krings_mode_commit(na, state); - } - + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + vtnet_init_locked(sc, state ? VTNET_INIT_NETMAP_ENTER + : VTNET_INIT_NETMAP_EXIT); VTNET_CORE_UNLOCK(sc); - return success; + return 0; } @@ -245,15 +211,13 @@ vtnet_netmap_rxq_populate(struct vtnet_rxq *rxq) { struct netmap_adapter *na = NA(rxq->vtnrx_sc->vtnet_ifp); struct netmap_kring *kring; + struct netmap_slot *slot; int error; - if (!nm_native_on(na) || rxq->vtnrx_id >= na->num_rx_rings) + slot = netmap_reset(na, NR_RX, rxq->vtnrx_id, 0); + if (slot == NULL) return -1; - kring = na->rx_rings[rxq->vtnrx_id]; - if (!(nm_kring_pending_on(kring) || - kring->nr_pending_mode == NKR_NETMAP_ON)) - return -1; /* Expose all the RX netmap buffers we can. In case of no indirect * buffers, the number of netmap slots in the RX ring matches the Modified: head/sys/dev/virtio/network/if_vtnet.c == --- head/sys/dev/virtio/network/if_vtnet.c Sun Jun 14 19:41:24 2020 (r362182) +++ head/sys/dev/virtio/network/if_vtnet.c Sun Jun 14 20:47:31 2020 (r362183) @@ -181,7 +181,7 @@ static int vtnet_init_tx_queues(struct vtnet_softc *); static int vtnet_init_rxtx_queues(struct vtnet_softc *); static voidvtnet_set_active_vq_pairs(struct vtnet_softc *); static int vtnet_reinit(struct vtnet_softc *); -static voidvtnet_init_locked(struct vtnet_softc *); +static voidvtnet_init_locked(struct vtnet_softc *, int); static voidvtnet_init(void *); static voidvtnet_free_ctrl_vq(struct vtnet_softc *); @@ -523,7 +523,7 @@ vtnet_resume(device_t
svn commit: r362076 - in head/sys/dev: netmap virtio/network
Author: vmaffione Date: Thu Jun 11 20:35:28 2020 New Revision: 362076 URL: https://svnweb.freebsd.org/changeset/base/362076 Log: netmap: introduce netmap_kring_on() This function returns NULL if the ring identified by queue id and direction is in netmap mode. Otherwise return the corresponding kring. Use this function to replace vtnet_netmap_queue_on(). MFC after:1 week Modified: head/sys/dev/netmap/if_vtnet_netmap.h head/sys/dev/netmap/netmap_kern.h head/sys/dev/virtio/network/if_vtnet.c Modified: head/sys/dev/netmap/if_vtnet_netmap.h == --- head/sys/dev/netmap/if_vtnet_netmap.h Thu Jun 11 20:26:39 2020 (r362075) +++ head/sys/dev/netmap/if_vtnet_netmap.h Thu Jun 11 20:35:28 2020 (r362076) @@ -33,25 +33,6 @@ #include /* vtophys ? */ #include -/* - * Return 1 if the queue identified by 't' and 'idx' is in netmap mode. - */ -static int -vtnet_netmap_queue_on(struct vtnet_softc *sc, enum txrx t, int idx) -{ - struct netmap_adapter *na = NA(sc->vtnet_ifp); - - if (!nm_native_on(na)) - return 0; - - if (t == NR_RX) - return !!(idx < na->num_rx_rings && - na->rx_rings[idx]->nr_mode == NKR_NETMAP_ON); - - return !!(idx < na->num_tx_rings && - na->tx_rings[idx]->nr_mode == NKR_NETMAP_ON); -} - /* Register and unregister. */ static int vtnet_netmap_reg(struct netmap_adapter *na, int state) Modified: head/sys/dev/netmap/netmap_kern.h == --- head/sys/dev/netmap/netmap_kern.h Thu Jun 11 20:26:39 2020 (r362075) +++ head/sys/dev/netmap/netmap_kern.h Thu Jun 11 20:35:28 2020 (r362076) @@ -1353,6 +1353,24 @@ nm_native_on(struct netmap_adapter *na) return nm_netmap_on(na) && (na->na_flags & NAF_NATIVE); } +static inline struct netmap_kring * +netmap_kring_on(struct netmap_adapter *na, u_int q, enum txrx t) +{ + struct netmap_kring *kring = NULL; + + if (!nm_native_on(na)) + return NULL; + + if (t == NR_RX && q < na->num_rx_rings) + kring = na->rx_rings[q]; + else if (t == NR_TX && q < na->num_tx_rings) + kring = na->tx_rings[q]; + else + return NULL; + + return (kring->nr_mode == NKR_NETMAP_ON) ? kring : NULL; +} + static inline int nm_iszombie(struct netmap_adapter *na) { Modified: head/sys/dev/virtio/network/if_vtnet.c == --- head/sys/dev/virtio/network/if_vtnet.c Thu Jun 11 20:26:39 2020 (r362075) +++ head/sys/dev/virtio/network/if_vtnet.c Thu Jun 11 20:35:28 2020 (r362076) @@ -1249,17 +1249,17 @@ vtnet_rxq_free_mbufs(struct vtnet_rxq *rxq) struct mbuf *m; int last; #ifdef DEV_NETMAP - int netmap_bufs = vtnet_netmap_queue_on(rxq->vtnrx_sc, NR_RX, - rxq->vtnrx_id); + struct netmap_kring *kring = netmap_kring_on(NA(rxq->vtnrx_sc->vtnet_ifp), + rxq->vtnrx_id, NR_RX); #else /* !DEV_NETMAP */ - int netmap_bufs = 0; + void *kring = NULL; #endif /* !DEV_NETMAP */ vq = rxq->vtnrx_vq; last = 0; while ((m = virtqueue_drain(vq, )) != NULL) { - if (!netmap_bufs) + if (kring == NULL) m_freem(m); } @@ -2074,17 +2074,17 @@ vtnet_txq_free_mbufs(struct vtnet_txq *txq) struct vtnet_tx_header *txhdr; int last; #ifdef DEV_NETMAP - int netmap_bufs = vtnet_netmap_queue_on(txq->vtntx_sc, NR_TX, - txq->vtntx_id); + struct netmap_kring *kring = netmap_kring_on(NA(txq->vtntx_sc->vtnet_ifp), + txq->vtntx_id, NR_TX); #else /* !DEV_NETMAP */ - int netmap_bufs = 0; + void *kring = NULL; #endif /* !DEV_NETMAP */ vq = txq->vtntx_vq; last = 0; while ((txhdr = virtqueue_drain(vq, )) != NULL) { - if (!netmap_bufs) { + if (kring == NULL) { m_freem(txhdr->vth_mbuf); uma_zfree(vtnet_tx_header_zone, txhdr); } ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362026 - stable/12/sys/dev/netmap
Author: vmaffione Date: Wed Jun 10 20:05:53 2020 New Revision: 362026 URL: https://svnweb.freebsd.org/changeset/base/362026 Log: MFC r361760 netmap: vtnet: clean up rxsync disabled logs Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h == --- stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 20:05:07 2020 (r362025) +++ stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 20:05:53 2020 (r362026) @@ -363,8 +363,6 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl kring->nr_hwtail = nm_i; kring->nr_kflags &= ~NKR_PENDINTR; } - nm_prdis("[B] h %d c %d hwcur %d hwtail %d", ring->head, ring->cur, - kring->nr_hwcur, kring->nr_hwtail); /* * Second part: skip past packets that userspace has released. @@ -387,8 +385,8 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl virtqueue_notify(vq); } - nm_prdis("[C] h %d c %d t %d hwcur %d hwtail %d", ring->head, ring->cur, - ring->tail, kring->nr_hwcur, kring->nr_hwtail); + nm_prdis("h %d c %d t %d hwcur %d hwtail %d", kring->rhead, + kring->rcur, kring->rtail, kring->nr_hwcur, kring->nr_hwtail); return 0; } ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362025 - stable/12/sys/dev/netmap
Author: vmaffione Date: Wed Jun 10 20:05:07 2020 New Revision: 362025 URL: https://svnweb.freebsd.org/changeset/base/362025 Log: MFC r361759 netmap: vtnet: fix race condition in rxsync This change prevents a race that happens when rxsync dequeues N-1 rx packets (with N being the size of the netmap rx ring). In this situation, the loop exits without re-enabling the rx interrupts, thus causing the VQ to stall. Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h == --- stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 20:04:20 2020 (r362024) +++ stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 20:05:07 2020 (r362025) @@ -310,8 +310,11 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl /* * First part: import newly received packets. * Only accept our own buffers (matching the token). We should only get -* matching buffers. We may need to stop early to avoid hwtail to overrun -* hwcur. +* matching buffers. The hwtail should never overrun hwcur, because +* we publish only N-1 receive buffers (and non N). +* In any case we must not leave this routine with the interrupts +* disabled, pending packets in the VQ and hwtail == (hwcur - 1), +* otherwise the pending packets could stall. */ if (netmap_no_pendintr || force_update) { uint32_t hwtail_lim = nm_prev(kring->nr_hwcur, lim); @@ -320,10 +323,17 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl vtnet_rxq_disable_intr(rxq); nm_i = kring->nr_hwtail; - while (nm_i != hwtail_lim) { + for (;;) { int len; token = virtqueue_dequeue(vq, ); if (token == NULL) { + /* +* Enable the interrupts again and double-check +* for more work. We can go on until we win the +* race condition, since we are not replenishing +* in the meanwhile, and thus we will process at +* most N-1 slots. +*/ if (interrupts && vtnet_rxq_enable_intr(rxq)) { vtnet_rxq_disable_intr(rxq); continue; @@ -333,6 +343,11 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl if (unlikely(token != (void *)rxq)) { nm_prerr("BUG: RX token mismatch"); } else { + if (nm_i == hwtail_lim) { + KASSERT(false, ("hwtail would " + "overrun hwcur")); + } + /* Skip the virtio-net header. */ len -= sc->vtnet_hdr_size; if (unlikely(len < 0)) { ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362024 - in stable/12/sys/dev: netmap virtio/network
Author: vmaffione Date: Wed Jun 10 20:04:20 2020 New Revision: 362024 URL: https://svnweb.freebsd.org/changeset/base/362024 Log: MFC r361758 netmap: vtnet: add vtnrx_nm_refill index to receive queues The new index tracks the next netmap slot that is going to be enqueued into the virtqueue. The index is necessary to prevent the receive VQ and the netmap rx ring from going out of sync, considering that we never enqueue N slots, but at most N-1. This change fixes a bug that causes the VQ and the netmap ring to go out of sync after N-1 packets have been received. Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h stable/12/sys/dev/virtio/network/if_vtnetvar.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h == --- stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 20:03:11 2020 (r362023) +++ stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 20:04:20 2020 (r362024) @@ -196,9 +196,11 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int fl } /* - * Publish (up to) num netmap receive buffers to the host, - * starting from the first one that the user made available - * (kring->nr_hwcur). + * Publish 'num 'netmap receive buffers to the host, starting + * from the next available one (rx->vtnrx_nm_refill). + * Return a positive error code on error, and 0 on success. + * If we could not publish all of the buffers that's an error, + * since the netmap ring and the virtqueue would go out of sync. */ static int vtnet_netmap_kring_refill(struct netmap_kring *kring, u_int num) @@ -208,7 +210,7 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring, struct netmap_ring *ring = kring->ring; u_int ring_nr = kring->ring_id; u_int const lim = kring->nkr_num_slots - 1; - u_int nm_i = kring->nr_hwcur; + u_int nm_i; /* device-specific */ struct vtnet_softc *sc = ifp->if_softc; @@ -219,7 +221,8 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring, struct sglist_seg ss[2]; struct sglist sg = { ss, 0, 0, 2 }; - for (; num > 0; nm_i = nm_next(nm_i, lim), num--) { + for (nm_i = rxq->vtnrx_nm_refill; num > 0; + nm_i = nm_next(nm_i, lim), num--) { struct netmap_slot *slot = >slot[nm_i]; uint64_t paddr; void *addr = PNMB(na, slot, ); @@ -227,7 +230,7 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring, if (addr == NETMAP_BUF_BASE(na)) { /* bad buf */ if (netmap_ring_reinit(kring)) - return -1; + return EFAULT; } slot->flags &= ~NS_BUF_CHANGED; @@ -240,14 +243,14 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring, err = virtqueue_enqueue(vq, /*cookie=*/rxq, , /*readable=*/0, /*writeable=*/sg.sg_nseg); if (unlikely(err)) { - if (err != ENOSPC) - nm_prerr("virtqueue_enqueue(%s) failed: %d", - kring->name, err); + nm_prerr("virtqueue_enqueue(%s) failed: %d", + kring->name, err); break; } } + rxq->vtnrx_nm_refill = nm_i; - return nm_i; + return num == 0 ? 0 : ENOSPC; } /* @@ -274,11 +277,14 @@ vtnet_netmap_rxq_populate(struct vtnet_rxq *rxq) /* Expose all the RX netmap buffers we can. In case of no indirect * buffers, the number of netmap slots in the RX ring matches the * maximum number of 2-elements sglist that the RX virtqueue can -* accommodate (minus 1 to avoid netmap ring wraparound). */ +* accommodate. We need to start from kring->nr_hwcur, which is 0 +* on netmap register and may be different from 0 if a virtio +* re-init happens while the device is in use by netmap. */ + rxq->vtnrx_nm_refill = kring->nr_hwcur; error = vtnet_netmap_kring_refill(kring, na->num_rx_desc - 1); virtqueue_notify(rxq->vtnrx_vq); - return error < 0 ? ENXIO : 0; + return error; } /* Reconcile kernel and user view of the receive ring. */ @@ -350,15 +356,19 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl */ nm_i = kring->nr_hwcur; /* netmap ring index */ if (nm_i != head) { - int howmany = head - nm_i; - int nm_j; + int released; + int error; - if (howmany < 0) - howmany += kring->nkr_num_slots; - nm_j = vtnet_netmap_kring_refill(kring, howmany); - if (nm_j < 0) - return nm_j; - kring->nr_hwcur = nm_j; +
svn commit: r362023 - stable/12/sys/dev/netmap
Author: vmaffione Date: Wed Jun 10 20:03:11 2020 New Revision: 362023 URL: https://svnweb.freebsd.org/changeset/base/362023 Log: MFC r361746 netmap: vale: fix disabled logs Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h == --- stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 20:02:38 2020 (r362022) +++ stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 20:03:11 2020 (r362023) @@ -129,7 +129,6 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int fl /* * First part: process new packets to send. */ - rmb(); nm_i = kring->nr_hwcur; if (nm_i != head) { /* we have new packets to send */ @@ -302,7 +301,6 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl struct vtnet_rxq *rxq = >vtnet_rxqs[ring_nr]; struct virtqueue *vq = rxq->vtnrx_vq; - rmb(); /* * First part: import newly received packets. * Only accept our own buffers (matching the token). We should only get ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362022 - stable/12/sys/dev/virtio/network
Author: vmaffione Date: Wed Jun 10 20:02:38 2020 New Revision: 362022 URL: https://svnweb.freebsd.org/changeset/base/362022 Log: MFC r361745 netmap: vtnet: call netmap_rx_irq() under VQ lock The netmap_rx_irq() function normally wakes up user-space threads waiting for more packets. In this case, it is not necessary to call it under the driver queue lock. However, if the interface is attached to a VALE switch, netmap_rx_irq() ends up calling rxsync on the interface (see netmap_bwrap_intr_notify()). Although concurrent rxsyncs are serialized through the kring lock (see nm_kr_tryget()), the lock acquire operation is not blocking. As a result, it may happen that netmap_rx_irq() is called on an RX ring while another instance is running, causing the second call to fail, and received packets stall in the receive VQ. We fix this issue by calling netmap_irx_irq() under the VQ lock. Modified: stable/12/sys/dev/virtio/network/if_vtnet.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/virtio/network/if_vtnet.c == --- stable/12/sys/dev/virtio/network/if_vtnet.c Wed Jun 10 19:59:11 2020 (r362021) +++ stable/12/sys/dev/virtio/network/if_vtnet.c Wed Jun 10 20:02:38 2020 (r362022) @@ -1873,9 +1873,20 @@ vtnet_rx_vq_intr(void *xrxq) return; } + VTNET_RXQ_LOCK(rxq); + #ifdef DEV_NETMAP + /* +* We call netmap_rx_irq() under lock to prevent concurrent calls. +* This is not necessary to serialize the access to the RX vq, but +* rather to avoid races that may happen if this interface is +* attached to a VALE switch, which would cause received packets +* to stall in the RX queue (nm_kr_tryget() could find the kring +* busy when called from netmap_bwrap_intr_notify()). +*/ nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, ); if (nmirq != NM_IRQ_PASS) { + VTNET_RXQ_UNLOCK(rxq); if (nmirq == NM_IRQ_RESCHED) { taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); } @@ -1883,8 +1894,6 @@ vtnet_rx_vq_intr(void *xrxq) } #endif /* DEV_NETMAP */ - VTNET_RXQ_LOCK(rxq); - again: if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { VTNET_RXQ_UNLOCK(rxq); @@ -1924,17 +1933,18 @@ vtnet_rxq_tq_intr(void *xrxq, int pending) sc = rxq->vtnrx_sc; ifp = sc->vtnet_ifp; + VTNET_RXQ_LOCK(rxq); + #ifdef DEV_NETMAP nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, ); if (nmirq != NM_IRQ_PASS) { + VTNET_RXQ_UNLOCK(rxq); if (nmirq == NM_IRQ_RESCHED) { taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); } return; } #endif /* DEV_NETMAP */ - - VTNET_RXQ_LOCK(rxq); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { VTNET_RXQ_UNLOCK(rxq); ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362021 - stable/12/sys/dev/virtio/network
Author: vmaffione Date: Wed Jun 10 19:59:11 2020 New Revision: 362021 URL: https://svnweb.freebsd.org/changeset/base/362021 Log: MFC r361744 netmap: vtnet: honor NM_IRQ_RESCHED The netmap_rx_irq() function may return NM_IRQ_RESCHED to inform the driver that more work is pending, and that netmap expects netmap_rx_irq() to be called again as soon as possible. This change implements this behaviour in the vtnet driver. Modified: stable/12/sys/dev/virtio/network/if_vtnet.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/virtio/network/if_vtnet.c == --- stable/12/sys/dev/virtio/network/if_vtnet.c Wed Jun 10 19:58:03 2020 (r362020) +++ stable/12/sys/dev/virtio/network/if_vtnet.c Wed Jun 10 19:59:11 2020 (r362021) @@ -1853,6 +1853,9 @@ vtnet_rx_vq_intr(void *xrxq) struct vtnet_rxq *rxq; struct ifnet *ifp; int tries, more; +#ifdef DEV_NETMAP + int nmirq; +#endif /* DEV_NETMAP */ rxq = xrxq; sc = rxq->vtnrx_sc; @@ -1871,8 +1874,13 @@ vtnet_rx_vq_intr(void *xrxq) } #ifdef DEV_NETMAP - if (netmap_rx_irq(ifp, rxq->vtnrx_id, ) != NM_IRQ_PASS) + nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, ); + if (nmirq != NM_IRQ_PASS) { + if (nmirq == NM_IRQ_RESCHED) { + taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); + } return; + } #endif /* DEV_NETMAP */ VTNET_RXQ_LOCK(rxq); @@ -1908,10 +1916,23 @@ vtnet_rxq_tq_intr(void *xrxq, int pending) struct vtnet_rxq *rxq; struct ifnet *ifp; int more; +#ifdef DEV_NETMAP + int nmirq; +#endif /* DEV_NETMAP */ rxq = xrxq; sc = rxq->vtnrx_sc; ifp = sc->vtnet_ifp; + +#ifdef DEV_NETMAP + nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, ); + if (nmirq != NM_IRQ_PASS) { + if (nmirq == NM_IRQ_RESCHED) { + taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); + } + return; + } +#endif /* DEV_NETMAP */ VTNET_RXQ_LOCK(rxq); ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362020 - stable/12/sys/dev/netmap
Author: vmaffione Date: Wed Jun 10 19:58:03 2020 New Revision: 362020 URL: https://svnweb.freebsd.org/changeset/base/362020 Log: MFC r361698 netmap: if_vtnet: avoid netmap ring wraparound netmap assumes the one "slot" is left unused to distinguish the empty ring and full ring conditions. This assumption was violated by vtnet_netmap_rxq_populate(). Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h == --- stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 19:57:10 2020 (r362019) +++ stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 19:58:03 2020 (r362020) @@ -275,8 +275,8 @@ vtnet_netmap_rxq_populate(struct vtnet_rxq *rxq) /* Expose all the RX netmap buffers we can. In case of no indirect * buffers, the number of netmap slots in the RX ring matches the * maximum number of 2-elements sglist that the RX virtqueue can -* accommodate. */ - error = vtnet_netmap_kring_refill(kring, na->num_rx_desc); +* accommodate (minus 1 to avoid netmap ring wraparound). */ + error = vtnet_netmap_kring_refill(kring, na->num_rx_desc - 1); virtqueue_notify(rxq->vtnrx_vq); return error < 0 ? ENXIO : 0; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362019 - stable/12/sys/dev/netmap
Author: vmaffione Date: Wed Jun 10 19:57:10 2020 New Revision: 362019 URL: https://svnweb.freebsd.org/changeset/base/362019 Log: MFC r361697 netmap: if_vtnet: replace vtnet_free_used() The functionality contained in this function is duplicated, as it is already available in vtnet_txq_free_mbufs() and vtnet_rxq_free_mbufs(). Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h == --- stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 19:55:36 2020 (r362018) +++ stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 19:57:10 2020 (r362019) @@ -52,37 +52,6 @@ vtnet_netmap_queue_on(struct vtnet_softc *sc, enum txr na->tx_rings[idx]->nr_mode == NKR_NETMAP_ON); } -static void -vtnet_free_used(struct virtqueue *vq, int netmap_bufs, enum txrx t, int idx) -{ - void *cookie; - int deq = 0; - - while ((cookie = virtqueue_dequeue(vq, NULL)) != NULL) { - if (netmap_bufs) { - /* These are netmap buffers: there is nothing to do. */ - } else { - /* These are mbufs that we need to free. */ - struct mbuf *m; - - if (t == NR_TX) { - struct vtnet_tx_header *txhdr = cookie; - m = txhdr->vth_mbuf; - m_freem(m); - uma_zfree(vtnet_tx_header_zone, txhdr); - } else { - m = cookie; - m_freem(m); - } - } - deq++; - } - - if (deq) - nm_prinf("%d sgs dequeued from %s-%d (netmap=%d)", -deq, nm_txrx2str(t), idx, netmap_bufs); -} - /* Register and unregister. */ static int vtnet_netmap_reg(struct netmap_adapter *na, int state) @@ -113,18 +82,13 @@ vtnet_netmap_reg(struct netmap_adapter *na, int state) for (i = 0; i < sc->vtnet_act_vq_pairs; i++) { struct vtnet_txq *txq = >vtnet_txqs[i]; struct vtnet_rxq *rxq = >vtnet_rxqs[i]; - struct netmap_kring *kring; VTNET_TXQ_LOCK(txq); - kring = NMR(na, NR_TX)[i]; - vtnet_free_used(txq->vtntx_vq, - kring->nr_mode == NKR_NETMAP_ON, NR_TX, i); + vtnet_txq_free_mbufs(txq); VTNET_TXQ_UNLOCK(txq); VTNET_RXQ_LOCK(rxq); - kring = NMR(na, NR_RX)[i]; - vtnet_free_used(rxq->vtnrx_vq, - kring->nr_mode == NKR_NETMAP_ON, NR_RX, i); + vtnet_rxq_free_mbufs(rxq); VTNET_RXQ_UNLOCK(rxq); } vtnet_init_locked(sc); ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r362018 - stable/12/sys/dev/netmap
Author: vmaffione Date: Wed Jun 10 19:55:36 2020 New Revision: 362018 URL: https://svnweb.freebsd.org/changeset/base/362018 Log: MFC r361696 netmap: vtnet: fix RX virtqueue initialization bug The vtnet_netmap_rxq_populate() function erroneously assumed that kring->nr_hwcur = 0, i.e. the kring was in the initial state. However, this is not always the case: for example, when a vtnet reinit is triggered by some changes in the interface flags or capenable. This patch changes the behaviour of vtnet_netmap_kring_refill() so that it always starts publishing the netmap buffers starting from the current value of kring->nr_hwcur. Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/netmap/if_vtnet_netmap.h == --- stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 19:23:58 2020 (r362017) +++ stable/12/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 10 19:55:36 2020 (r362018) @@ -232,14 +232,20 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int fl return 0; } +/* + * Publish (up to) num netmap receive buffers to the host, + * starting from the first one that the user made available + * (kring->nr_hwcur). + */ static int -vtnet_netmap_kring_refill(struct netmap_kring *kring, u_int nm_i, u_int head) +vtnet_netmap_kring_refill(struct netmap_kring *kring, u_int num) { struct netmap_adapter *na = kring->na; struct ifnet *ifp = na->ifp; struct netmap_ring *ring = kring->ring; u_int ring_nr = kring->ring_id; u_int const lim = kring->nkr_num_slots - 1; + u_int nm_i = kring->nr_hwcur; /* device-specific */ struct vtnet_softc *sc = ifp->if_softc; @@ -250,7 +256,7 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring, struct sglist_seg ss[2]; struct sglist sg = { ss, 0, 0, 2 }; - for (; nm_i != head; nm_i = nm_next(nm_i, lim)) { + for (; num > 0; nm_i = nm_next(nm_i, lim), num--) { struct netmap_slot *slot = >slot[nm_i]; uint64_t paddr; void *addr = PNMB(na, slot, ); @@ -302,10 +308,11 @@ vtnet_netmap_rxq_populate(struct vtnet_rxq *rxq) kring->nr_pending_mode == NKR_NETMAP_ON)) return -1; - /* Expose all the RX netmap buffers. Note that the number of -* netmap slots in the RX ring matches the maximum number of -* 2-elements sglist that the RX virtqueue can accommodate. */ - error = vtnet_netmap_kring_refill(kring, 0, na->num_rx_desc); + /* Expose all the RX netmap buffers we can. In case of no indirect +* buffers, the number of netmap slots in the RX ring matches the +* maximum number of 2-elements sglist that the RX virtqueue can +* accommodate. */ + error = vtnet_netmap_kring_refill(kring, na->num_rx_desc); virtqueue_notify(rxq->vtnrx_vq); return error < 0 ? ENXIO : 0; @@ -381,7 +388,12 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl */ nm_i = kring->nr_hwcur; /* netmap ring index */ if (nm_i != head) { - int nm_j = vtnet_netmap_kring_refill(kring, nm_i, head); + int howmany = head - nm_i; + int nm_j; + + if (howmany < 0) + howmany += kring->nkr_num_slots; + nm_j = vtnet_netmap_kring_refill(kring, howmany); if (nm_j < 0) return nm_j; kring->nr_hwcur = nm_j; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r361982 - head/sys/net
Author: vmaffione Date: Tue Jun 9 19:15:43 2020 New Revision: 361982 URL: https://svnweb.freebsd.org/changeset/base/361982 Log: iflib: netmap: honor netmap_irx_irq return values In the receive interrupt routine, always call netmap_rx_irq(). The latter function will return != NM_IRQ_PASS if netmap is not active on that specific receive queue, so that the driver can go on with iflib_rxeof(). Note that netmap supports partial opening, where only a subset of the RX or TX rings can be open in netmap mode. Checking the IFCAP_NETMAP flag is not enough to make sure that the queue is indeed in netmap mode. Moreover, in case netmap_rx_irq() returns NM_IRQ_RESCHED, it means that netmap expects the driver to call netmap_rx_irq() again as soon as possible. Currently, this may happen when the device is attached to a VALE switch. Reviewed by: gallatin MFC after:2 weeks Differential Revision:https://reviews.freebsd.org/D25167 Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c == --- head/sys/net/iflib.cTue Jun 9 19:07:44 2020(r361981) +++ head/sys/net/iflib.cTue Jun 9 19:15:43 2020(r361982) @@ -3790,6 +3790,10 @@ _task_fn_rx(void *context) if_ctx_t ctx = rxq->ifr_ctx; uint8_t more; uint16_t budget; +#ifdef DEV_NETMAP + u_int work = 0; + int nmirq; +#endif #ifdef IFLIB_DIAGNOSTICS rxq->ifr_cpu_exec_count[curcpu]++; @@ -3798,12 +3802,10 @@ _task_fn_rx(void *context) if (__predict_false(!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING))) return; #ifdef DEV_NETMAP - if (if_getcapenable(ctx->ifc_ifp) & IFCAP_NETMAP) { - u_int work = 0; - if (netmap_rx_irq(ctx->ifc_ifp, rxq->ifr_id, )) { - more = 0; - goto skip_rxeof; - } + nmirq = netmap_rx_irq(ctx->ifc_ifp, rxq->ifr_id, ); + if (nmirq != NM_IRQ_PASS) { + more = (nmirq == NM_IRQ_RESCHED) ? IFLIB_RXEOF_MORE : 0; + goto skip_rxeof; } #endif budget = ctx->ifc_sysctl_rx_budget; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r361760 - head/sys/dev/netmap
Author: vmaffione Date: Wed Jun 3 17:47:32 2020 New Revision: 361760 URL: https://svnweb.freebsd.org/changeset/base/361760 Log: netmap: vtnet: clean up rxsync disabled logs MFC after:1 week Modified: head/sys/dev/netmap/if_vtnet_netmap.h Modified: head/sys/dev/netmap/if_vtnet_netmap.h == --- head/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 3 17:46:21 2020 (r361759) +++ head/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 3 17:47:32 2020 (r361760) @@ -363,8 +363,6 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl kring->nr_hwtail = nm_i; kring->nr_kflags &= ~NKR_PENDINTR; } - nm_prdis("[B] h %d c %d hwcur %d hwtail %d", ring->head, ring->cur, - kring->nr_hwcur, kring->nr_hwtail); /* * Second part: skip past packets that userspace has released. @@ -387,8 +385,8 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl virtqueue_notify(vq); } - nm_prdis("[C] h %d c %d t %d hwcur %d hwtail %d", ring->head, ring->cur, - ring->tail, kring->nr_hwcur, kring->nr_hwtail); + nm_prdis("h %d c %d t %d hwcur %d hwtail %d", kring->rhead, + kring->rcur, kring->rtail, kring->nr_hwcur, kring->nr_hwtail); return 0; } ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r361759 - head/sys/dev/netmap
Author: vmaffione Date: Wed Jun 3 17:46:21 2020 New Revision: 361759 URL: https://svnweb.freebsd.org/changeset/base/361759 Log: netmap: vtnet: fix race condition in rxsync This change prevents a race that happens when rxsync dequeues N-1 rx packets (with N being the size of the netmap rx ring). In this situation, the loop exits without re-enabling the rx interrupts, thus causing the VQ to stall. MFC after:1 week Modified: head/sys/dev/netmap/if_vtnet_netmap.h Modified: head/sys/dev/netmap/if_vtnet_netmap.h == --- head/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 3 17:42:17 2020 (r361758) +++ head/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 3 17:46:21 2020 (r361759) @@ -310,8 +310,11 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl /* * First part: import newly received packets. * Only accept our own buffers (matching the token). We should only get -* matching buffers. We may need to stop early to avoid hwtail to overrun -* hwcur. +* matching buffers. The hwtail should never overrun hwcur, because +* we publish only N-1 receive buffers (and non N). +* In any case we must not leave this routine with the interrupts +* disabled, pending packets in the VQ and hwtail == (hwcur - 1), +* otherwise the pending packets could stall. */ if (netmap_no_pendintr || force_update) { uint32_t hwtail_lim = nm_prev(kring->nr_hwcur, lim); @@ -320,10 +323,17 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl vtnet_rxq_disable_intr(rxq); nm_i = kring->nr_hwtail; - while (nm_i != hwtail_lim) { + for (;;) { int len; token = virtqueue_dequeue(vq, ); if (token == NULL) { + /* +* Enable the interrupts again and double-check +* for more work. We can go on until we win the +* race condition, since we are not replenishing +* in the meanwhile, and thus we will process at +* most N-1 slots. +*/ if (interrupts && vtnet_rxq_enable_intr(rxq)) { vtnet_rxq_disable_intr(rxq); continue; @@ -333,6 +343,11 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl if (unlikely(token != (void *)rxq)) { nm_prerr("BUG: RX token mismatch"); } else { + if (nm_i == hwtail_lim) { + KASSERT(false, ("hwtail would " + "overrun hwcur")); + } + /* Skip the virtio-net header. */ len -= sc->vtnet_hdr_size; if (unlikely(len < 0)) { ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r361758 - in head/sys/dev: netmap virtio/network
Author: vmaffione Date: Wed Jun 3 17:42:17 2020 New Revision: 361758 URL: https://svnweb.freebsd.org/changeset/base/361758 Log: netmap: vtnet: add vtnrx_nm_refill index to receive queues The new index tracks the next netmap slot that is going to be enqueued into the virtqueue. The index is necessary to prevent the receive VQ and the netmap rx ring from going out of sync, considering that we never enqueue N slots, but at most N-1. This change fixes a bug that causes the VQ and the netmap ring to go out of sync after N-1 packets have been received. MFC after:1 week Modified: head/sys/dev/netmap/if_vtnet_netmap.h head/sys/dev/virtio/network/if_vtnetvar.h Modified: head/sys/dev/netmap/if_vtnet_netmap.h == --- head/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 3 17:26:00 2020 (r361757) +++ head/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 3 17:42:17 2020 (r361758) @@ -196,9 +196,11 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int fl } /* - * Publish (up to) num netmap receive buffers to the host, - * starting from the first one that the user made available - * (kring->nr_hwcur). + * Publish 'num 'netmap receive buffers to the host, starting + * from the next available one (rx->vtnrx_nm_refill). + * Return a positive error code on error, and 0 on success. + * If we could not publish all of the buffers that's an error, + * since the netmap ring and the virtqueue would go out of sync. */ static int vtnet_netmap_kring_refill(struct netmap_kring *kring, u_int num) @@ -208,7 +210,7 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring, struct netmap_ring *ring = kring->ring; u_int ring_nr = kring->ring_id; u_int const lim = kring->nkr_num_slots - 1; - u_int nm_i = kring->nr_hwcur; + u_int nm_i; /* device-specific */ struct vtnet_softc *sc = ifp->if_softc; @@ -219,7 +221,8 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring, struct sglist_seg ss[2]; struct sglist sg = { ss, 0, 0, 2 }; - for (; num > 0; nm_i = nm_next(nm_i, lim), num--) { + for (nm_i = rxq->vtnrx_nm_refill; num > 0; + nm_i = nm_next(nm_i, lim), num--) { struct netmap_slot *slot = >slot[nm_i]; uint64_t paddr; void *addr = PNMB(na, slot, ); @@ -227,7 +230,7 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring, if (addr == NETMAP_BUF_BASE(na)) { /* bad buf */ if (netmap_ring_reinit(kring)) - return -1; + return EFAULT; } slot->flags &= ~NS_BUF_CHANGED; @@ -240,14 +243,14 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring, err = virtqueue_enqueue(vq, /*cookie=*/rxq, , /*readable=*/0, /*writeable=*/sg.sg_nseg); if (unlikely(err)) { - if (err != ENOSPC) - nm_prerr("virtqueue_enqueue(%s) failed: %d", - kring->name, err); + nm_prerr("virtqueue_enqueue(%s) failed: %d", + kring->name, err); break; } } + rxq->vtnrx_nm_refill = nm_i; - return nm_i; + return num == 0 ? 0 : ENOSPC; } /* @@ -274,11 +277,14 @@ vtnet_netmap_rxq_populate(struct vtnet_rxq *rxq) /* Expose all the RX netmap buffers we can. In case of no indirect * buffers, the number of netmap slots in the RX ring matches the * maximum number of 2-elements sglist that the RX virtqueue can -* accommodate (minus 1 to avoid netmap ring wraparound). */ +* accommodate. We need to start from kring->nr_hwcur, which is 0 +* on netmap register and may be different from 0 if a virtio +* re-init happens while the device is in use by netmap. */ + rxq->vtnrx_nm_refill = kring->nr_hwcur; error = vtnet_netmap_kring_refill(kring, na->num_rx_desc - 1); virtqueue_notify(rxq->vtnrx_vq); - return error < 0 ? ENXIO : 0; + return error; } /* Reconcile kernel and user view of the receive ring. */ @@ -350,15 +356,19 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl */ nm_i = kring->nr_hwcur; /* netmap ring index */ if (nm_i != head) { - int howmany = head - nm_i; - int nm_j; + int released; + int error; - if (howmany < 0) - howmany += kring->nkr_num_slots; - nm_j = vtnet_netmap_kring_refill(kring, howmany); - if (nm_j < 0) - return nm_j; - kring->nr_hwcur = nm_j; + released = head - nm_i; + if (released < 0) +
svn commit: r361746 - head/sys/dev/netmap
Author: vmaffione Date: Wed Jun 3 05:48:42 2020 New Revision: 361746 URL: https://svnweb.freebsd.org/changeset/base/361746 Log: netmap: vtnet: remove leftover memory barriers MFC after:1 week Modified: head/sys/dev/netmap/if_vtnet_netmap.h Modified: head/sys/dev/netmap/if_vtnet_netmap.h == --- head/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 3 05:27:29 2020 (r361745) +++ head/sys/dev/netmap/if_vtnet_netmap.h Wed Jun 3 05:48:42 2020 (r361746) @@ -129,7 +129,6 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int fl /* * First part: process new packets to send. */ - rmb(); nm_i = kring->nr_hwcur; if (nm_i != head) { /* we have new packets to send */ @@ -302,7 +301,6 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl struct vtnet_rxq *rxq = >vtnet_rxqs[ring_nr]; struct virtqueue *vq = rxq->vtnrx_vq; - rmb(); /* * First part: import newly received packets. * Only accept our own buffers (matching the token). We should only get ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r361747 - head/sys/dev/netmap
Author: vmaffione Date: Wed Jun 3 05:49:19 2020 New Revision: 361747 URL: https://svnweb.freebsd.org/changeset/base/361747 Log: netmap: vale: fix disabled logs MFC after:1 week Modified: head/sys/dev/netmap/netmap_vale.c Modified: head/sys/dev/netmap/netmap_vale.c == --- head/sys/dev/netmap/netmap_vale.c Wed Jun 3 05:48:42 2020 (r361746) +++ head/sys/dev/netmap/netmap_vale.c Wed Jun 3 05:49:19 2020 (r361747) @@ -1034,7 +1034,7 @@ nm_vale_flush(struct nm_bdg_fwd *ft, u_int n, struct n } nm_prdis(5, "pass 2 dst %d is %x %s", - i, d_i, is_vp ? "virtual" : "nic/host"); + i, d_i, nm_is_bwrap(_na->up) ? "nic/host" : "virtual"); dst_nr = d_i & (NM_BDG_MAXRINGS-1); nrings = dst_na->up.num_rx_rings; if (dst_nr >= nrings) @@ -1114,7 +1114,7 @@ retry: nm_prdis("send [%d] %d(%d) bytes at %s:%d", i, (int)copy_len, (int)dst_len, - NM_IFPNAME(dst_ifp), j); + dst_na->up.name, j); /* round to a multiple of 64 */ copy_len = (copy_len + 63) & ~63; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r361745 - head/sys/dev/virtio/network
Author: vmaffione Date: Wed Jun 3 05:27:29 2020 New Revision: 361745 URL: https://svnweb.freebsd.org/changeset/base/361745 Log: netmap: vtnet: call netmap_rx_irq() under VQ lock The netmap_rx_irq() function normally wakes up user-space threads waiting for more packets. In this case, it is not necessary to call it under the driver queue lock. However, if the interface is attached to a VALE switch, netmap_rx_irq() ends up calling rxsync on the interface (see netmap_bwrap_intr_notify()). Although concurrent rxsyncs are serialized through the kring lock (see nm_kr_tryget()), the lock acquire operation is not blocking. As a result, it may happen that netmap_rx_irq() is called on an RX ring while another instance is running, causing the second call to fail, and received packets stall in the receive VQ. We fix this issue by calling netmap_irx_irq() under the VQ lock. MFC after:1 week Modified: head/sys/dev/virtio/network/if_vtnet.c Modified: head/sys/dev/virtio/network/if_vtnet.c == --- head/sys/dev/virtio/network/if_vtnet.c Wed Jun 3 05:09:33 2020 (r361744) +++ head/sys/dev/virtio/network/if_vtnet.c Wed Jun 3 05:27:29 2020 (r361745) @@ -1936,9 +1936,20 @@ vtnet_rx_vq_intr(void *xrxq) return; } + VTNET_RXQ_LOCK(rxq); + #ifdef DEV_NETMAP + /* +* We call netmap_rx_irq() under lock to prevent concurrent calls. +* This is not necessary to serialize the access to the RX vq, but +* rather to avoid races that may happen if this interface is +* attached to a VALE switch, which would cause received packets +* to stall in the RX queue (nm_kr_tryget() could find the kring +* busy when called from netmap_bwrap_intr_notify()). +*/ nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, ); if (nmirq != NM_IRQ_PASS) { + VTNET_RXQ_UNLOCK(rxq); if (nmirq == NM_IRQ_RESCHED) { taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); } @@ -1946,8 +1957,6 @@ vtnet_rx_vq_intr(void *xrxq) } #endif /* DEV_NETMAP */ - VTNET_RXQ_LOCK(rxq); - again: if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { VTNET_RXQ_UNLOCK(rxq); @@ -1987,17 +1996,18 @@ vtnet_rxq_tq_intr(void *xrxq, int pending) sc = rxq->vtnrx_sc; ifp = sc->vtnet_ifp; + VTNET_RXQ_LOCK(rxq); + #ifdef DEV_NETMAP nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, ); if (nmirq != NM_IRQ_PASS) { + VTNET_RXQ_UNLOCK(rxq); if (nmirq == NM_IRQ_RESCHED) { taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); } return; } #endif /* DEV_NETMAP */ - - VTNET_RXQ_LOCK(rxq); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { VTNET_RXQ_UNLOCK(rxq); ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r361744 - head/sys/dev/virtio/network
Author: vmaffione Date: Wed Jun 3 05:09:33 2020 New Revision: 361744 URL: https://svnweb.freebsd.org/changeset/base/361744 Log: netmap: vtnet: honor NM_IRQ_RESCHED The netmap_rx_irq() function may return NM_IRQ_RESCHED to inform the driver that more work is pending, and that netmap expects netmap_rx_irq() to be called again as soon as possible. This change implements this behaviour in the vtnet driver. MFC after:1 week Modified: head/sys/dev/virtio/network/if_vtnet.c Modified: head/sys/dev/virtio/network/if_vtnet.c == --- head/sys/dev/virtio/network/if_vtnet.c Wed Jun 3 05:00:40 2020 (r361743) +++ head/sys/dev/virtio/network/if_vtnet.c Wed Jun 3 05:09:33 2020 (r361744) @@ -1916,6 +1916,9 @@ vtnet_rx_vq_intr(void *xrxq) struct vtnet_rxq *rxq; struct ifnet *ifp; int tries, more; +#ifdef DEV_NETMAP + int nmirq; +#endif /* DEV_NETMAP */ rxq = xrxq; sc = rxq->vtnrx_sc; @@ -1934,8 +1937,13 @@ vtnet_rx_vq_intr(void *xrxq) } #ifdef DEV_NETMAP - if (netmap_rx_irq(ifp, rxq->vtnrx_id, ) != NM_IRQ_PASS) + nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, ); + if (nmirq != NM_IRQ_PASS) { + if (nmirq == NM_IRQ_RESCHED) { + taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); + } return; + } #endif /* DEV_NETMAP */ VTNET_RXQ_LOCK(rxq); @@ -1971,10 +1979,23 @@ vtnet_rxq_tq_intr(void *xrxq, int pending) struct vtnet_rxq *rxq; struct ifnet *ifp; int more; +#ifdef DEV_NETMAP + int nmirq; +#endif /* DEV_NETMAP */ rxq = xrxq; sc = rxq->vtnrx_sc; ifp = sc->vtnet_ifp; + +#ifdef DEV_NETMAP + nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, ); + if (nmirq != NM_IRQ_PASS) { + if (nmirq == NM_IRQ_RESCHED) { + taskqueue_enqueue(rxq->vtnrx_tq, >vtnrx_intrtask); + } + return; + } +#endif /* DEV_NETMAP */ VTNET_RXQ_LOCK(rxq); ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r361698 - head/sys/dev/netmap
Author: vmaffione Date: Mon Jun 1 16:14:29 2020 New Revision: 361698 URL: https://svnweb.freebsd.org/changeset/base/361698 Log: netmap: if_vtnet: avoid netmap ring wraparound netmap assumes the one "slot" is left unused to distinguish the empty ring and full ring conditions. This assumption was violated by vtnet_netmap_rxq_populate(). MFC after:1 week Modified: head/sys/dev/netmap/if_vtnet_netmap.h Modified: head/sys/dev/netmap/if_vtnet_netmap.h == --- head/sys/dev/netmap/if_vtnet_netmap.h Mon Jun 1 16:12:09 2020 (r361697) +++ head/sys/dev/netmap/if_vtnet_netmap.h Mon Jun 1 16:14:29 2020 (r361698) @@ -275,8 +275,8 @@ vtnet_netmap_rxq_populate(struct vtnet_rxq *rxq) /* Expose all the RX netmap buffers we can. In case of no indirect * buffers, the number of netmap slots in the RX ring matches the * maximum number of 2-elements sglist that the RX virtqueue can -* accommodate. */ - error = vtnet_netmap_kring_refill(kring, na->num_rx_desc); +* accommodate (minus 1 to avoid netmap ring wraparound). */ + error = vtnet_netmap_kring_refill(kring, na->num_rx_desc - 1); virtqueue_notify(rxq->vtnrx_vq); return error < 0 ? ENXIO : 0; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r361697 - head/sys/dev/netmap
Author: vmaffione Date: Mon Jun 1 16:12:09 2020 New Revision: 361697 URL: https://svnweb.freebsd.org/changeset/base/361697 Log: netmap: if_vtnet: replace vtnet_free_used() The functionality contained in this function is duplicated, as it is already available in vtnet_txq_free_mbufs() and vtnet_rxq_free_mbufs(). MFC after:1 week Modified: head/sys/dev/netmap/if_vtnet_netmap.h Modified: head/sys/dev/netmap/if_vtnet_netmap.h == --- head/sys/dev/netmap/if_vtnet_netmap.h Mon Jun 1 16:10:44 2020 (r361696) +++ head/sys/dev/netmap/if_vtnet_netmap.h Mon Jun 1 16:12:09 2020 (r361697) @@ -52,37 +52,6 @@ vtnet_netmap_queue_on(struct vtnet_softc *sc, enum txr na->tx_rings[idx]->nr_mode == NKR_NETMAP_ON); } -static void -vtnet_free_used(struct virtqueue *vq, int netmap_bufs, enum txrx t, int idx) -{ - void *cookie; - int deq = 0; - - while ((cookie = virtqueue_dequeue(vq, NULL)) != NULL) { - if (netmap_bufs) { - /* These are netmap buffers: there is nothing to do. */ - } else { - /* These are mbufs that we need to free. */ - struct mbuf *m; - - if (t == NR_TX) { - struct vtnet_tx_header *txhdr = cookie; - m = txhdr->vth_mbuf; - m_freem(m); - uma_zfree(vtnet_tx_header_zone, txhdr); - } else { - m = cookie; - m_freem(m); - } - } - deq++; - } - - if (deq) - nm_prinf("%d sgs dequeued from %s-%d (netmap=%d)", -deq, nm_txrx2str(t), idx, netmap_bufs); -} - /* Register and unregister. */ static int vtnet_netmap_reg(struct netmap_adapter *na, int state) @@ -113,18 +82,13 @@ vtnet_netmap_reg(struct netmap_adapter *na, int state) for (i = 0; i < sc->vtnet_act_vq_pairs; i++) { struct vtnet_txq *txq = >vtnet_txqs[i]; struct vtnet_rxq *rxq = >vtnet_rxqs[i]; - struct netmap_kring *kring; VTNET_TXQ_LOCK(txq); - kring = NMR(na, NR_TX)[i]; - vtnet_free_used(txq->vtntx_vq, - kring->nr_mode == NKR_NETMAP_ON, NR_TX, i); + vtnet_txq_free_mbufs(txq); VTNET_TXQ_UNLOCK(txq); VTNET_RXQ_LOCK(rxq); - kring = NMR(na, NR_RX)[i]; - vtnet_free_used(rxq->vtnrx_vq, - kring->nr_mode == NKR_NETMAP_ON, NR_RX, i); + vtnet_rxq_free_mbufs(rxq); VTNET_RXQ_UNLOCK(rxq); } vtnet_init_locked(sc); ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r361696 - head/sys/dev/netmap
Author: vmaffione Date: Mon Jun 1 16:10:44 2020 New Revision: 361696 URL: https://svnweb.freebsd.org/changeset/base/361696 Log: netmap: vtnet: fix RX virtqueue initialization bug The vtnet_netmap_rxq_populate() function erroneously assumed that kring->nr_hwcur = 0, i.e. the kring was in the initial state. However, this is not always the case: for example, when a vtnet reinit is triggered by some changes in the interface flags or capenable. This patch changes the behaviour of vtnet_netmap_kring_refill() so that it always starts publishing the netmap buffers starting from the current value of kring->nr_hwcur. MFC after:1 week Modified: head/sys/dev/netmap/if_vtnet_netmap.h Modified: head/sys/dev/netmap/if_vtnet_netmap.h == --- head/sys/dev/netmap/if_vtnet_netmap.h Mon Jun 1 15:58:22 2020 (r361695) +++ head/sys/dev/netmap/if_vtnet_netmap.h Mon Jun 1 16:10:44 2020 (r361696) @@ -232,14 +232,20 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int fl return 0; } +/* + * Publish (up to) num netmap receive buffers to the host, + * starting from the first one that the user made available + * (kring->nr_hwcur). + */ static int -vtnet_netmap_kring_refill(struct netmap_kring *kring, u_int nm_i, u_int head) +vtnet_netmap_kring_refill(struct netmap_kring *kring, u_int num) { struct netmap_adapter *na = kring->na; struct ifnet *ifp = na->ifp; struct netmap_ring *ring = kring->ring; u_int ring_nr = kring->ring_id; u_int const lim = kring->nkr_num_slots - 1; + u_int nm_i = kring->nr_hwcur; /* device-specific */ struct vtnet_softc *sc = ifp->if_softc; @@ -250,7 +256,7 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring, struct sglist_seg ss[2]; struct sglist sg = { ss, 0, 0, 2 }; - for (; nm_i != head; nm_i = nm_next(nm_i, lim)) { + for (; num > 0; nm_i = nm_next(nm_i, lim), num--) { struct netmap_slot *slot = >slot[nm_i]; uint64_t paddr; void *addr = PNMB(na, slot, ); @@ -302,10 +308,11 @@ vtnet_netmap_rxq_populate(struct vtnet_rxq *rxq) kring->nr_pending_mode == NKR_NETMAP_ON)) return -1; - /* Expose all the RX netmap buffers. Note that the number of -* netmap slots in the RX ring matches the maximum number of -* 2-elements sglist that the RX virtqueue can accommodate. */ - error = vtnet_netmap_kring_refill(kring, 0, na->num_rx_desc); + /* Expose all the RX netmap buffers we can. In case of no indirect +* buffers, the number of netmap slots in the RX ring matches the +* maximum number of 2-elements sglist that the RX virtqueue can +* accommodate. */ + error = vtnet_netmap_kring_refill(kring, na->num_rx_desc); virtqueue_notify(rxq->vtnrx_vq); return error < 0 ? ENXIO : 0; @@ -381,7 +388,12 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl */ nm_i = kring->nr_hwcur; /* netmap ring index */ if (nm_i != head) { - int nm_j = vtnet_netmap_kring_refill(kring, nm_i, head); + int howmany = head - nm_i; + int nm_j; + + if (howmany < 0) + howmany += kring->nkr_num_slots; + nm_j = vtnet_netmap_kring_refill(kring, howmany); if (nm_j < 0) return nm_j; kring->nr_hwcur = nm_j; ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r360837 - head/usr.sbin/bhyve
Author: vmaffione Date: Sat May 9 07:57:41 2020 New Revision: 360837 URL: https://svnweb.freebsd.org/changeset/base/360837 Log: bhyve: update man page to describe the virtio-net mtu option r359704 introduced an 'mtu' option for the virtio-net device emulation. Update the man page to describe the new option. Reviewed by: bcr Differential Revision:https://reviews.freebsd.org/D24723 Modified: head/usr.sbin/bhyve/bhyve.8 Modified: head/usr.sbin/bhyve/bhyve.8 == --- head/usr.sbin/bhyve/bhyve.8 Sat May 9 06:25:20 2020(r360836) +++ head/usr.sbin/bhyve/bhyve.8 Sat May 9 07:57:41 2020(r360837) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 04, 2020 +.Dd May 5, 2020 .Dt BHYVE 8 .Os .Sh NAME @@ -293,8 +293,8 @@ considered unconnected. .Pp Network devices: .Bl -tag -width 10n -.It Ar tapN Ns Op , Ns Ar mac=xx:xx:xx:xx:xx:xx -.It Ar vmnetN Ns Op , Ns Ar mac=xx:xx:xx:xx:xx:xx +.It Ar tapN Ns Oo , Ns Ar mac=xx:xx:xx:xx:xx:xx Oc Ns Oo , Ns Ar mtu=N Oc +.It Ar vmnetN Ns Oo , Ns Ar mac=xx:xx:xx:xx:xx:xx Oc Ns Oo , Ns Ar mtu=N Oc .Pp If .Ar mac @@ -305,6 +305,11 @@ the device name. The MAC address is an ASCII string in .Xr ethers 5 format. +.Pp +With virtio-net devices, the +.Ar mtu +parameter can be specified to inform the guest about the largest MTU +that should be allowed, expressed in bytes. .El .Pp Block storage devices: ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r359610 - stable/11/tools/tools/netmap
Author: vmaffione Date: Fri Apr 3 19:00:11 2020 New Revision: 359610 URL: https://svnweb.freebsd.org/changeset/base/359610 Log: netmap: vale-ctl: fix typo in man page Submitted by: Jose Luis Duran Modified: stable/11/tools/tools/netmap/vale-ctl.4 Modified: stable/11/tools/tools/netmap/vale-ctl.4 == --- stable/11/tools/tools/netmap/vale-ctl.4 Fri Apr 3 18:55:22 2020 (r359609) +++ stable/11/tools/tools/netmap/vale-ctl.4 Fri Apr 3 19:00:11 2020 (r359610) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 24, 2018 +.Dd April 3, 2020 .Dt VALE-CTL 4 .Os .Sh NAME @@ -95,7 +95,7 @@ Create a new persistent VALE port with name .Ar interface . The name must be different from any other network interface already present in the system. -.It Fl d Ar interface +.It Fl r Ar interface Destroy the persistent VALE port with name .Ar inteface . .It Fl l Ar valeSSS:PPP ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
svn commit: r359609 - stable/12/usr.sbin/valectl
Author: vmaffione Date: Fri Apr 3 18:55:22 2020 New Revision: 359609 URL: https://svnweb.freebsd.org/changeset/base/359609 Log: MFC r359489 valectl: fix typo in man page Submitted by: Jose Luis Duran MFC after: 3 days Modified: stable/12/usr.sbin/valectl/valectl.8 Directory Properties: stable/12/ (props changed) Modified: stable/12/usr.sbin/valectl/valectl.8 == --- stable/12/usr.sbin/valectl/valectl.8Fri Apr 3 17:17:17 2020 (r359608) +++ stable/12/usr.sbin/valectl/valectl.8Fri Apr 3 18:55:22 2020 (r359609) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 26, 2019 +.Dd March 31, 2020 .Dt VALECTL 8 .Os .Sh NAME @@ -95,7 +95,7 @@ Create a new persistent VALE port with name .Ar interface . The name must be different from any other network interface already present in the system. -.It Fl d Ar interface +.It Fl r Ar interface Destroy the persistent VALE port with name .Ar inteface . .It Fl l Ar valeSSS:PPP ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"