Re: [PATCH nf] netfilter: arptables: use percpu jumpstack

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2015-07-02 at 13:48 +0200, Florian Westphal wrote:

> My plan:
> 
> - move tee_active percpu varible to xtables core (suggested by Eric)
> - in do_table, check if we're TEE'd or not
> 
> 1. if no, then just use the jumpstack from offset 0 onwards.
> 2. If yes, then fetch jumpstack, and use the upper half:
> 
> if (__this_cpu_read(xt_tee_active))
>  	jumpstack += private->stacksize;

Or maybe not using a conditional

jumpstack += private->stacksize * __this_cpu_read(xt_tee_active);


BTW, I do not remember why I used a conditional in
xt_write_recseq_begin(). This also adds extra setup cost, as @addend has
to be preserved in the stack.

Hmm... What about something like :

diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 286098a5667f..bee1484c18d2 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -287,44 +287,28 @@ DECLARE_PER_CPU(seqcount_t, xt_recseq);
  * Begin packet processing : all readers must wait the end
  * 1) Must be called with preemption disabled
  * 2) softirqs must be disabled too (or we should use this_cpu_add())
- * Returns :
- *  1 if no recursion on this cpu
- *  0 if recursion detected
  */
-static inline unsigned int xt_write_recseq_begin(void)
+static inline void xt_write_recseq_begin(void)
 {
-	unsigned int addend;
-
-	/*
-	 * Low order bit of sequence is set if we already
-	 * called xt_write_recseq_begin().
-	 */
-	addend = (__this_cpu_read(xt_recseq.sequence) + 1) & 1;
-
-	/*
-	 * This is kind of a write_seqcount_begin(), but addend is 0 or 1
-	 * We dont check addend value to avoid a test and conditional jump,
-	 * since addend is most likely 1
+	/* This is kind of a write_seqcount_begin(),
+	 * but can be nested (no lockdep support)
 	 */
-	__this_cpu_add(xt_recseq.sequence, addend);
+	__this_cpu_inc(xt_recseq.sequence);
 	smp_wmb();
-
-	return addend;
 }
 
 /**
  * xt_write_recseq_end - end of a write section
- * @addend: return value from previous xt_write_recseq_begin()
  *
  * End packet processing : all readers can proceed
  * 1) Must be called with preemption disabled
  * 2) softirqs must be disabled too (or we should use this_cpu_add())
  */
-static inline void xt_write_recseq_end(unsigned int addend)
+static inline void xt_write_recseq_end(void)
 {
-	/* this is kind of a write_seqcount_end(), but addend is 0 or 1 */
+	/* this is kind of a write_seqcount_end() */
 	smp_wmb();
-	__this_cpu_add(xt_recseq.sequence, addend);
+	__this_cpu_inc(xt_recseq.sequence);
 }
 
 /*
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 95c9b6eece25..b34ac984bd7f 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -259,7 +259,6 @@ unsigned int arpt_do_table(struct sk_buff *skb,
 	const void *table_base;
 	const struct xt_table_info *private;
 	struct xt_action_param acpar;
-	unsigned int addend;
 
 	if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
 		return NF_DROP;
@@ -268,7 +267,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
 	outdev = state->out ? state->out->name : nulldevname;
 
 	local_bh_disable();
-	addend = xt_write_recseq_begin();
+	xt_write_recseq_begin();
 	private = table->private;
 	/*
 	 * Ensure we load private-> members after we've fetched the base
@@ -346,7 +345,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
 			/* Verdict */
 			break;
 	} while (!acpar.hotdrop);
-	xt_write_recseq_end(addend);
+	xt_write_recseq_end();
 	local_bh_enable();
 
 	if (acpar.hotdrop)
@@ -1130,7 +1129,6 @@ static int do_add_counters(struct net *net, const void __user *user,
 	const struct xt_table_info *private;
 	int ret = 0;
 	struct arpt_entry *iter;
-	unsigned int addend;
 #ifdef CONFIG_COMPAT
 	struct compat_xt_counters_info compat_tmp;
 
@@ -1185,7 +1183,7 @@ static int do_add_counters(struct net *net, const void __user *user,
 
 	i = 0;
 
-	addend = xt_write_recseq_begin();
+	xt_write_recseq_begin();
 	xt_entry_foreach(iter,  private->entries, private->size) {
 		struct xt_counters *tmp;
 
@@ -1193,7 +1191,7 @@ static int do_add_counters(struct net *net, const void __user *user,
 		ADD_COUNTER(*tmp, paddc[i].bcnt, paddc[i].pcnt);
 		++i;
 	}
-	xt_write_recseq_end(addend);
+	xt_write_recseq_end();
  unlock_up_free:
 	local_bh_enable();
 	xt_table_unlock(t);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 6c72fbb7b49e..4c575fb623aa 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -299,7 +299,6 @@ ipt_do_table(struct sk_buff *skb,
 	unsigned int *stackptr, origptr, cpu;
 	const struct xt_table_info *private;
 	struct xt_action_param acpar;
-	unsigned int addend;
 
 	/* Initialization */
 	ip = ip_hdr(skb);
@@ -321,7 +320,7 @@ ipt_do_table(struct sk_buff *skb,
 
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
 	local_bh_disable();
-	addend = xt_write_recseq_begin();
+	xt_write_recseq_begin();
 	private = table->private;
 	cpu        = smp_processor_id();
 	/*
@@ -426,7 +425,7 @@ ipt_do_table(struct sk_buff *skb,
 	pr_debug("Exiting %s; resetting sp from %u to %u\n",
 		 __func__, *stackptr, origptr);
 	*stackptr = origptr;
- 	xt_write_recseq_end(addend);
+ 	xt_write_recseq_end();
  	local_bh_enable();
 
 #ifdef DEBUG_ALLOW_ALL
@@ -1312,7 +1311,6 @@ do_add_counters(struct net *net, const void __user *user,
 	const struct xt_table_info *private;
 	int ret = 0;
 	struct ipt_entry *iter;
-	unsigned int addend;
 #ifdef CONFIG_COMPAT
 	struct compat_xt_counters_info compat_tmp;
 
@@ -1366,7 +1364,7 @@ do_add_counters(struct net *net, const void __user *user,
 	}
 
 	i = 0;
-	addend = xt_write_recseq_begin();
+	xt_write_recseq_begin();
 	xt_entry_foreach(iter, private->entries, private->size) {
 		struct xt_counters *tmp;
 
@@ -1374,7 +1372,7 @@ do_add_counters(struct net *net, const void __user *user,
 		ADD_COUNTER(*tmp, paddc[i].bcnt, paddc[i].pcnt);
 		++i;
 	}
-	xt_write_recseq_end(addend);
+	xt_write_recseq_end();
  unlock_up_free:
 	local_bh_enable();
 	xt_table_unlock(t);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 3c35ced39b42..d0f66a11ed90 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -327,7 +327,6 @@ ip6t_do_table(struct sk_buff *skb,
 	unsigned int *stackptr, origptr, cpu;
 	const struct xt_table_info *private;
 	struct xt_action_param acpar;
-	unsigned int addend;
 
 	/* Initialization */
 	indev = state->in ? state->in->name : nulldevname;
@@ -347,7 +346,7 @@ ip6t_do_table(struct sk_buff *skb,
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
 
 	local_bh_disable();
-	addend = xt_write_recseq_begin();
+	xt_write_recseq_begin();
 	private = table->private;
 	/*
 	 * Ensure we load private-> members after we've fetched the base
@@ -439,7 +438,7 @@ ip6t_do_table(struct sk_buff *skb,
 
 	*stackptr = origptr;
 
- 	xt_write_recseq_end(addend);
+ 	xt_write_recseq_end();
  	local_bh_enable();
 
 #ifdef DEBUG_ALLOW_ALL
@@ -1325,7 +1324,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
 	const struct xt_table_info *private;
 	int ret = 0;
 	struct ip6t_entry *iter;
-	unsigned int addend;
+
 #ifdef CONFIG_COMPAT
 	struct compat_xt_counters_info compat_tmp;
 
@@ -1379,7 +1378,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
 	}
 
 	i = 0;
-	addend = xt_write_recseq_begin();
+	xt_write_recseq_begin();
 	xt_entry_foreach(iter, private->entries, private->size) {
 		struct xt_counters *tmp;
 
@@ -1387,7 +1386,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
 		ADD_COUNTER(*tmp, paddc[i].bcnt, paddc[i].pcnt);
 		++i;
 	}
-	xt_write_recseq_end(addend);
+	xt_write_recseq_end();
  unlock_up_free:
 	local_bh_enable();
 	xt_table_unlock(t);





--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux