From: Stephen Hemminger <shemminger@vyatta.com>
To: David Miller <davem@davemloft.net>,
Robert Olsson <Robert.Olsson@data.slu.se>
Cc: netdev@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@elte.hu>
Subject: [RFC 2/4] pktgen: spin using hrtimer
Date: Tue, 25 Aug 2009 23:15:15 -0700 [thread overview]
Message-ID: <20090826061728.694353568@vyatta.com> (raw)
In-Reply-To: 20090826061513.755294685@vyatta.com
[-- Attachment #1: pktgen-hrtimer-spin.patch --]
[-- Type: text/plain, Size: 3108 bytes --]
This changes how the pktgen thread spins/waits between
packets if delay is configured. The new code is basically
an revised version of what the nanosleep system call does.
It requires exporting hrtimer_init_sleeper from standard hrtimer
code, since pktgen can be a module.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
kernel/hrtimer.c | 1 +
net/core/pktgen.c | 43 ++++++++++++++++++++++++++-----------------
2 files changed, 27 insertions(+), 17 deletions(-)
--- a/net/core/pktgen.c 2009-08-25 22:49:33.979402479 -0700
+++ b/net/core/pktgen.c 2009-08-25 22:49:55.966424251 -0700
@@ -131,6 +131,7 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/capability.h>
+#include <linux/hrtimer.h>
#include <linux/freezer.h>
#include <linux/delay.h>
#include <linux/timer.h>
@@ -2084,33 +2085,32 @@ static void pktgen_setup_inject(struct p
pkt_dev->nflows = 0;
}
-static inline s64 delta_ns(ktime_t a, ktime_t b)
-{
- return ktime_to_ns(ktime_sub(a, b));
-}
-
static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
{
- ktime_t start, now;
- s64 dt;
+ struct hrtimer_sleeper t;
+ enum hrtimer_mode mode = HRTIMER_MODE_REL;
+ unsigned long slack = rt_task(current) ? 0 : current->timer_slack_ns;
+
+ hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, mode);
+ hrtimer_set_expires_range_ns(&t.timer, spin_until, slack);
+ hrtimer_init_sleeper(&t, current);
- start = now = ktime_now();
+ /* based on do_nanosleep() */
+ do {
+ set_current_state(TASK_INTERRUPTIBLE);
+ hrtimer_start_expires(&t.timer, mode);
+ if (!hrtimer_active(&t.timer))
+ t.task = NULL;
- while ((dt = delta_ns(spin_until, now)) > 0) {
- /* TODO: optimize sleeping behavior */
- if (dt > TICK_NSEC)
- schedule_timeout_interruptible(1);
- else if (dt > 100*NSEC_PER_USEC) {
- if (!pkt_dev->running)
- return;
- if (need_resched())
- schedule();
- }
+ if (likely(t.task))
+ schedule();
- now = ktime_now();
- }
+ hrtimer_cancel(&t.timer);
+ mode = HRTIMER_MODE_ABS;
+ } while (t.task && pkt_dev->running && !signal_pending(current));
- pkt_dev->idle_acc += ktime_to_ns(ktime_sub(now, start));
+ __set_current_state(TASK_RUNNING);
+ destroy_hrtimer_on_stack(&t.timer);
}
static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
@@ -3352,8 +3352,12 @@ static __inline__ void pktgen_xmit(struc
int ret;
if (pkt_dev->delay) {
- if (ktime_lt(ktime_now(), pkt_dev->next_tx))
+ ktime_t start = ktime_now();
+ if (ktime_lt(start, pkt_dev->next_tx)) {
spin(pkt_dev, pkt_dev->next_tx);
+ pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(),
+ start));
+ }
/* This is max DELAY, this has special meaning of
* "never transmit"
--- a/kernel/hrtimer.c 2009-08-25 22:49:29.768405220 -0700
+++ b/kernel/hrtimer.c 2009-08-25 22:49:48.777711560 -0700
@@ -1477,6 +1477,7 @@ void hrtimer_init_sleeper(struct hrtimer
sl->timer.function = hrtimer_wakeup;
sl->task = task;
}
+EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
{
--
next prev parent reply other threads:[~2009-08-26 6:25 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-26 6:15 [RFC 0/4] pktgen patches Stephen Hemminger
2009-08-26 6:15 ` [RFC 1/4] pktgen: convert to use ktime_t Stephen Hemminger
2009-08-26 6:15 ` Stephen Hemminger [this message]
2009-08-26 6:15 ` [RFC 3/4] pktgen: clock optimizations Stephen Hemminger
2009-08-26 6:15 ` [RFC 4/4] pktgen: minor cleanup Stephen Hemminger
2009-08-26 6:54 ` [RFC 0/4] pktgen patches Eric Dumazet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090826061728.694353568@vyatta.com \
--to=shemminger@vyatta.com \
--cc=Robert.Olsson@data.slu.se \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.