diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2014-03-26 14:30:51 +0100 |
---|---|---|
committer | Daniel Borkmann <dborkman@redhat.com> | 2014-03-26 14:42:41 +0100 |
commit | c139e809f8562a2e9a1e24e86abc5a7c6eee6254 (patch) | |
tree | b247674a07c3e2c9cbec803818b24655d5c0d1bb | |
parent | 51168327bf55a604a6560a2c9838ade8209f816a (diff) |
trafgen: remove timer-based trigger model
perf reports in mmap case a huge number of kmem_cache_alloc's
which seem to stem from triggering signals from kernel to user
application, against dummy device:
Performance counter stats for 'trafgen -i blub -o dummy0 -n100000000 -k100': <-- mmap case
175,837 kmem:kmem_cache_alloc
14.758900522 seconds time elapsed
Performance counter stats for 'trafgen -i blub -o dummy0 -n100000000 -k100 -t0': <-- non-mmap case
707 kmem:kmem_cache_alloc
15.591667364 seconds time elapsed
It seems not to case significant number of cache-misses, but
it's better to switch to a direct trigger when we cannot fill
new frames anymore. After this patch, we see a similar number
of kmem_cache_alloc's as in the non-mmap case. This basically
renders the kpull interval useless, we can optionally remove
it if we don't care about people's scripts. ;-)
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
-rw-r--r-- | trafgen.c | 53 |
1 files changed, 10 insertions, 43 deletions
@@ -111,8 +111,6 @@ static const struct option long_options[] = { }; static int sock; -static struct itimerval itimer; -static unsigned long interval = TX_KERNEL_PULL_INT; static struct cpu_stats *stats; static unsigned int seed; @@ -141,38 +139,6 @@ static void signal_handler(int number) } } -static void timer_elapsed(int unused __maybe_unused) -{ - int ret = pull_and_flush_tx_ring(sock); - if (unlikely(ret < 0)) { - /* We could hit EBADF if the socket has been closed before - * the timer was triggered. - */ - if (errno != EBADF && errno != ENOBUFS) - panic("Flushing TX_RING failed: %s!\n", strerror(errno)); - } - - set_itimer_interval_value(&itimer, 0, interval); - setitimer(ITIMER_REAL, &itimer, NULL); -} - -static void timer_purge(void) -{ - int ret; - - ret = pull_and_flush_tx_ring_wait(sock); - if (unlikely(ret < 0)) { - /* We could hit EBADF if the socket has been closed before - * the timer was triggered. - */ - if (errno != EBADF && errno != ENOBUFS) - panic("Flushing TX_RING failed: %s!\n", strerror(errno)); - } - - set_itimer_interval_value(&itimer, 0, 0); - setitimer(ITIMER_REAL, &itimer, NULL); -} - static void __noreturn help(void) { printf("\ntrafgen %s, multithreaded zero-copy network packet generator\n", VERSION_STRING); @@ -647,21 +613,24 @@ static void xmit_fastpath_or_die(struct ctx *ctx, int cpu, unsigned long orig_nu drop_privileges(ctx->enforce, ctx->uid, ctx->gid); - if (ctx->kpull) - interval = ctx->kpull; if (ctx->num > 0) num = ctx->num; if (ctx->num == 0 && orig_num > 0) num = 0; - set_itimer_interval_value(&itimer, 0, interval); - setitimer(ITIMER_REAL, &itimer, NULL); - bug_on(gettimeofday(&start, NULL)); while (likely(sigint == 0 && num > 0 && plen > 0)) { if (!user_may_pull_from_tx(tx_ring.frames[it].iov_base)) { - sched_yield(); + int ret = pull_and_flush_tx_ring(sock); + if (unlikely(ret < 0)) { + /* We could hit EBADF if the socket has been closed before + * the timer was triggered. + */ + if (errno != EBADF && errno != ENOBUFS) + panic("Flushing TX_RING failed: %s!\n", strerror(errno)); + } + continue; } @@ -703,8 +672,7 @@ static void xmit_fastpath_or_die(struct ctx *ctx, int cpu, unsigned long orig_nu bug_on(gettimeofday(&end, NULL)); timersub(&end, &start, &diff); - timer_purge(); - + pull_and_flush_tx_ring_wait(sock); destroy_tx_ring(sock, &tx_ring); stats[cpu].tx_packets = tx_packets; @@ -1081,7 +1049,6 @@ int main(int argc, char **argv) register_signal(SIGQUIT, signal_handler); register_signal(SIGTERM, signal_handler); register_signal(SIGHUP, signal_handler); - register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); if (prio_high) { set_proc_prio(-20); |