#include <linux/etherdevice.h>
#include <linux/notifier.h>
#include <net/ip.h>
+#include <net/netlink.h>
#include <net/route.h>
#include <linux/skbuff.h>
#include <net/sock.h>
psched_time_t now;
psched_tdiff_t incr;
- PSCHED_GET_TIME(now);
- incr = PSCHED_TDIFF(now, q->now_rt);
- PSCHED_TADD2(q->now, incr, now);
+ now = psched_get_time();
+ incr = now - q->now_rt;
+ now = q->now + incr;
do {
- if (PSCHED_TLESS(cl->undertime, now)) {
+ if (cl->undertime < now) {
q->toplevel = cl->level;
return;
}
static void cbq_ovl_classic(struct cbq_class *cl)
{
struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
- psched_tdiff_t delay = PSCHED_TDIFF(cl->undertime, q->now);
+ psched_tdiff_t delay = cl->undertime - q->now;
if (!cl->delayed) {
delay += cl->offtime;
cl->avgidle = cl->minidle;
if (delay <= 0)
delay = 1;
- PSCHED_TADD2(q->now, delay, cl->undertime);
+ cl->undertime = q->now + delay;
cl->xstats.overactions++;
cl->delayed = 1;
psched_tdiff_t base_delay = q->wd_expires;
for (b = cl->borrow; b; b = b->borrow) {
- delay = PSCHED_TDIFF(b->undertime, q->now);
+ delay = b->undertime - q->now;
if (delay < base_delay) {
if (delay <= 0)
delay = 1;
static void cbq_ovl_delay(struct cbq_class *cl)
{
struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
- psched_tdiff_t delay = PSCHED_TDIFF(cl->undertime, q->now);
+ psched_tdiff_t delay = cl->undertime - q->now;
if (!cl->delayed) {
psched_time_t sched = q->now;
delay -= (-cl->avgidle) - ((-cl->avgidle) >> cl->ewma_log);
if (cl->avgidle < cl->minidle)
cl->avgidle = cl->minidle;
- PSCHED_TADD2(q->now, delay, cl->undertime);
+ cl->undertime = q->now + delay;
if (delay > 0) {
sched += delay + cl->penalty;
psched_tdiff_t delay = 0;
unsigned pmask;
- PSCHED_GET_TIME(now);
+ now = psched_get_time();
pmask = q->pmask;
q->pmask = 0;
if (cl && q->toplevel >= borrowed->level) {
if (cl->q->q.qlen > 1) {
do {
- if (PSCHED_IS_PASTPERFECT(borrowed->undertime)) {
+ if (borrowed->undertime == PSCHED_PASTPERFECT) {
q->toplevel = borrowed->level;
return;
}
idle = (now - last) - last_pktlen/rate
*/
- idle = PSCHED_TDIFF(q->now, cl->last);
+ idle = q->now - cl->last;
if ((unsigned long)idle > 128*1024*1024) {
avgidle = cl->maxidle;
} else {
idle -= L2T(&q->link, len);
idle += L2T(cl, len);
- PSCHED_AUDIT_TDIFF(idle);
-
- PSCHED_TADD2(q->now, idle, cl->undertime);
+ cl->undertime = q->now + idle;
} else {
/* Underlimit */
- PSCHED_SET_PASTPERFECT(cl->undertime);
+ cl->undertime = PSCHED_PASTPERFECT;
if (avgidle > cl->maxidle)
cl->avgidle = cl->maxidle;
else
if (cl->tparent == NULL)
return cl;
- if (PSCHED_IS_PASTPERFECT(cl->undertime) ||
- !PSCHED_TLESS(q->now, cl->undertime)) {
+ if (cl->undertime == PSCHED_PASTPERFECT || q->now >= cl->undertime) {
cl->delayed = 0;
return cl;
}
}
if (cl->level > q->toplevel)
return NULL;
- } while (!PSCHED_IS_PASTPERFECT(cl->undertime) &&
- PSCHED_TLESS(q->now, cl->undertime));
+ } while (cl->undertime != PSCHED_PASTPERFECT && q->now < cl->undertime);
cl->delayed = 0;
return cl;
psched_time_t now;
psched_tdiff_t incr;
- PSCHED_GET_TIME(now);
- incr = PSCHED_TDIFF(now, q->now_rt);
+ now = psched_get_time();
+ incr = now - q->now_rt;
if (q->tx_class) {
psched_tdiff_t incr2;
cbq_time = max(real_time, work);
*/
incr2 = L2T(&q->link, q->tx_len);
- PSCHED_TADD(q->now, incr2);
+ q->now += incr2;
cbq_update(q);
if ((incr -= incr2) < 0)
incr = 0;
}
- PSCHED_TADD(q->now, incr);
+ q->now += incr;
q->now_rt = now;
for (;;) {
*/
if (q->toplevel == TC_CBQ_MAXLEVEL &&
- PSCHED_IS_PASTPERFECT(q->link.undertime))
+ q->link.undertime == PSCHED_PASTPERFECT)
break;
q->toplevel = TC_CBQ_MAXLEVEL;
- PSCHED_SET_PASTPERFECT(q->link.undertime);
+ q->link.undertime = PSCHED_PASTPERFECT;
}
/* No packets in scheduler or nobody wants to give them to us :-(
sch->qstats.overlimits++;
if (q->wd_expires)
qdisc_watchdog_schedule(&q->watchdog,
- q->now + q->wd_expires);
+ now + q->wd_expires);
}
return NULL;
}
qdisc_watchdog_cancel(&q->watchdog);
hrtimer_cancel(&q->delay_timer);
q->toplevel = TC_CBQ_MAXLEVEL;
- PSCHED_GET_TIME(q->now);
+ q->now = psched_get_time();
q->now_rt = q->now;
for (prio = 0; prio <= TC_CBQ_MAXPRIO; prio++)
qdisc_reset(cl->q);
cl->next_alive = NULL;
- PSCHED_SET_PASTPERFECT(cl->undertime);
+ cl->undertime = PSCHED_PASTPERFECT;
cl->avgidle = cl->maxidle;
cl->deficit = cl->quantum;
cl->cpriority = cl->priority;
hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
q->delay_timer.function = cbq_undelay;
q->toplevel = TC_CBQ_MAXLEVEL;
- PSCHED_GET_TIME(q->now);
+ q->now = psched_get_time();
q->now_rt = q->now;
cbq_link_class(&q->link);
static __inline__ int cbq_dump_rate(struct sk_buff *skb, struct cbq_class *cl)
{
- unsigned char *b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
RTA_PUT(skb, TCA_CBQ_RATE, sizeof(cl->R_tab->rate), &cl->R_tab->rate);
return skb->len;
rtattr_failure:
- skb_trim(skb, b - skb->data);
+ nlmsg_trim(skb, b);
return -1;
}
static __inline__ int cbq_dump_lss(struct sk_buff *skb, struct cbq_class *cl)
{
- unsigned char *b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
struct tc_cbq_lssopt opt;
opt.flags = 0;
return skb->len;
rtattr_failure:
- skb_trim(skb, b - skb->data);
+ nlmsg_trim(skb, b);
return -1;
}
static __inline__ int cbq_dump_wrr(struct sk_buff *skb, struct cbq_class *cl)
{
- unsigned char *b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
struct tc_cbq_wrropt opt;
opt.flags = 0;
return skb->len;
rtattr_failure:
- skb_trim(skb, b - skb->data);
+ nlmsg_trim(skb, b);
return -1;
}
static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl)
{
- unsigned char *b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
struct tc_cbq_ovl opt;
opt.strategy = cl->ovl_strategy;
return skb->len;
rtattr_failure:
- skb_trim(skb, b - skb->data);
+ nlmsg_trim(skb, b);
return -1;
}
static __inline__ int cbq_dump_fopt(struct sk_buff *skb, struct cbq_class *cl)
{
- unsigned char *b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
struct tc_cbq_fopt opt;
if (cl->split || cl->defmap) {
return skb->len;
rtattr_failure:
- skb_trim(skb, b - skb->data);
+ nlmsg_trim(skb, b);
return -1;
}
#ifdef CONFIG_NET_CLS_POLICE
static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl)
{
- unsigned char *b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
struct tc_cbq_police opt;
if (cl->police) {
return skb->len;
rtattr_failure:
- skb_trim(skb, b - skb->data);
+ nlmsg_trim(skb, b);
return -1;
}
#endif
static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb)
{
struct cbq_sched_data *q = qdisc_priv(sch);
- unsigned char *b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
struct rtattr *rta;
rta = (struct rtattr*)b;
RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
if (cbq_dump_attr(skb, &q->link) < 0)
goto rtattr_failure;
- rta->rta_len = skb->tail - b;
+ rta->rta_len = skb_tail_pointer(skb) - b;
return skb->len;
rtattr_failure:
- skb_trim(skb, b - skb->data);
+ nlmsg_trim(skb, b);
return -1;
}
struct sk_buff *skb, struct tcmsg *tcm)
{
struct cbq_class *cl = (struct cbq_class*)arg;
- unsigned char *b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
struct rtattr *rta;
if (cl->tparent)
RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
if (cbq_dump_attr(skb, cl) < 0)
goto rtattr_failure;
- rta->rta_len = skb->tail - b;
+ rta->rta_len = skb_tail_pointer(skb) - b;
return skb->len;
rtattr_failure:
- skb_trim(skb, b - skb->data);
+ nlmsg_trim(skb, b);
return -1;
}
cl->xstats.avgidle = cl->avgidle;
cl->xstats.undertime = 0;
- if (!PSCHED_IS_PASTPERFECT(cl->undertime))
- cl->xstats.undertime = PSCHED_TDIFF(cl->undertime, q->now);
+ if (cl->undertime != PSCHED_PASTPERFECT)
+ cl->xstats.undertime = cl->undertime - q->now;
if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
#ifdef CONFIG_NET_ESTIMATOR
return 0;
}
-static void cbq_destroy_filters(struct cbq_class *cl)
-{
- struct tcf_proto *tp;
-
- while ((tp = cl->filter_list) != NULL) {
- cl->filter_list = tp->next;
- tcf_destroy(tp);
- }
-}
-
static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
{
struct cbq_sched_data *q = qdisc_priv(sch);
BUG_TRAP(!cl->filters);
- cbq_destroy_filters(cl);
+ tcf_destroy_chain(cl->filter_list);
qdisc_destroy(cl->q);
qdisc_put_rtab(cl->R_tab);
#ifdef CONFIG_NET_ESTIMATOR
*/
for (h = 0; h < 16; h++)
for (cl = q->classes[h]; cl; cl = cl->next)
- cbq_destroy_filters(cl);
+ tcf_destroy_chain(cl->filter_list);
for (h = 0; h < 16; h++) {
struct cbq_class *next;