projects
/
linux-block.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
[SK_BUFF]: Convert skb->tail to sk_buff_data_t
[linux-block.git]
/
net
/
sched
/
sch_netem.c
diff --git
a/net/sched/sch_netem.c
b/net/sched/sch_netem.c
index ef8874babf6ae8c7c23ae26fe1baaea03334dd2f..2a9b1e429ff8567a1e64b57d1f6be95cb862aadc 100644
(file)
--- a/
net/sched/sch_netem.c
+++ b/
net/sched/sch_netem.c
@@
-4,10
+4,10
@@
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
- * 2 of the License
, or (at your option) any later version
.
+ * 2 of the License.
*
* Many of the algorithms and ideas for this came from
*
* Many of the algorithms and ideas for this came from
- * NIST Net which is not copyrighted.
+ * NIST Net which is not copyrighted.
*
* Authors: Stephen Hemminger <shemminger@osdl.org>
* Catalin(ux aka Dino) BOIE <catab at umbrella dot ro>
*
* Authors: Stephen Hemminger <shemminger@osdl.org>
* Catalin(ux aka Dino) BOIE <catab at umbrella dot ro>
@@
-54,7
+54,7
@@
struct netem_sched_data {
struct Qdisc *qdisc;
struct netem_sched_data {
struct Qdisc *qdisc;
- struct
timer_list timer
;
+ struct
qdisc_watchdog watchdog
;
u32 latency;
u32 loss;
u32 latency;
u32 loss;
@@
-114,7
+114,7
@@
static unsigned long get_crandom(struct crndstate *state)
* std deviation sigma. Uses table lookup to approximate the desired
* distribution, and a uniformly-distributed pseudo-random source.
*/
* std deviation sigma. Uses table lookup to approximate the desired
* distribution, and a uniformly-distributed pseudo-random source.
*/
-static long tabledist(unsigned long mu, long sigma,
+static long tabledist(unsigned long mu, long sigma,
struct crndstate *state, const struct disttable *dist)
{
long t, x;
struct crndstate *state, const struct disttable *dist)
{
long t, x;
@@
-126,7
+126,7
@@
static long tabledist(unsigned long mu, long sigma,
rnd = get_crandom(state);
/* default uniform distribution */
rnd = get_crandom(state);
/* default uniform distribution */
- if (dist == NULL)
+ if (dist == NULL)
return (rnd % (2*sigma)) - sigma + mu;
t = dist->table[rnd % dist->size];
return (rnd % (2*sigma)) - sigma + mu;
t = dist->table[rnd % dist->size];
@@
-218,7
+218,7
@@
static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
++q->counter;
ret = q->qdisc->enqueue(skb, q->qdisc);
} else {
++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.
*/
* Do re-ordering by putting one out of N packets at the front
* of the queue.
*/
@@
-284,49
+284,33
@@
static struct sk_buff *netem_dequeue(struct Qdisc *sch)
sch->flags &= ~TCQ_F_THROTTLED;
return skb;
} else {
sch->flags &= ~TCQ_F_THROTTLED;
return skb;
} else {
-
psched_tdiff_t delay = PSCHED_TDIFF(cb->time_to_send, now
);
+
qdisc_watchdog_schedule(&q->watchdog, cb->time_to_send
);
if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
+ qdisc_tree_decrease_qlen(q->qdisc, 1);
sch->qstats.drops++;
sch->qstats.drops++;
-
- /* After this qlen is confused */
printk(KERN_ERR "netem: queue discpline %s could not requeue\n",
q->qdisc->ops->id);
printk(KERN_ERR "netem: queue discpline %s could not requeue\n",
q->qdisc->ops->id);
-
- sch->q.qlen--;
}
}
-
- mod_timer(&q->timer, jiffies + PSCHED_US2JIFFIE(delay));
- sch->flags |= TCQ_F_THROTTLED;
}
}
return NULL;
}
}
}
return NULL;
}
-static void netem_watchdog(unsigned long arg)
-{
- struct Qdisc *sch = (struct Qdisc *)arg;
-
- pr_debug("netem_watchdog qlen=%d\n", sch->q.qlen);
- sch->flags &= ~TCQ_F_THROTTLED;
- netif_schedule(sch->dev);
-}
-
static void netem_reset(struct Qdisc *sch)
{
struct netem_sched_data *q = qdisc_priv(sch);
qdisc_reset(q->qdisc);
sch->q.qlen = 0;
static void netem_reset(struct Qdisc *sch)
{
struct netem_sched_data *q = qdisc_priv(sch);
qdisc_reset(q->qdisc);
sch->q.qlen = 0;
- sch->flags &= ~TCQ_F_THROTTLED;
- del_timer_sync(&q->timer);
+ qdisc_watchdog_cancel(&q->watchdog);
}
/* Pass size change message down to embedded FIFO */
static int set_fifo_limit(struct Qdisc *q, int limit)
{
}
/* Pass size change message down to embedded FIFO */
static int set_fifo_limit(struct Qdisc *q, int limit)
{
-
struct rtattr *rta;
+ struct rtattr *rta;
int ret = -ENOMEM;
/* Hack to avoid sending change message to non-FIFO */
int ret = -ENOMEM;
/* Hack to avoid sending change message to non-FIFO */
@@
-336,9
+320,9
@@
static int set_fifo_limit(struct Qdisc *q, int limit)
rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
if (rta) {
rta->rta_type = RTM_NEWQDISC;
rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
if (rta) {
rta->rta_type = RTM_NEWQDISC;
- rta->rta_len = RTA_LENGTH(sizeof(struct tc_fifo_qopt));
+ rta->rta_len = RTA_LENGTH(sizeof(struct tc_fifo_qopt));
((struct tc_fifo_qopt *)RTA_DATA(rta))->limit = limit;
((struct tc_fifo_qopt *)RTA_DATA(rta))->limit = limit;
-
+
ret = q->ops->change(q, rta);
kfree(rta);
}
ret = q->ops->change(q, rta);
kfree(rta);
}
@@
-367,7
+351,7
@@
static int get_dist_table(struct Qdisc *sch, const struct rtattr *attr)
d->size = n;
for (i = 0; i < n; i++)
d->table[i] = data[i];
d->size = n;
for (i = 0; i < n; i++)
d->table[i] = data[i];
-
+
spin_lock_bh(&sch->dev->queue_lock);
d = xchg(&q->delay_dist, d);
spin_unlock_bh(&sch->dev->queue_lock);
spin_lock_bh(&sch->dev->queue_lock);
d = xchg(&q->delay_dist, d);
spin_unlock_bh(&sch->dev->queue_lock);
@@
-422,7
+406,7
@@
static int netem_change(struct Qdisc *sch, struct rtattr *opt)
struct netem_sched_data *q = qdisc_priv(sch);
struct tc_netem_qopt *qopt;
int ret;
struct netem_sched_data *q = qdisc_priv(sch);
struct tc_netem_qopt *qopt;
int ret;
-
+
if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt))
return -EINVAL;
if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt))
return -EINVAL;
@@
-432,7
+416,7
@@
static int netem_change(struct Qdisc *sch, struct rtattr *opt)
pr_debug("netem: can't set fifo limit\n");
return ret;
}
pr_debug("netem: can't set fifo limit\n");
return ret;
}
-
+
q->latency = qopt->latency;
q->jitter = qopt->jitter;
q->limit = qopt->limit;
q->latency = qopt->latency;
q->jitter = qopt->jitter;
q->limit = qopt->limit;
@@
-448,10
+432,10
@@
static int netem_change(struct Qdisc *sch, struct rtattr *opt)
/* Handle nested options after initial queue options.
* Should have put all options in nested format but too late now.
/* Handle nested options after initial queue options.
* Should have put all options in nested format but too late now.
- */
+ */
if (RTA_PAYLOAD(opt) > sizeof(*qopt)) {
struct rtattr *tb[TCA_NETEM_MAX];
if (RTA_PAYLOAD(opt) > sizeof(*qopt)) {
struct rtattr *tb[TCA_NETEM_MAX];
- if (rtattr_parse(tb, TCA_NETEM_MAX,
+ if (rtattr_parse(tb, TCA_NETEM_MAX,
RTA_DATA(opt) + sizeof(*qopt),
RTA_PAYLOAD(opt) - sizeof(*qopt)))
return -EINVAL;
RTA_DATA(opt) + sizeof(*qopt),
RTA_PAYLOAD(opt) - sizeof(*qopt)))
return -EINVAL;
@@
-570,11
+554,10
@@
static int netem_init(struct Qdisc *sch, struct rtattr *opt)
if (!opt)
return -EINVAL;
if (!opt)
return -EINVAL;
- init_timer(&q->timer);
- q->timer.function = netem_watchdog;
- q->timer.data = (unsigned long) sch;
+ qdisc_watchdog_init(&q->watchdog, sch);
- q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops);
+ q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops,
+ TC_H_MAKE(sch->handle, 1));
if (!q->qdisc) {
pr_debug("netem: qdisc create failed\n");
return -ENOMEM;
if (!q->qdisc) {
pr_debug("netem: qdisc create failed\n");
return -ENOMEM;
@@
-592,7
+575,7
@@
static void netem_destroy(struct Qdisc *sch)
{
struct netem_sched_data *q = qdisc_priv(sch);
{
struct netem_sched_data *q = qdisc_priv(sch);
-
del_timer_sync(&q->timer
);
+
qdisc_watchdog_cancel(&q->watchdog
);
qdisc_destroy(q->qdisc);
kfree(q->delay_dist);
}
qdisc_destroy(q->qdisc);
kfree(q->delay_dist);
}
@@
-600,7
+583,7
@@
static void netem_destroy(struct Qdisc *sch)
static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
{
const struct netem_sched_data *q = qdisc_priv(sch);
static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
{
const struct netem_sched_data *q = qdisc_priv(sch);
- unsigned char
*b = skb->tail
;
+ unsigned char
*b = skb_tail_pointer(skb)
;
struct rtattr *rta = (struct rtattr *) b;
struct tc_netem_qopt qopt;
struct tc_netem_corr cor;
struct rtattr *rta = (struct rtattr *) b;
struct tc_netem_qopt qopt;
struct tc_netem_corr cor;
@@
-628,7
+611,7
@@
static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
corrupt.correlation = q->corrupt_cor.rho;
RTA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
corrupt.correlation = q->corrupt_cor.rho;
RTA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
- rta->rta_len = skb
->tail
- b;
+ rta->rta_len = skb
_tail_pointer(skb)
- b;
return skb->len;
return skb->len;
@@
-661,8
+644,8
@@
static int netem_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
sch_tree_lock(sch);
*old = xchg(&q->qdisc, new);
sch_tree_lock(sch);
*old = xchg(&q->qdisc, new);
+ qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
qdisc_reset(*old);
qdisc_reset(*old);
- sch->q.qlen = 0;
sch_tree_unlock(sch);
return 0;
sch_tree_unlock(sch);
return 0;
@@
-683,7
+666,7
@@
static void netem_put(struct Qdisc *sch, unsigned long arg)
{
}
{
}
-static int netem_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+static int netem_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
struct rtattr **tca, unsigned long *arg)
{
return -ENOSYS;
struct rtattr **tca, unsigned long *arg)
{
return -ENOSYS;