summaryrefslogtreecommitdiffstats
path: root/net-use-a-rcu-callback-for-nf_conntrack_destroy.patch
blob: bbff7e8fdb5cf2f4208da026de339c2972b08e6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
From c561b8da83e811af20cfca26fc8bf3c666c40acb Mon Sep 17 00:00:00 2001
From: Steven Rostedt <srostedt@redhat.com>
Date: Fri, 3 Jul 2009 08:44:35 -0500
Subject: [PATCH] net: use a rcu callback for nf_conntrack_destroy

commit 1eba80024f931c61851363662f9b2922307114ae in tip.

__nf_conntrack_destroy is called with preemption disabled and calls
functions that will schedule in PREEMPT_RT. When PREEMPT_RT is defined
we call an RCU callback to do the destruction at a later time.

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 include/linux/skbuff.h |    3 +++
 net/netfilter/core.c   |   24 +++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 124f90c..8028bb4 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -98,6 +98,9 @@ struct pipe_inode_info;
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 struct nf_conntrack {
 	atomic_t use;
+#ifdef CONFIG_PREEMPT_RT
+	struct rcu_head rcu;
+#endif
 };
 #endif
 
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 78b505d..691aa22 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -234,7 +234,7 @@ EXPORT_SYMBOL(nf_ct_attach);
 void (*nf_ct_destroy)(struct nf_conntrack *);
 EXPORT_SYMBOL(nf_ct_destroy);
 
-void nf_conntrack_destroy(struct nf_conntrack *nfct)
+static void __nf_conntrack_destroy(struct nf_conntrack *nfct)
 {
 	void (*destroy)(struct nf_conntrack *);
 
@@ -244,6 +244,28 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct)
 	destroy(nfct);
 	rcu_read_unlock();
 }
+
+#ifdef CONFIG_PREEMPT_RT
+/*
+ * nf_contrack_destroy is called with preemption disabled
+ * and will call functions that might schedule in PREEMPT_RT.
+ * For PREEMPT_RT we use a rcu callback instead to handle
+ * the destroying.
+ */
+static void nf_conntrack_destroy_rcu(struct rcu_head *rhp)
+{
+	__nf_conntrack_destroy(container_of(rhp, struct nf_conntrack, rcu));
+}
+void nf_conntrack_destroy(struct nf_conntrack *nfct)
+{
+	call_rcu(&nfct->rcu, nf_conntrack_destroy_rcu);
+}
+#else /* !PREEMPT_RT */
+void nf_conntrack_destroy(struct nf_conntrack *nfct)
+{
+	__nf_conntrack_destroy(nfct);
+}
+#endif /* PREEMPT_RT */
 EXPORT_SYMBOL(nf_conntrack_destroy);
 #endif /* CONFIG_NF_CONNTRACK */
 
-- 
1.7.0.4