On Mon, Aug 18, 2008 at 09:07:01PM -0700, David Miller wrote:
...
quoted text > pkt_sched: Don't hold qdisc lock over qdisc_destroy().
>
> Based upon reports by Denys Fedoryshchenko, and feedback
> and help from Jarek Poplawski and Herbert Xu.
>
> We always either:
>
> 1) Never made an external reference to this qdisc.
>
> or
>
> 2) Did a dev_deactivate() which purged all asynchronous
> references.
3) Read below, please...
>
quoted text > So do not lock the qdisc when we call qdisc_destroy(),
> it's illegal anyways as when we drop the lock this is
> free'd memory.
>
> Signed-off-by: David S. Miller
> ---
> net/sched/sch_api.c | 13 ++-----------
> net/sched/sch_generic.c | 6 ------
> 2 files changed, 2 insertions(+), 17 deletions(-)
>
> diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> index 7d7070b..d91a233 100644
> --- a/net/sched/sch_api.c
> +++ b/net/sched/sch_api.c
> @@ -638,11 +638,8 @@ static void notify_and_destroy(struct sk_buff *skb, struct nlmsghdr *n, u32 clid
> if (new || old)
> qdisc_notify(skb, n, clid, old, new);
>
> - if (old) {
> - sch_tree_lock(old);
> + if (old)
> qdisc_destroy(old);
> - sch_tree_unlock(old);
> - }
> }
Actually, I, and earlier Herbert, have written about destroying root
qdiscs without sch_tree_lock(). I don't know how Herbert, but I'd
prefer to leave here this lock for child qdiscs: they can remove some
common structures, so this needs more checking, and even if they don't
do this currently, there is no need to remove this possibility here.
Similarly, I'm not sure if removing BH protection is really needed
here.
And, btw., this is neither 1) nor 2) case according to the changelog,
I guess.
>
quoted text > /* Graft qdisc "new" to class "classid" of qdisc "parent" or
> @@ -1092,16 +1089,10 @@ create_n_graft:
>
> graft:
> if (1) {
> - spinlock_t *root_lock;
> -
> err = qdisc_graft(dev, p, skb, n, clid, q, NULL);
> if (err) {
> - if (q) {
> - root_lock = qdisc_root_lock(q);
> - spin_lock_bh(root_lock);
> + if (q)
> qdisc_destroy(q);
> - spin_unlock_bh(root_lock);
> - }
Probably, as above.
> return err;
quoted text > }
> }
> diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
> index 6f96b7b..c3ed4d4 100644
> --- a/net/sched/sch_generic.c
> +++ b/net/sched/sch_generic.c
> @@ -518,8 +518,6 @@ void qdisc_reset(struct Qdisc *qdisc)
> }
> EXPORT_SYMBOL(qdisc_reset);
>
> -/* Under qdisc_lock(qdisc) and BH! */
> -
??
+ /* Under BH for all, and qdisc_lock(qdisc) for child qdiscs only */
Jarek P.
> void qdisc_destroy(struct Qdisc *qdisc)
quoted text > {
> const struct Qdisc_ops *ops = qdisc->ops;
> @@ -712,14 +710,10 @@ static void shutdown_scheduler_queue(struct net_device *dev,
> struct Qdisc *qdisc_default = _qdisc_default;
>
> if (qdisc) {
> - spinlock_t *root_lock = qdisc_lock(qdisc);
> -
> dev_queue->qdisc = qdisc_default;
> dev_queue->qdisc_sleeping = qdisc_default;
>
> - spin_lock_bh(root_lock);
> qdisc_destroy(qdisc);
> - spin_unlock_bh(root_lock);
> }
> }
>
> --
> 1.5.6.5.GIT
>
--
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