*/
#include <linux/module.h>
-#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
u64 value, rho;
unsigned long answer;
- if (state->rho == 0) /* no correllation */
+ if (state->rho == 0) /* no correlation */
return net_random();
value = net_random();
delay = tabledist(q->latency, q->jitter,
&q->delay_cor, q->delay_dist);
- PSCHED_GET_TIME(now);
- PSCHED_TADD2(now, delay, cb->time_to_send);
+ now = psched_get_time();
+ cb->time_to_send = now + delay;
++q->counter;
ret = q->qdisc->enqueue(skb, q->qdisc);
} else {
* Do re-ordering by putting one out of N packets at the front
* of the queue.
*/
- PSCHED_GET_TIME(cb->time_to_send);
+ cb->time_to_send = psched_get_time();
q->counter = 0;
ret = q->qdisc->ops->requeue(skb, q->qdisc);
}
struct netem_sched_data *q = qdisc_priv(sch);
struct sk_buff *skb;
+ smp_mb();
+ if (sch->flags & TCQ_F_THROTTLED)
+ return NULL;
+
skb = q->qdisc->dequeue(q->qdisc);
if (skb) {
const struct netem_skb_cb *cb
= (const struct netem_skb_cb *)skb->cb;
- psched_time_t now;
+ psched_time_t now = psched_get_time();
/* if more time remaining? */
- PSCHED_GET_TIME(now);
-
- if (PSCHED_TLESS(cb->time_to_send, now)) {
+ if (cb->time_to_send <= now) {
pr_debug("netem_dequeue: return skb=%p\n", skb);
sch->q.qlen--;
- sch->flags &= ~TCQ_F_THROTTLED;
return skb;
- } else {
- qdisc_watchdog_schedule(&q->watchdog, cb->time_to_send);
-
- if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
- qdisc_tree_decrease_qlen(q->qdisc, 1);
- sch->qstats.drops++;
- printk(KERN_ERR "netem: queue discpline %s could not requeue\n",
- q->qdisc->ops->id);
- }
}
+
+ if (unlikely(q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS)) {
+ qdisc_tree_decrease_qlen(q->qdisc, 1);
+ sch->qstats.drops++;
+ printk(KERN_ERR "netem: %s could not requeue\n",
+ q->qdisc->ops->id);
+ }
+
+ qdisc_watchdog_schedule(&q->watchdog, cb->time_to_send);
}
return NULL;
q->loss = qopt->loss;
q->duplicate = qopt->duplicate;
- /* for compatiablity with earlier versions.
- * if gap is set, need to assume 100% probablity
+ /* for compatibility with earlier versions.
+ * if gap is set, need to assume 100% probability
*/
if (q->gap)
q->reorder = ~0;
if (likely(skb_queue_len(list) < q->limit)) {
/* Optimize for add at tail */
- if (likely(skb_queue_empty(list) || !PSCHED_TLESS(tnext, q->oldest))) {
+ if (likely(skb_queue_empty(list) || tnext >= q->oldest)) {
q->oldest = tnext;
return qdisc_enqueue_tail(nskb, sch);
}
const struct netem_skb_cb *cb
= (const struct netem_skb_cb *)skb->cb;
- if (!PSCHED_TLESS(tnext, cb->time_to_send))
+ if (tnext >= cb->time_to_send)
break;
}
} else
q->limit = max_t(u32, sch->dev->tx_queue_len, 1);
- PSCHED_SET_PASTPERFECT(q->oldest);
+ q->oldest = PSCHED_PASTPERFECT;
return 0;
}