| 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 |
| |