diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2012-10-28 10:18:08 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2013-04-04 22:09:39 (GMT) |
commit | afe10a673089defcf4d4f77bc691b4a4d3e97031 (patch) | |
tree | 0a00964d1ff1cdc557a70229548034ed822a495f /include | |
parent | 6205c51fcf0bd6cc7957372f997a7cb73011f4a1 (diff) | |
download | linux-fsl-qoriq-afe10a673089defcf4d4f77bc691b4a4d3e97031.tar.xz |
net: netfilter: Serialize xt_write_recseq sections on RT
The netfilter code relies only on the implicit semantics of
local_bh_disable() for serializing wt_write_recseq sections. RT breaks
that and needs explicit serialization here.
Reported-by: Peter LaDow <petela@gocougs.wsu.edu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable-rt@vger.kernel.org
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/locallock.h | 4 | ||||
-rw-r--r-- | include/linux/netfilter/x_tables.h | 7 |
2 files changed, 11 insertions, 0 deletions
diff --git a/include/linux/locallock.h b/include/linux/locallock.h index f1804a3..a5eea5d 100644 --- a/include/linux/locallock.h +++ b/include/linux/locallock.h @@ -25,6 +25,9 @@ struct local_irq_lock { DEFINE_PER_CPU(struct local_irq_lock, lvar) = { \ .lock = __SPIN_LOCK_UNLOCKED((lvar).lock) } +#define DECLARE_LOCAL_IRQ_LOCK(lvar) \ + DECLARE_PER_CPU(struct local_irq_lock, lvar) + #define local_irq_lock_init(lvar) \ do { \ int __cpu; \ @@ -220,6 +223,7 @@ static inline int __local_unlock_irqrestore(struct local_irq_lock *lv, #else /* PREEMPT_RT_BASE */ #define DEFINE_LOCAL_IRQ_LOCK(lvar) __typeof__(const int) lvar +#define DECLARE_LOCAL_IRQ_LOCK(lvar) extern __typeof__(const int) lvar static inline void local_irq_lock_init(int lvar) { } diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index dd49566..7d083af 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -3,6 +3,7 @@ #include <linux/netdevice.h> +#include <linux/locallock.h> #include <uapi/linux/netfilter/x_tables.h> /** @@ -284,6 +285,8 @@ extern void xt_free_table_info(struct xt_table_info *info); */ DECLARE_PER_CPU(seqcount_t, xt_recseq); +DECLARE_LOCAL_IRQ_LOCK(xt_write_lock); + /** * xt_write_recseq_begin - start of a write section * @@ -298,6 +301,9 @@ static inline unsigned int xt_write_recseq_begin(void) { unsigned int addend; + /* RT protection */ + local_lock(xt_write_lock); + /* * Low order bit of sequence is set if we already * called xt_write_recseq_begin(). @@ -328,6 +334,7 @@ static inline void xt_write_recseq_end(unsigned int addend) /* this is kind of a write_seqcount_end(), but addend is 0 or 1 */ smp_wmb(); __this_cpu_add(xt_recseq.sequence, addend); + local_unlock(xt_write_lock); } /* |