Patrick McHardy wrote: > David S. Miller wrote: > >> How do these child qdiscs get destroyed at all if you just >> remove them from the lists they are on? How will the rest >> of destroy processing find them and clean them up? >> >> > > The RCU-callback calls ops->destroy. The qdisc knows about it's inner > structure and destroys all classes and the inner qdiscs. dev->qdisc_list > is just a flat list containing all qdiscs of the tree for lookups. This is the final patch: # [PKT_SCHED]: Unlink inner qdiscs immediately in qdisc_destroy # # Before the RCU change distruction of the qdisc and all inner # qdiscs happend immediately and under the rtnl semaphore. This # made sure nothing holding the rtnl semaphore could end up with # invalid memory. This is not true anymore, inner qdiscs found on # dev->qdisc_list can be suddenly destroyed by the RCU callback. # Unlink them immediately when the outer qdisc is destroyed so # nothing can find them until they get destroyed. This also makes semantics sane again, an inner qdiscs should not be user-visible once the containing qdisc has been destroyed. The second part (locking in qdisc_lookup) is not really required, but currently the only purpose of qdisc_tree_lock seems to be to protect dev->qdisc_list, which is also protected by the rtnl. The rtnl is especially relied on for making sure nobody frees a qdisc while it is used in user-context, so qdisc_tree_lock looks unnecessary. I'm currently reviewing all qdisc locking, if this turns out to be right I will remove qdisc_tree_lock entirely in a follow-up patch, but for now I left it in for consistency. Regards Patrick