From f6e0b239a2657ea8cb67f0d83d0bfdbfd19a481b Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Fri, 22 Aug 2008 03:24:05 -0700 Subject: pkt_sched: Fix qdisc list locking Since some qdiscs call qdisc_tree_decrease_qlen() (so qdisc_lookup()) without rtnl_lock(), adding and deleting from a qdisc list needs additional locking. This patch adds global spinlock qdisc_list_lock and wrapper functions for modifying the list. It is considered as a temporary solution until hfsc_dequeue(), netem_dequeue() and tbf_dequeue() (or qdisc_tree_decrease_qlen()) are redone. With feedback from Herbert Xu and David S. Miller. Signed-off-by: Jarek Poplawski Acked-by: Herbert Xu Signed-off-by: David S. Miller --- include/net/pkt_sched.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 853fe83d9f3..b786a5b0925 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -78,6 +78,7 @@ extern struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops, extern int register_qdisc(struct Qdisc_ops *qops); extern int unregister_qdisc(struct Qdisc_ops *qops); +extern void qdisc_list_del(struct Qdisc *q); extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle); extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle); extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, -- cgit v1.2.3 From f6f9b93f1624206c802ac9162c9302edaf59bfd9 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Wed, 27 Aug 2008 02:25:17 -0700 Subject: pkt_sched: Fix gen_estimator locks While passing a qdisc root lock to gen_new_estimator() and gen_replace_estimator() dev could be deactivated or even before grafting proper root qdisc as qdisc_sleeping (e.g. qdisc_create), so using qdisc_root_lock() is not enough. This patch adds qdisc_root_sleeping_lock() for this, plus additional checks, where necessary. Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller --- include/net/sch_generic.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index b1d2cfea89c..ef8a7e2e12e 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -217,6 +217,14 @@ static inline spinlock_t *qdisc_root_lock(struct Qdisc *qdisc) return qdisc_lock(root); } +static inline spinlock_t *qdisc_root_sleeping_lock(struct Qdisc *qdisc) +{ + struct Qdisc *root = qdisc_root_sleeping(qdisc); + + ASSERT_RTNL(); + return qdisc_lock(root); +} + static inline struct net_device *qdisc_dev(struct Qdisc *qdisc) { return qdisc->dev_queue->dev; -- cgit v1.2.3 From fe439dd09d3e4da6a44d35df7371b9c6a2661b99 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Wed, 27 Aug 2008 02:27:10 -0700 Subject: pkt_sched: Fix sch_tree_lock() Use new qdisc_root_sleeping_lock() instead of qdisc_root_lock() as sch_tree_lock() because this lock could be used while dev is deactivated, but we never need to use this with noop_qdisc as a root. Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller --- include/net/sch_generic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index ef8a7e2e12e..e5569625d2a 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -232,12 +232,12 @@ static inline struct net_device *qdisc_dev(struct Qdisc *qdisc) static inline void sch_tree_lock(struct Qdisc *q) { - spin_lock_bh(qdisc_root_lock(q)); + spin_lock_bh(qdisc_root_sleeping_lock(q)); } static inline void sch_tree_unlock(struct Qdisc *q) { - spin_unlock_bh(qdisc_root_lock(q)); + spin_unlock_bh(qdisc_root_sleeping_lock(q)); } #define tcf_tree_lock(tp) sch_tree_lock((tp)->q) -- cgit v1.2.3 From 7c19a3d280297d43ef5ff7c6b205dc208a16d3d1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 29 Aug 2008 14:37:23 -0700 Subject: net: Unbreak userspace usage of linux/mroute.h Nothing in linux/pim.h should be exported to userspace. This should fix the XORP build failure reported by Jose Calhariz, the debain package maintainer. Nothing originally in linux/mroute.h was exported to userspace ever, but some of this stuff started to be when it was moved into this new linux/pim.h, and that was wrong. If we didn't provide these definitions for 10 years we can reasonably expect that applications defined this stuff locally or used GLIBC headers providing the protocol definitions. And as such the only result of this can be conflict and userland build breakage. Signed-off-by: David S. Miller --- include/linux/Kbuild | 1 - include/linux/mroute.h | 2 +- include/linux/mroute6.h | 1 + include/linux/pim.h | 18 ------------------ 4 files changed, 2 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 7d970678f94..59391250d51 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -297,7 +297,6 @@ unifdef-y += parport.h unifdef-y += patchkey.h unifdef-y += pci.h unifdef-y += personality.h -unifdef-y += pim.h unifdef-y += pktcdvd.h unifdef-y += pmu.h unifdef-y += poll.h diff --git a/include/linux/mroute.h b/include/linux/mroute.h index 07112ee9293..8a455694d68 100644 --- a/include/linux/mroute.h +++ b/include/linux/mroute.h @@ -6,7 +6,6 @@ #ifdef __KERNEL__ #include #endif -#include /* * Based on the MROUTING 3.5 defines primarily to keep @@ -130,6 +129,7 @@ struct igmpmsg */ #ifdef __KERNEL__ +#include #include #ifdef CONFIG_IP_MROUTE diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h index 5cf50473a10..6f4c180179e 100644 --- a/include/linux/mroute6.h +++ b/include/linux/mroute6.h @@ -115,6 +115,7 @@ struct sioc_mif_req6 #ifdef __KERNEL__ +#include #include /* for struct sk_buff_head */ #ifdef CONFIG_IPV6_MROUTE diff --git a/include/linux/pim.h b/include/linux/pim.h index 236ffd31739..1ba0661561a 100644 --- a/include/linux/pim.h +++ b/include/linux/pim.h @@ -3,22 +3,6 @@ #include -#ifndef __KERNEL__ -struct pim { -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 pim_type:4, /* PIM message type */ - pim_ver:4; /* PIM version */ -#elif defined(__BIG_ENDIAN_BITFIELD) - __u8 pim_ver:4; /* PIM version */ - pim_type:4; /* PIM message type */ -#endif - __u8 pim_rsv; /* Reserved */ - __be16 pim_cksum; /* Checksum */ -}; - -#define PIM_MINLEN 8 -#endif - /* Message types - V1 */ #define PIM_V1_VERSION __constant_htonl(0x10000000) #define PIM_V1_REGISTER 1 @@ -27,7 +11,6 @@ struct pim { #define PIM_VERSION 2 #define PIM_REGISTER 1 -#if defined(__KERNEL__) #define PIM_NULL_REGISTER __constant_htonl(0x40000000) /* PIMv2 register message header layout (ietf-draft-idmr-pimvsm-v2-00.ps */ @@ -42,4 +25,3 @@ struct pimreghdr struct sk_buff; extern int pim_rcv_v1(struct sk_buff *); #endif -#endif -- cgit v1.2.3