Some safety improvements to netem to make it safer to change paramters while queue is running. Use sch_tree_lock() to block all packets during change. Signed-off-by: Stephen Hemminger --- a/net/sched/sch_netem.c 2010-08-02 16:22:42.389335747 -0700 +++ b/net/sched/sch_netem.c 2010-08-03 08:25:15.611820853 -0700 @@ -318,7 +318,6 @@ static int get_dist_table(struct Qdisc * struct netem_sched_data *q = qdisc_priv(sch); unsigned long n = nla_len(attr)/sizeof(__s16); const __s16 *data = nla_data(attr); - spinlock_t *root_lock; struct disttable *d; int i; @@ -333,12 +332,9 @@ static int get_dist_table(struct Qdisc * for (i = 0; i < n; i++) d->table[i] = data[i]; - root_lock = qdisc_root_sleeping_lock(sch); - - spin_lock_bh(root_lock); kfree(q->delay_dist); q->delay_dist = d; - spin_unlock_bh(root_lock); + return 0; } @@ -412,6 +408,7 @@ static int netem_change(struct Qdisc *sc return ret; } + sch_tree_lock(sch); q->latency = qopt->latency; q->jitter = qopt->jitter; q->limit = qopt->limit; @@ -432,7 +429,7 @@ static int netem_change(struct Qdisc *sc if (tb[TCA_NETEM_DELAY_DIST]) { ret = get_dist_table(sch, tb[TCA_NETEM_DELAY_DIST]); if (ret) - return ret; + goto out; } if (tb[TCA_NETEM_REORDER]) @@ -440,6 +437,8 @@ static int netem_change(struct Qdisc *sc if (tb[TCA_NETEM_CORRUPT]) get_corrupt(sch, tb[TCA_NETEM_CORRUPT]); + out: + sch_tree_unlock(sch); return 0; } -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html