netmap: bridge: fix transmission in busy-wait mode

In busy-wait mode (BUSYWAIT defined), NIOCTXSYNC should be
performed after packets have been moved to the TX ring
(rather than before).
Before the change, moved packets may stall for an indefinite
time in the TX ring.

MFC after:	1 week
This commit is contained in:
Vincenzo Maffione 2021-03-30 06:24:56 +00:00
parent 27bf5dd3d4
commit 51cc31088b

View File

@ -17,6 +17,10 @@
#include <stdlib.h>
#include <unistd.h>
#if defined(_WIN32)
#define BUSYWAIT
#endif
static int verbose = 0;
static int do_abort = 0;
@ -321,21 +325,19 @@ main(int argc, char **argv)
pollfd[0].revents = pollfd[1].revents = 0;
n0 = rx_slots_avail(pa);
n1 = rx_slots_avail(pb);
#if defined(_WIN32) || defined(BUSYWAIT)
#ifdef BUSYWAIT
if (n0) {
ioctl(pollfd[1].fd, NIOCTXSYNC, NULL);
pollfd[1].revents = POLLOUT;
} else {
ioctl(pollfd[0].fd, NIOCRXSYNC, NULL);
}
if (n1) {
ioctl(pollfd[0].fd, NIOCTXSYNC, NULL);
pollfd[0].revents = POLLOUT;
} else {
ioctl(pollfd[1].fd, NIOCRXSYNC, NULL);
}
ret = 1;
#else
#else /* !defined(BUSYWAIT) */
if (n0)
pollfd[1].events |= POLLOUT;
else
@ -347,7 +349,7 @@ main(int argc, char **argv)
/* poll() also cause kernel to txsync/rxsync the NICs */
ret = poll(pollfd, 2, 2500);
#endif /* defined(_WIN32) || defined(BUSYWAIT) */
#endif /* !defined(BUSYWAIT) */
if (ret <= 0 || verbose)
D("poll %s [0] ev %x %x rx %d@%d tx %d,"
" [1] ev %x %x rx %d@%d tx %d",
@ -375,11 +377,19 @@ main(int argc, char **argv)
D("error on fd1, rx [%d,%d,%d)",
rx->head, rx->cur, rx->tail);
}
if (pollfd[0].revents & POLLOUT)
if (pollfd[0].revents & POLLOUT) {
ports_move(pb, pa, burst, msg_b2a);
#ifdef BUSYWAIT
ioctl(pollfd[0].fd, NIOCTXSYNC, NULL);
#endif
}
if (pollfd[1].revents & POLLOUT)
if (pollfd[1].revents & POLLOUT) {
ports_move(pa, pb, burst, msg_a2b);
#ifdef BUSYWAIT
ioctl(pollfd[1].fd, NIOCTXSYNC, NULL);
#endif
}
/*
* We don't need ioctl(NIOCTXSYNC) on the two file descriptors.