aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/hrtimer.c2
-rw-r--r--net/core/pktgen.c49
2 files changed, 30 insertions, 21 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 49da79ab8486..05071bf6a37b 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -485,6 +485,7 @@ void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t clock_id,
485 debug_object_init_on_stack(timer, &hrtimer_debug_descr); 485 debug_object_init_on_stack(timer, &hrtimer_debug_descr);
486 __hrtimer_init(timer, clock_id, mode); 486 __hrtimer_init(timer, clock_id, mode);
487} 487}
488EXPORT_SYMBOL_GPL(hrtimer_init_on_stack);
488 489
489void destroy_hrtimer_on_stack(struct hrtimer *timer) 490void destroy_hrtimer_on_stack(struct hrtimer *timer)
490{ 491{
@@ -1477,6 +1478,7 @@ void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task)
1477 sl->timer.function = hrtimer_wakeup; 1478 sl->timer.function = hrtimer_wakeup;
1478 sl->task = task; 1479 sl->task = task;
1479} 1480}
1481EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
1480 1482
1481static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) 1483static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
1482{ 1484{
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index bede00b54038..3045dd133071 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -131,6 +131,7 @@
131#include <linux/ioport.h> 131#include <linux/ioport.h>
132#include <linux/interrupt.h> 132#include <linux/interrupt.h>
133#include <linux/capability.h> 133#include <linux/capability.h>
134#include <linux/hrtimer.h>
134#include <linux/freezer.h> 135#include <linux/freezer.h>
135#include <linux/delay.h> 136#include <linux/delay.h>
136#include <linux/timer.h> 137#include <linux/timer.h>
@@ -2086,33 +2087,40 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
2086 pkt_dev->nflows = 0; 2087 pkt_dev->nflows = 0;
2087} 2088}
2088 2089
2089static inline s64 delta_ns(ktime_t a, ktime_t b)
2090{
2091 return ktime_to_ns(ktime_sub(a, b));
2092}
2093 2090
2094static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until) 2091static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
2095{ 2092{
2096 ktime_t start, now; 2093 ktime_t start;
2097 s64 dt; 2094 s32 remaining;
2095 struct hrtimer_sleeper t;
2098 2096
2099 start = now = ktime_now(); 2097 hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
2098 hrtimer_set_expires(&t.timer, spin_until);
2099
2100 remaining = ktime_to_us(hrtimer_expires_remaining(&t.timer));
2101 if (remaining <= 0)
2102 return;
2100 2103
2101 while ((dt = delta_ns(spin_until, now)) > 0) { 2104 start = ktime_now();
2102 /* TODO: optimize sleeping behavior */ 2105 if (remaining < 100)
2103 if (dt > TICK_NSEC) 2106 udelay(remaining); /* really small just spin */
2104 schedule_timeout_interruptible(1); 2107 else {
2105 else if (dt > 100*NSEC_PER_USEC) { 2108 /* see do_nanosleep */
2106 if (!pkt_dev->running) 2109 hrtimer_init_sleeper(&t, current);
2107 return; 2110 do {
2108 if (need_resched()) 2111 set_current_state(TASK_INTERRUPTIBLE);
2112 hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS);
2113 if (!hrtimer_active(&t.timer))
2114 t.task = NULL;
2115
2116 if (likely(t.task))
2109 schedule(); 2117 schedule();
2110 }
2111 2118
2112 now = ktime_now(); 2119 hrtimer_cancel(&t.timer);
2120 } while (t.task && pkt_dev->running && !signal_pending(current));
2121 __set_current_state(TASK_RUNNING);
2113 } 2122 }
2114 2123 pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(), start));
2115 pkt_dev->idle_acc += ktime_to_ns(ktime_sub(now, start));
2116} 2124}
2117 2125
2118static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev) 2126static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
@@ -3360,8 +3368,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
3360 int ret; 3368 int ret;
3361 3369
3362 if (pkt_dev->delay) { 3370 if (pkt_dev->delay) {
3363 if (ktime_lt(ktime_now(), pkt_dev->next_tx)) 3371 spin(pkt_dev, pkt_dev->next_tx);
3364 spin(pkt_dev, pkt_dev->next_tx);
3365 3372
3366 /* This is max DELAY, this has special meaning of 3373 /* This is max DELAY, this has special meaning of
3367 * "never transmit" 3374 * "never transmit"