lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Wed, 7 Mar 2007 15:59:36 -0800 From: Stephen Hemminger <shemminger@...ux-foundation.org> To: Patrick McHardy <kaber@...sh.net> Cc: netdev@...r.kernel.org Subject: Re: [RFC] use ktime for packet scheduling Here is the lastest version of the netem patch to use hrtimers. It is against the current net tree, so it will need adjusting to fit with new psched/ktime stuff. --- include/net/pkt_sched.h | 3 ++ net/sched/sch_api.c | 30 +++++++++++++++++++++ net/sched/sch_netem.c | 68 ++++++++++++++++++++++++------------------------ 3 files changed, 67 insertions(+), 34 deletions(-) --- netem-dev.orig/net/sched/sch_netem.c +++ netem-dev/net/sched/sch_netem.c @@ -54,7 +54,7 @@ struct netem_sched_data { struct Qdisc *qdisc; - struct timer_list timer; + struct hrtimer timer; u32 latency; u32 loss; @@ -78,8 +78,9 @@ struct netem_sched_data { }; /* Time stamp put into socket buffer control block */ +/* TODO: move this to skb->timestamp */ struct netem_skb_cb { - psched_time_t time_to_send; + ktime_t due_time; }; /* init_crandom - initialize correlated random number generator @@ -207,14 +208,14 @@ static int netem_enqueue(struct sk_buff if (q->gap == 0 /* not doing reordering */ || q->counter < q->gap /* inside last reordering gap */ || q->reorder < get_crandom(&q->reorder_cor)) { - psched_time_t now; - psched_tdiff_t delay; + u64 ns; - delay = tabledist(q->latency, q->jitter, - &q->delay_cor, q->delay_dist); + ns = tabledist(q->latency, q->jitter, + &q->delay_cor, q->delay_dist) * 1000ul; + + + cb->due_time = ktime_add_ns(ktime_get(), ns); - PSCHED_GET_TIME(now); - PSCHED_TADD2(now, delay, cb->time_to_send); ++q->counter; ret = q->qdisc->enqueue(skb, q->qdisc); } else { @@ -222,7 +223,7 @@ static int netem_enqueue(struct sk_buff * Do re-ordering by putting one out of N packets at the front * of the queue. */ - PSCHED_GET_TIME(cb->time_to_send); + cb->due_time = ktime_get(); q->counter = 0; ret = q->qdisc->ops->requeue(skb, q->qdisc); } @@ -273,41 +274,40 @@ static struct sk_buff *netem_dequeue(str if (skb) { const struct netem_skb_cb *cb = (const struct netem_skb_cb *)skb->cb; - psched_time_t now; + ktime_t now = ktime_get(); - /* if more time remaining? */ - PSCHED_GET_TIME(now); - - if (PSCHED_TLESS(cb->time_to_send, now)) { + /* if time has come to send? */ + if (now.tv64 <= cb->due_time.tv64) { pr_debug("netem_dequeue: return skb=%p\n", skb); sch->q.qlen--; sch->flags &= ~TCQ_F_THROTTLED; return skb; - } else { - psched_tdiff_t delay = PSCHED_TDIFF(cb->time_to_send, now); - - 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); - } + } - mod_timer(&q->timer, jiffies + PSCHED_US2JIFFIE(delay)); - sch->flags |= TCQ_F_THROTTLED; + 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); } + + hrtimer_start(&q->timer, cb->due_time, HRTIMER_MODE_ABS); + sch->flags |= TCQ_F_THROTTLED; } return NULL; } -static void netem_watchdog(unsigned long arg) +static enum hrtimer_restart netem_watchdog(struct hrtimer *hrt) { - struct Qdisc *sch = (struct Qdisc *)arg; + struct netem_sched_data *q + = container_of(hrt, struct netem_sched_data, timer); + struct Qdisc *sch = q->qdisc; pr_debug("netem_watchdog qlen=%d\n", sch->q.qlen); sch->flags &= ~TCQ_F_THROTTLED; netif_schedule(sch->dev); + return HRTIMER_NORESTART; } static void netem_reset(struct Qdisc *sch) @@ -317,7 +317,7 @@ static void netem_reset(struct Qdisc *sc qdisc_reset(q->qdisc); sch->q.qlen = 0; sch->flags &= ~TCQ_F_THROTTLED; - del_timer_sync(&q->timer); + hrtimer_cancel(&q->timer); } /* Pass size change message down to embedded FIFO */ @@ -502,7 +502,8 @@ static int tfifo_enqueue(struct sk_buff const struct netem_skb_cb *cb = (const struct netem_skb_cb *)skb->cb; - if (!PSCHED_TLESS(ncb->time_to_send, cb->time_to_send)) + if (ktime_to_ns(ktime_sub(ncb->due_time, + cb->due_time)) >= 0) break; } @@ -567,9 +568,8 @@ static int netem_init(struct Qdisc *sch, if (!opt) return -EINVAL; - init_timer(&q->timer); + hrtimer_init(&q->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); q->timer.function = netem_watchdog; - q->timer.data = (unsigned long) sch; q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops, TC_H_MAKE(sch->handle, 1)); @@ -590,7 +590,7 @@ static void netem_destroy(struct Qdisc * { struct netem_sched_data *q = qdisc_priv(sch); - del_timer_sync(&q->timer); + hrtimer_cancel(&q->timer); qdisc_destroy(q->qdisc); kfree(q->delay_dist); } @@ -605,8 +605,8 @@ static int netem_dump(struct Qdisc *sch, struct tc_netem_reorder reorder; struct tc_netem_corrupt corrupt; - qopt.latency = q->latency; - qopt.jitter = q->jitter; + qopt.latency = psched_usecs2ticks(q->latency); + qopt.jitter = psched_usecs2ticks(q->jitter); qopt.limit = q->limit; qopt.loss = q->loss; qopt.gap = q->gap; --- netem-dev.orig/include/net/pkt_sched.h +++ netem-dev/include/net/pkt_sched.h @@ -239,4 +239,7 @@ static inline unsigned psched_mtu(struct return dev->hard_header ? mtu + dev->hard_header_len : mtu; } +extern unsigned long psched_usecs2ticks(unsigned long us); +extern unsigned long psched_ticks2usecs(unsigned long ticks); + #endif --- netem-dev.orig/net/sched/sch_api.c +++ netem-dev/net/sched/sch_api.c @@ -1178,6 +1178,36 @@ reclassify: static int psched_us_per_tick = 1; static int psched_tick_per_us = 1; + +/** + * psched_ticks2usecs - convert from scaled PSCHED ticks to usecs + * @ticks: pscehed ticks + * Returns time in microseconds + */ +unsigned long psched_ticks2usecs(unsigned long ticks) +{ + u64 t = ticks; + + t *= psched_us_per_tick; + do_div(t, psched_tick_per_us); + return t; +} +EXPORT_SYMBOL(psched_ticks2usecs); + +/** + * psched_usecs2ticks - convert from usecs to PSCHED ticks + * @us: time in microseconds + */ +unsigned long psched_usecs2ticks(unsigned long us) +{ + u64 t = us; + + t *= psched_tick_per_us; + do_div(t, psched_us_per_tick); + return t; +} +EXPORT_SYMBOL(psched_usecs2ticks); + #ifdef CONFIG_PROC_FS static int psched_show(struct seq_file *seq, void *v) { - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists