diff options
author | David S. Miller <davem@davemloft.net> | 2008-08-02 23:27:37 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-08-02 23:27:37 -0700 |
commit | 7e43f1128d4c4bd91786ca6abff45a91e88f9776 (patch) | |
tree | 9bf24079d6a70090d1872b23b95c483237d86b25 | |
parent | 35ed4e75989c4e84a44b25569bbf09b98f923880 (diff) |
pkt_sched: Make sure RTNL is held in qdisc_root_lock().
It is the only legal environment in which this can be
used.
Add some commentary explaining the situation.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/sch_generic.h | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index b5f40d7ef72..c5bb1306505 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -193,10 +193,22 @@ static inline struct Qdisc *qdisc_root(struct Qdisc *qdisc) return qdisc->dev_queue->qdisc; } +/* The qdisc root lock is a mechanism by which to top level + * of a qdisc tree can be locked from any qdisc node in the + * forest. This allows changing the configuration of some + * aspect of the qdisc tree while blocking out asynchronous + * qdisc access in the packet processing paths. + * + * It is only legal to do this when the root will not change + * on us. Otherwise we'll potentially lock the wrong qdisc + * root. This is enforced by holding the RTNL semaphore, which + * all users of this lock accessor must do. + */ static inline spinlock_t *qdisc_root_lock(struct Qdisc *qdisc) { struct Qdisc *root = qdisc_root(qdisc); + ASSERT_RTNL(); return qdisc_lock(root); } |