Netdev List
 help / color / mirror / Atom feed
* [PATCH] seq_file: add RCU versions of new hlist/list iterators
From: Stephen Hemminger @ 2010-02-18 23:30 UTC (permalink / raw)
  To: David S. Miller, Paul E. McKenney; +Cc: netdev, linux-kernel

Many usages of seq_file use RCU protected lists, so non RCU
iterators will not work safely.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 fs/seq_file.c            |   82 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/rculist.h  |    5 ++
 include/linux/seq_file.h |   27 ++++++++++-----
 3 files changed, 105 insertions(+), 9 deletions(-)

--- a/fs/seq_file.c	2010-02-18 15:08:53.228872265 -0800
+++ b/fs/seq_file.c	2010-02-18 15:26:21.157402219 -0800
@@ -695,6 +695,38 @@ struct list_head *seq_list_next(void *v,
 }
 EXPORT_SYMBOL(seq_list_next);
 
+struct list_head *seq_list_start_rcu(struct list_head *head, loff_t pos)
+{
+	struct list_head *lh;
+
+	__list_for_each_rcu(lh, head)
+		if (pos-- == 0)
+			return lh;
+
+	return NULL;
+}
+EXPORT_SYMBOL(seq_list_start_rcu);
+
+struct list_head *seq_list_start_head_rcu(struct list_head *head, loff_t pos)
+{
+	if (!pos)
+		return head;
+
+	return seq_list_start_rcu(head, pos - 1);
+}
+EXPORT_SYMBOL(seq_list_start_head_rcu);
+
+struct list_head *seq_list_next_rcu(void *v, struct list_head *head,
+				    loff_t *ppos)
+{
+	struct list_head *lh = v;
+
+	lh = rcu_dereference(lh->next);
+	++*ppos;
+	return lh == head ? NULL : lh;
+}
+EXPORT_SYMBOL(seq_list_next_rcu);
+
 /**
  * seq_hlist_start - start an iteration of a hlist
  * @head: the head of the hlist
@@ -750,3 +782,53 @@ struct hlist_node *seq_hlist_next(void *
 		return node->next;
 }
 EXPORT_SYMBOL(seq_hlist_next);
+
+/**
+ * seq_hlist_start_rcu - start an iteration of a hlist protected by RCU
+ * @head: the head of the hlist
+ * @pos:  the start position of the sequence
+ *
+ * Called at seq_file->op->start().
+ */
+struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head, loff_t pos)
+{
+	struct hlist_node *node;
+
+	__hlist_for_each_rcu(node, head)
+		if (pos-- == 0)
+			return node;
+	return NULL;
+}
+EXPORT_SYMBOL(seq_hlist_start_rcu);
+
+/**
+ * seq_hlist_start_head_rcu - start an iteration of a hlist protected by RCU
+ * @head: the head of the hlist
+ * @pos:  the start position of the sequence
+ *
+ * Called at seq_file->op->start(). Call this function if you want to
+ * print a header at the top of the output.
+ */
+struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head, loff_t pos)
+{
+	if (!pos)
+		return SEQ_START_TOKEN;
+
+	return seq_hlist_start_rcu(head, pos - 1);
+}
+EXPORT_SYMBOL(seq_hlist_start_rcu);
+
+/**
+ * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU
+ * @v:    the current iterator
+ * @head: the head of the hlist
+ * @pos:  the current posision
+ *
+ * Called at seq_file->op->next().
+ */
+struct hlist_node *seq_hlist_next_rcu(void *v, struct hlist_head *head,
+				      loff_t *ppos)
+{
+	return rcu_dereference(seq_hlist_next(v, head, ppos));
+}
+EXPORT_SYMBOL(seq_hlist_next_rcu);
--- a/include/linux/seq_file.h	2010-02-18 15:08:53.256872028 -0800
+++ b/include/linux/seq_file.h	2010-02-18 15:09:14.128997914 -0800
@@ -127,23 +127,32 @@ int seq_release_private(struct inode *, 
 /*
  * Helpers for iteration over list_head-s in seq_files
  */
-
 extern struct list_head *seq_list_start(struct list_head *head,
-		loff_t pos);
+					loff_t pos);
 extern struct list_head *seq_list_start_head(struct list_head *head,
-		loff_t pos);
+					     loff_t pos);
 extern struct list_head *seq_list_next(void *v, struct list_head *head,
-		loff_t *ppos);
-
+				       loff_t *ppos);
+extern struct list_head *seq_list_start_rcu(struct list_head *head,
+					    loff_t pos);
+extern struct list_head *seq_list_start_head_rcu(struct list_head *head,
+						 loff_t pos);
+extern struct list_head *seq_list_next_rcu(void *v, struct list_head *head,
+					   loff_t *ppos);
 /*
  * Helpers for iteration over hlist_head-s in seq_files
  */
-
 extern struct hlist_node *seq_hlist_start(struct hlist_head *head,
-		loff_t pos);
+					  loff_t pos);
 extern struct hlist_node *seq_hlist_start_head(struct hlist_head *head,
-		loff_t pos);
+					       loff_t pos);
 extern struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
-		loff_t *ppos);
+					 loff_t *ppos);
 
+extern struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head,
+					      loff_t pos);
+extern struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head,
+						   loff_t pos);
+extern struct hlist_node *seq_hlist_next_rcu(void *v, struct hlist_head *head,
+					     loff_t *ppos);
 #endif
--- a/include/linux/rculist.h	2010-02-18 15:25:03.681496691 -0800
+++ b/include/linux/rculist.h	2010-02-18 15:26:13.909286656 -0800
@@ -406,6 +406,11 @@ static inline void hlist_add_after_rcu(s
 		n->next->pprev = &n->next;
 }
 
+#define __hlist_for_each(pos, head)			\
+	for (pos = rcu_dereference((head)->first);	\
+	     pos && ({ prefetch(pos->next); 1; });	\
+	     pos = rcu_derference(pos->next))
+
 /**
  * hlist_for_each_entry_rcu - iterate over rcu list of given type
  * @tpos:	the type * to use as a loop cursor.

^ permalink raw reply

* Re: [net-next PATCH v5 0/3] net: TCP thin-stream latency-improving modifications
From: David Miller @ 2010-02-18 23:43 UTC (permalink / raw)
  To: apetlund
  Cc: netdev, ilpo.jarvinen, eric.dumazet, hannemann, linux-kernel,
	shemminger, william.allen.simpson, damian, ebiederm, franco
In-Reply-To: <4B7D35A5.10106@simula.no>

From: Andreas Petlund <apetlund@simula.no>
Date: Thu, 18 Feb 2010 13:42:13 +0100

> This is a series of patches enabling non-intrusive, dynamically 
> triggered modifications that improve retransmission latencies 
> for thin streams.
> 
> The patch set was modified according to the feedback received.
> 
> Major change:
>       -Used bitfields to compact the nonagle variable
>        in the tcp_sock struct. nonagle, thin_lto and
>        thin_dupack is now contained in the same u8.
> 
> I decided to use bitfields to handle this as it is
> already done similarly in the tcp_options_received struct.
> 
> Also corrected some formatting issues.

All applied (I made sure the get the updated version of patch #3),
thanks a lot!

^ permalink raw reply

* Re: [PATCH V2 net-next 13/15] drivers/net/tg3.c: Use (pr|netdev)_<level> macro helpers
From: David Miller @ 2010-02-18 23:44 UTC (permalink / raw)
  To: joe; +Cc: netdev, mcarlson, mchan, linux-kernel
In-Reply-To: <1266471859.8446.256.camel@Joe-Laptop.home>

From: Joe Perches <joe@perches.com>
Date: Wed, 17 Feb 2010 21:44:19 -0800

> Add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> Remove #define PFX
> Use pr_<level>
> Use netdev_<level>
> Remove periods from most formats
> Coalesce long formats
> Use printk_once
> 
> Signed-off-by: Joe Perches <joe@perches.com>

Applied.

^ permalink raw reply

* Re: [RFC PATCH net-next-2.6]: xfrm: Introduce LINUX_MIB_XFRMFWDHDRERROR
From: David Miller @ 2010-02-18 23:44 UTC (permalink / raw)
  To: hadi; +Cc: nakam, kaber, herbert, netdev
In-Reply-To: <1266500107.17794.167.camel@bigi>

From: jamal <hadi@cyberus.ca>
Date: Thu, 18 Feb 2010 08:35:07 -0500

> On Wed, 2010-02-17 at 13:49 -0800, David Miller wrote:
> 
>> This should be fine, the tools just parse the lines individually
>> as "string integer" pairs.
>> 
>> If you want to be super anal, add the new counter to the end of
>> the array.
> 
> Ok, thanks - here is the updated patch.

Applied, thanks Jamal.

^ permalink raw reply

* Re: [PATCH V2 net-next 09/15] drivers/net/sis190.c: Use (pr|netdev|netif)_<level> macro helpers
From: David Miller @ 2010-02-18 23:44 UTC (permalink / raw)
  To: joe; +Cc: netdev, romieu, linux-kernel
In-Reply-To: <1266472817.8446.258.camel@Joe-Laptop.home>

From: Joe Perches <joe@perches.com>
Date: Wed, 17 Feb 2010 22:00:17 -0800

> Add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> Remove #define PFX
> Use pr_<level>
> Use netdev_<level>
> Use netif_<level> and netif_msg_<test>
> Remove local #define net_<test> macros
> Remove periods from formats
> 
> Signed-off-by: Joe Perches <joe@perches.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-next-2.6] be2net: free tx buffers when completions never arrive
From: David Miller @ 2010-02-18 23:44 UTC (permalink / raw)
  To: sathyap; +Cc: netdev
In-Reply-To: <20100218103717.GA15679@serverengines.com>

From: Sathya Perla <sathyap@serverengines.com>
Date: Thu, 18 Feb 2010 16:07:17 +0530

> 
> On 18/02/10 02:16 -0800, David Miller wrote:
> <snip>
>> > +        bool dummy_wrb;
>> 
>> Some of your lines start with tabs, some with spaces.   You
>> have to use tabs consistently.
>> 
> <snip>
> 
> Sorry, mistake fixed; patch below. Thanks a lot...

Applied.

^ permalink raw reply

* Re: [PATCH] Orphan DECnet
From: David Miller @ 2010-02-18 23:44 UTC (permalink / raw)
  To: christine.caulfield; +Cc: netdev, torvalds, swhiteho, linux-kernel
In-Reply-To: <1266492793.412.1.camel@rhdesktop.chrissie.net>

From: Christine Caulfield <christine.caulfield@googlemail.com>
Date: Thu, 18 Feb 2010 11:33:13 +0000

> Hiya all
> 
> Due to lack of time, space, motivation, hardware and probably expertise,
> I have reluctantly decided to orphan the DECnet code in the kernel.
> 
> Judging by the deafening silence on the linux-decnet mailing list I
> suspect it's either not being used anyway, or the few people that are
> using it are happy with their older kernels.
> 
> Chrissie
> 
> 
> Signed-Off-By: Christine Caulfield <christine.caulfield@googlemail.com>

Thanks for all of your contributions, patch applied, thanks!

^ permalink raw reply

* Re: [PATCH] seq_file: add RCU versions of new hlist/list iterators
From: Paul E. McKenney @ 2010-02-19  1:12 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David S. Miller, netdev, linux-kernel
In-Reply-To: <20100218153041.2f722db8@nehalam>

On Thu, Feb 18, 2010 at 03:30:41PM -0800, Stephen Hemminger wrote:
> Many usages of seq_file use RCU protected lists, so non RCU
> iterators will not work safely.

Can't say that I am thrilled by the use of __list_for_each_rcu() and the
creation of __hlist_for_each(), but given the seq_list API, I don't see
a reasonable alternative.  So...

Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>

> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> ---
>  fs/seq_file.c            |   82 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/rculist.h  |    5 ++
>  include/linux/seq_file.h |   27 ++++++++++-----
>  3 files changed, 105 insertions(+), 9 deletions(-)
> 
> --- a/fs/seq_file.c	2010-02-18 15:08:53.228872265 -0800
> +++ b/fs/seq_file.c	2010-02-18 15:26:21.157402219 -0800
> @@ -695,6 +695,38 @@ struct list_head *seq_list_next(void *v,
>  }
>  EXPORT_SYMBOL(seq_list_next);
> 
> +struct list_head *seq_list_start_rcu(struct list_head *head, loff_t pos)
> +{
> +	struct list_head *lh;
> +
> +	__list_for_each_rcu(lh, head)
> +		if (pos-- == 0)
> +			return lh;
> +
> +	return NULL;
> +}
> +EXPORT_SYMBOL(seq_list_start_rcu);
> +
> +struct list_head *seq_list_start_head_rcu(struct list_head *head, loff_t pos)
> +{
> +	if (!pos)
> +		return head;
> +
> +	return seq_list_start_rcu(head, pos - 1);
> +}
> +EXPORT_SYMBOL(seq_list_start_head_rcu);
> +
> +struct list_head *seq_list_next_rcu(void *v, struct list_head *head,
> +				    loff_t *ppos)
> +{
> +	struct list_head *lh = v;
> +
> +	lh = rcu_dereference(lh->next);
> +	++*ppos;
> +	return lh == head ? NULL : lh;
> +}
> +EXPORT_SYMBOL(seq_list_next_rcu);
> +
>  /**
>   * seq_hlist_start - start an iteration of a hlist
>   * @head: the head of the hlist
> @@ -750,3 +782,53 @@ struct hlist_node *seq_hlist_next(void *
>  		return node->next;
>  }
>  EXPORT_SYMBOL(seq_hlist_next);
> +
> +/**
> + * seq_hlist_start_rcu - start an iteration of a hlist protected by RCU
> + * @head: the head of the hlist
> + * @pos:  the start position of the sequence
> + *
> + * Called at seq_file->op->start().
> + */
> +struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head, loff_t pos)
> +{
> +	struct hlist_node *node;
> +
> +	__hlist_for_each_rcu(node, head)
> +		if (pos-- == 0)
> +			return node;
> +	return NULL;
> +}
> +EXPORT_SYMBOL(seq_hlist_start_rcu);
> +
> +/**
> + * seq_hlist_start_head_rcu - start an iteration of a hlist protected by RCU
> + * @head: the head of the hlist
> + * @pos:  the start position of the sequence
> + *
> + * Called at seq_file->op->start(). Call this function if you want to
> + * print a header at the top of the output.
> + */
> +struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head, loff_t pos)
> +{
> +	if (!pos)
> +		return SEQ_START_TOKEN;
> +
> +	return seq_hlist_start_rcu(head, pos - 1);
> +}
> +EXPORT_SYMBOL(seq_hlist_start_rcu);
> +
> +/**
> + * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU
> + * @v:    the current iterator
> + * @head: the head of the hlist
> + * @pos:  the current posision
> + *
> + * Called at seq_file->op->next().
> + */
> +struct hlist_node *seq_hlist_next_rcu(void *v, struct hlist_head *head,
> +				      loff_t *ppos)
> +{
> +	return rcu_dereference(seq_hlist_next(v, head, ppos));
> +}
> +EXPORT_SYMBOL(seq_hlist_next_rcu);
> --- a/include/linux/seq_file.h	2010-02-18 15:08:53.256872028 -0800
> +++ b/include/linux/seq_file.h	2010-02-18 15:09:14.128997914 -0800
> @@ -127,23 +127,32 @@ int seq_release_private(struct inode *, 
>  /*
>   * Helpers for iteration over list_head-s in seq_files
>   */
> -
>  extern struct list_head *seq_list_start(struct list_head *head,
> -		loff_t pos);
> +					loff_t pos);
>  extern struct list_head *seq_list_start_head(struct list_head *head,
> -		loff_t pos);
> +					     loff_t pos);
>  extern struct list_head *seq_list_next(void *v, struct list_head *head,
> -		loff_t *ppos);
> -
> +				       loff_t *ppos);
> +extern struct list_head *seq_list_start_rcu(struct list_head *head,
> +					    loff_t pos);
> +extern struct list_head *seq_list_start_head_rcu(struct list_head *head,
> +						 loff_t pos);
> +extern struct list_head *seq_list_next_rcu(void *v, struct list_head *head,
> +					   loff_t *ppos);
>  /*
>   * Helpers for iteration over hlist_head-s in seq_files
>   */
> -
>  extern struct hlist_node *seq_hlist_start(struct hlist_head *head,
> -		loff_t pos);
> +					  loff_t pos);
>  extern struct hlist_node *seq_hlist_start_head(struct hlist_head *head,
> -		loff_t pos);
> +					       loff_t pos);
>  extern struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
> -		loff_t *ppos);
> +					 loff_t *ppos);
> 
> +extern struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head,
> +					      loff_t pos);
> +extern struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head,
> +						   loff_t pos);
> +extern struct hlist_node *seq_hlist_next_rcu(void *v, struct hlist_head *head,
> +					     loff_t *ppos);
>  #endif
> --- a/include/linux/rculist.h	2010-02-18 15:25:03.681496691 -0800
> +++ b/include/linux/rculist.h	2010-02-18 15:26:13.909286656 -0800
> @@ -406,6 +406,11 @@ static inline void hlist_add_after_rcu(s
>  		n->next->pprev = &n->next;
>  }
> 
> +#define __hlist_for_each(pos, head)			\
> +	for (pos = rcu_dereference((head)->first);	\
> +	     pos && ({ prefetch(pos->next); 1; });	\
> +	     pos = rcu_derference(pos->next))
> +
>  /**
>   * hlist_for_each_entry_rcu - iterate over rcu list of given type
>   * @tpos:	the type * to use as a loop cursor.

^ permalink raw reply

* Re: [net-next-2.6 PATCH 1/3] vlan: adds vlan_dev_select_queue
From: Vasu Dev @ 2010-02-19  1:12 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, jeffrey.t.kirsher, netdev, gospo, vasu.dev
In-Reply-To: <1266478630.2877.9.camel@edumazet-laptop>

On Thu, 2010-02-18 at 08:37 +0100, Eric Dumazet wrote:
> > This means vlan_netdev_ops & vlan_netdev_accel_ops not to be const
> > anymore so that vlan_dev_select_queue() could be initialized to vlan
> ops
> > based on real dev ndo_select_queue() present or not, should be okay
> to
> > be not const anymore. I'll update patch as suggested.
> 
> No they should stay const
> 
> I said you should mirror (copy if you prefer) the structure, one with
> a
> NULL ndo_select_queue pointer, one with a ndo_select_queue =
> vlan_dev_select_queue.
> 
> Both structures are const.
> 
> You must not dynamiucally change the structure, because the same
> machine
> might have a vlan over a device with no ndo_select_queue() method, and
> another vlan over a device with a ndo_select_queue()
> 

I see, I'll mirror existing vlan op structs to have them w/ and w/o
vlan_dev_select_queue while having all vlan ops statically defined
const.

	Thanks Eric.
	Vasu


^ permalink raw reply

* NAT regression in next tree
From: Stephen Hemminger @ 2010-02-19  1:36 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: David Miller, netdev, netfilter-devel
In-Reply-To: <201002171526.02493.arnd@arndb.de>

Something in net-next tree broke bridging of virtual nets.
My local VM's can no longer access external networks.

It is a NAT problem. One of the recent netfilter changes is causing
the packets to not have there source address rewritten.

I see:
    VM1  -- 192.168.100.0/24 -- HOST -- 192.168.1.0/24 -- ROUTER
                           virbr0    eth0

Even a simple ping from VM1 doesn't get responded to because
the 192.168.100.X source address is not getting rewritten.

iptables -n -v -v -L (on host) after several attempted packets
-----------------
Chain INPUT (policy ACCEPT 2767 packets, 1347K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     udp  --  virbr1 *       0.0.0.0/0            0.0.0.0/0           udp dpt:53 
    0     0 ACCEPT     tcp  --  virbr1 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:53 
    0     0 ACCEPT     udp  --  virbr1 *       0.0.0.0/0            0.0.0.0/0           udp dpt:67 
    0     0 ACCEPT     tcp  --  virbr1 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:67 
    0     0 ACCEPT     udp  --  virbr2 *       0.0.0.0/0            0.0.0.0/0           udp dpt:53 
    0     0 ACCEPT     tcp  --  virbr2 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:53 
    0     0 ACCEPT     udp  --  virbr2 *       0.0.0.0/0            0.0.0.0/0           udp dpt:67 
    0     0 ACCEPT     tcp  --  virbr2 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:67 
    5   295 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           udp dpt:53 
    0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:53 
    2   656 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           udp dpt:67 
    0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:67 
    0     0 ACCEPT     udp  --  virbr4 *       0.0.0.0/0            0.0.0.0/0           udp dpt:53 
    0     0 ACCEPT     tcp  --  virbr4 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:53 
    0     0 ACCEPT     udp  --  virbr4 *       0.0.0.0/0            0.0.0.0/0           udp dpt:67 
    0     0 ACCEPT     tcp  --  virbr4 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:67 

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  virbr1 virbr1  0.0.0.0/0            0.0.0.0/0           
    0     0 REJECT     all  --  *      virbr1  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable 
    0     0 REJECT     all  --  virbr1 *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable 
    0     0 ACCEPT     all  --  virbr2 virbr2  0.0.0.0/0            0.0.0.0/0           
    0     0 REJECT     all  --  *      virbr2  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable 
    0     0 REJECT     all  --  virbr2 *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable 
    0     0 ACCEPT     all  --  *      virbr0  0.0.0.0/0            192.168.100.0/24    state RELATED,ESTABLISHED 
   15  1188 ACCEPT     all  --  virbr0 *       192.168.100.0/24     0.0.0.0/0           
    0     0 ACCEPT     all  --  virbr0 virbr0  0.0.0.0/0            0.0.0.0/0           
    0     0 REJECT     all  --  *      virbr0  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable 
    0     0 REJECT     all  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable 
    0     0 ACCEPT     all  --  virbr4 virbr4  0.0.0.0/0            0.0.0.0/0           
    0     0 REJECT     all  --  *      virbr4  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable 
    0     0 REJECT     all  --  virbr4 *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable 

Chain OUTPUT (policy ACCEPT 2720 packets, 1311K bytes)
 pkts bytes target     prot opt in     out     source               destination         
libiptc vlibxtables.so.2. 6000 bytes.
Table `filter'
Hooks: pre/in/fwd/out/post = ffffffff/0/d18/1628/ffffffff
Underflows: pre/in/fwd/out/post = ffffffff/c80/1590/1628/ffffffff
Entry 0 (0):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr1'/XXXXXXX.........to `'/................
Protocol: 17
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `udp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 1 (200):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr1'/XXXXXXX.........to `'/................
Protocol: 6
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `tcp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 2 (400):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr1'/XXXXXXX.........to `'/................
Protocol: 17
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `udp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 3 (600):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr1'/XXXXXXX.........to `'/................
Protocol: 6
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `tcp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 4 (800):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr2'/XXXXXXX.........to `'/................
Protocol: 17
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `udp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 5 (1000):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr2'/XXXXXXX.........to `'/................
Protocol: 6
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `tcp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 6 (1200):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr2'/XXXXXXX.........to `'/................
Protocol: 17
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `udp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 7 (1400):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr2'/XXXXXXX.........to `'/................
Protocol: 6
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `tcp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 8 (1600):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr0'/XXXXXXX.........to `'/................
Protocol: 17
Flags: 00
Invflags: 00
Counters: 5 packets, 295 bytes
Cache: 00000000
Match name: `udp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 9 (1800):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr0'/XXXXXXX.........to `'/................
Protocol: 6
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `tcp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 10 (2000):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr0'/XXXXXXX.........to `'/................
Protocol: 17
Flags: 00
Invflags: 00
Counters: 2 packets, 656 bytes
Cache: 00000000
Match name: `udp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 11 (2200):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr0'/XXXXXXX.........to `'/................
Protocol: 6
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `tcp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 12 (2400):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr4'/XXXXXXX.........to `'/................
Protocol: 17
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `udp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 13 (2600):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr4'/XXXXXXX.........to `'/................
Protocol: 6
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `tcp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 14 (2800):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr4'/XXXXXXX.........to `'/................
Protocol: 17
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `udp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 15 (3000):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr4'/XXXXXXX.........to `'/................
Protocol: 6
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `tcp'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 16 (3200):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `'/................to `'/................
Protocol: 0
Flags: 00
Invflags: 00
Counters: 2767 packets, 1347401 bytes
Cache: 00000000
Target name: `' [40]
verdict=NF_ACCEPT

Entry 17 (3352):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr1'/XXXXXXX.........to `virbr1'/XXXXXXX.........
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `' [40]
verdict=NF_ACCEPT

Entry 18 (3504):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `'/................to `virbr1'/XXXXXXX.........
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `REJECT' [40]

Entry 19 (3656):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr1'/XXXXXXX.........to `'/................
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `REJECT' [40]

Entry 20 (3808):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr2'/XXXXXXX.........to `virbr2'/XXXXXXX.........
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `' [40]
verdict=NF_ACCEPT

Entry 21 (3960):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `'/................to `virbr2'/XXXXXXX.........
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `REJECT' [40]

Entry 22 (4112):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr2'/XXXXXXX.........to `'/................
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `REJECT' [40]

Entry 23 (4264):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 192.168.100.0/255.255.255.0
Interface: `'/................to `virbr0'/XXXXXXX.........
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Match name: `state'
Target name: `' [40]
verdict=NF_ACCEPT

Entry 24 (4456):
SRC IP: 192.168.100.0/255.255.255.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr0'/XXXXXXX.........to `'/................
Protocol: 0
Flags: 00
Invflags: 00
Counters: 15 packets, 1188 bytes
Cache: 00000000
Target name: `' [40]
verdict=NF_ACCEPT

Entry 25 (4608):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr0'/XXXXXXX.........to `virbr0'/XXXXXXX.........
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `' [40]
verdict=NF_ACCEPT

Entry 26 (4760):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `'/................to `virbr0'/XXXXXXX.........
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `REJECT' [40]

Entry 27 (4912):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr0'/XXXXXXX.........to `'/................
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `REJECT' [40]

Entry 28 (5064):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr4'/XXXXXXX.........to `virbr4'/XXXXXXX.........
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `' [40]
verdict=NF_ACCEPT

Entry 29 (5216):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `'/................to `virbr4'/XXXXXXX.........
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `REJECT' [40]

Entry 30 (5368):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `virbr4'/XXXXXXX.........to `'/................
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `REJECT' [40]

Entry 31 (5520):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `'/................to `'/................
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `' [40]
verdict=NF_ACCEPT

Entry 32 (5672):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `'/................to `'/................
Protocol: 0
Flags: 00
Invflags: 00
Counters: 2720 packets, 1310915 bytes
Cache: 00000000
Target name: `' [40]
verdict=NF_ACCEPT

Entry 33 (5824):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `'/................to `'/................
Protocol: 0
Flags: 00
Invflags: 00
Counters: 0 packets, 0 bytes
Cache: 00000000
Target name: `ERROR' [64]
error=`ERROR'


^ permalink raw reply

* Re: [PATCH net-next-2.6] vhost: Restart tx poll when socket send queue is full
From: Sridhar Samudrala @ 2010-02-19  2:00 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: David Miller, netdev
In-Reply-To: <20100218223021.GB14847@redhat.com>

On Fri, 2010-02-19 at 00:30 +0200, Michael S. Tsirkin wrote:
> On Thu, Feb 18, 2010 at 12:59:11PM -0800, Sridhar Samudrala wrote:
> > When running guest to remote host TCP stream test using vhost-net
> > via tap/macvtap, i am seeing network transmit hangs. This happens
> > when handle_tx() returns because of the socket send queue full 
> > condition.
> > This patch fixes this by restarting tx poll when hitting this
> > condition.
> 
> 
> Thanks! I would like to better understand what happens exactly.
> Some questions below:
> 
> > 
> > Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
> > 
> > diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> > index 91a324c..82d4bbe 100644
> > --- a/drivers/vhost/net.c
> > +++ b/drivers/vhost/net.c
> > @@ -113,12 +113,16 @@ static void handle_tx(struct vhost_net *net)
> >  	if (!sock)
> >  		return;
> >  
> > -	wmem = atomic_read(&sock->sk->sk_wmem_alloc);
> > -	if (wmem >= sock->sk->sk_sndbuf)
> > -		return;
> > -
> 
> The disadvantage here is that a spurious wakeup
> when queue is still full becomes more expensive.
> 
> >  	use_mm(net->dev.mm);
> >  	mutex_lock(&vq->mutex);
> > +
> > +	wmem = atomic_read(&sock->sk->sk_wmem_alloc);
> > +	if (wmem >= sock->sk->sk_sndbuf) {
> > +		tx_poll_start(net, sock);
> 
> Hmm. We already do
>                        if (wmem >= sock->sk->sk_sndbuf * 3 / 4) {
>                                 tx_poll_start(net, sock);
>                                 set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
>                                 break;
>                         }
> why does not this code trigger here?

This check is done only when the ring is empty(head == vq->num).
But we are breaking out of the loop here.
                if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
                        vhost_poll_queue(&vq->poll);
                        break;
                }

I guess tx_poll_start() is missing here. The following patch fixes
the hang and may be a better fix.

Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 4c89283..fe9d296 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -172,6 +172,7 @@ static void handle_tx(struct vhost_net *net)
 		vhost_add_used_and_signal(&net->dev, vq, head, 0);
 		total_len += len;
 		if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
+			tx_poll_start(net, sock);
 			vhost_poll_queue(&vq->poll);
 			break;
 		}

Thanks
Sridhar


^ permalink raw reply related

* Re: kernel stack  trace using conntrack
From: Pablo Neira Ayuso @ 2010-02-19  2:18 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: Ramblewski David, Eric Dumazet, netfilter-devel@vger.kernel.org,
	netdev
In-Reply-To: <4B7D306F.9060808@trash.net>

[-- Attachment #1: Type: text/plain, Size: 1284 bytes --]

Patrick McHardy wrote:
> Pablo Neira Ayuso wrote:
>> Patrick McHardy wrote:
>>>>> Pablo, please let me know whether you want me to apply this.
>>>> ctnetlink_change_helper() also calls nf_ct_ext_add() for conntracks that
>>>> are confirmed (in case of a helper update for an existing conntrack).
>>>> That would also trigger the assertion. If we want to support helper
>>>> assignation via ctnetlink for existing conntracks, we will need to add
>>>> locking to the conntrack extension infrastructure to avoid races.
>>>>
>>>> I don't see a clear solution for this yet.
>>> I see, this is indeed a problem. Since the helper is known at the
>>> first event, we could restrict this to only allow manual assignment
>>> for newly created conntracks. Most helpers probably can't properly
>>> cope with connections not seen from the beginning anyways.
>> Indeed, changing the helper in the middle of the road doesn't make too
>> much sense to me either. I can send you a patch for this along today,
>> I'll find some spare time to do it.
> 
> Great, thanks Pablo.

I have slightly tested the following patch here. I think it should fix
the problem.

We can revisit ctnetlink_change_helper() later, I think there's some
code there that can be refactorized.

Let me know if you're OK with it.

[-- Attachment #2: fix-helper.patch --]
[-- Type: text/x-patch, Size: 2841 bytes --]

netfilter: ctnetlink: fix creation of conntrack with helpers

This patch fixes a bug that triggers an assertion if you create
a conntrack entry with a helper and netfilter debugging is enabled.
Basically, we hit the assertion because the confirmation flag is
set before the conntrack extensions are added. To fix this, we
move the extension addition before the aforementioned flag is
set.

This patch also removes the possibility of setting a helper for
existing conntracks. This operation would also trigger the
assertion since we are not allowed to add new extensions for
existing conntracks. We know noone that could benefit from
this operation sanely.

Thanks to Eric Dumazet for initial posting a preliminary patch
to address this issue.

Reported-by: David Ramblewski <David.Ramblewski@atosorigin.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_conntrack_netlink.c |   22 +++++++++++-----------
 1 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 8b05f36..2b2af63 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1077,9 +1077,8 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
 		/* need to zero data of old helper */
 		memset(&help->help, 0, sizeof(help->help));
 	} else {
-		help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
-		if (help == NULL)
-			return -ENOMEM;
+		/* we cannot set a helper for an existing conntrack */
+		return -EOPNOTSUPP;
 	}
 
 	rcu_assign_pointer(help->helper, helper);
@@ -1263,7 +1262,6 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
 	ct->timeout.expires = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
 
 	ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
-	ct->status |= IPS_CONFIRMED;
 
 	rcu_read_lock();
  	if (cda[CTA_HELP]) {
@@ -1314,14 +1312,19 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
 			goto err2;
 	}
 
-	if (cda[CTA_STATUS]) {
-		err = ctnetlink_change_status(ct, cda);
+	if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
+		err = ctnetlink_change_nat(ct, cda);
 		if (err < 0)
 			goto err2;
 	}
 
-	if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
-		err = ctnetlink_change_nat(ct, cda);
+	nf_ct_acct_ext_add(ct, GFP_ATOMIC);
+	nf_ct_ecache_ext_add(ct, 0, 0, GFP_ATOMIC);
+	/* we must add conntrack extensions before confirmation. */
+	ct->status |= IPS_CONFIRMED;
+
+	if (cda[CTA_STATUS]) {
+		err = ctnetlink_change_status(ct, cda);
 		if (err < 0)
 			goto err2;
 	}
@@ -1340,9 +1343,6 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
 			goto err2;
 	}
 
-	nf_ct_acct_ext_add(ct, GFP_ATOMIC);
-	nf_ct_ecache_ext_add(ct, 0, 0, GFP_ATOMIC);
-
 #if defined(CONFIG_NF_CONNTRACK_MARK)
 	if (cda[CTA_MARK])
 		ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));

^ permalink raw reply related

* Re: NAT regression in next tree
From: Patrick McHardy @ 2010-02-19  5:45 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev, netfilter-devel
In-Reply-To: <20100218173633.30bb8c41@nehalam>

Stephen Hemminger wrote:
> Something in net-next tree broke bridging of virtual nets.
> My local VM's can no longer access external networks.
> 
> It is a NAT problem. One of the recent netfilter changes is causing
> the packets to not have there source address rewritten.
> 
> I see:
>     VM1  -- 192.168.100.0/24 -- HOST -- 192.168.1.0/24 -- ROUTER
>                            virbr0    eth0
> 
> Even a simple ping from VM1 doesn't get responded to because
> the 192.168.100.X source address is not getting rewritten.

I'll try to reproduce it locally. What is the HEAD of the broken
tree you're running?

^ permalink raw reply

* [PATCH 1/2] seq_file: add RCU versions of new hlist/list iterators (v2)
From: Stephen Hemminger @ 2010-02-19  5:41 UTC (permalink / raw)
  To: David S. Miller, Li Zefan; +Cc: netdev, linux-kernel
In-Reply-To: <20100219054145.959067404@vyatta.com>

[-- Attachment #1: seq_hlist_rcu.patch --]
[-- Type: text/plain, Size: 5194 bytes --]

Many usages of seq_file use RCU protected lists, so non RCU
iterators will not work safely. Needed to make __hlist_for_each_rcu
macro (like __list_for_each_rcu).

Also indented prototypes to match existing style.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 fs/seq_file.c            |   88 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/rculist.h  |    5 ++
 include/linux/seq_file.h |   27 +++++++++-----
 3 files changed, 111 insertions(+), 9 deletions(-)

--- a/fs/seq_file.c	2010-02-18 15:08:53.228872265 -0800
+++ b/fs/seq_file.c	2010-02-18 15:37:09.660996801 -0800
@@ -695,6 +695,38 @@ struct list_head *seq_list_next(void *v,
 }
 EXPORT_SYMBOL(seq_list_next);
 
+struct list_head *seq_list_start_rcu(struct list_head *head, loff_t pos)
+{
+	struct list_head *lh;
+
+	__list_for_each_rcu(lh, head)
+		if (pos-- == 0)
+			return lh;
+
+	return NULL;
+}
+EXPORT_SYMBOL(seq_list_start_rcu);
+
+struct list_head *seq_list_start_head_rcu(struct list_head *head, loff_t pos)
+{
+	if (!pos)
+		return head;
+
+	return seq_list_start_rcu(head, pos - 1);
+}
+EXPORT_SYMBOL(seq_list_start_head_rcu);
+
+struct list_head *seq_list_next_rcu(void *v, struct list_head *head,
+				    loff_t *ppos)
+{
+	struct list_head *lh = v;
+
+	lh = rcu_dereference(lh->next);
+	++*ppos;
+	return lh == head ? NULL : lh;
+}
+EXPORT_SYMBOL(seq_list_next_rcu);
+
 /**
  * seq_hlist_start - start an iteration of a hlist
  * @head: the head of the hlist
@@ -750,3 +782,59 @@ struct hlist_node *seq_hlist_next(void *
 		return node->next;
 }
 EXPORT_SYMBOL(seq_hlist_next);
+
+/**
+ * seq_hlist_start_rcu - start an iteration of a hlist protected by RCU
+ * @head: the head of the hlist
+ * @pos:  the start position of the sequence
+ *
+ * Called at seq_file->op->start().
+ */
+struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head, loff_t pos)
+{
+	struct hlist_node *node;
+
+	__hlist_for_each_rcu(node, head)
+		if (pos-- == 0)
+			return node;
+	return NULL;
+}
+EXPORT_SYMBOL(seq_hlist_start_rcu);
+
+/**
+ * seq_hlist_start_head_rcu - start an iteration of a hlist protected by RCU
+ * @head: the head of the hlist
+ * @pos:  the start position of the sequence
+ *
+ * Called at seq_file->op->start(). Call this function if you want to
+ * print a header at the top of the output.
+ */
+struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head, loff_t pos)
+{
+	if (!pos)
+		return SEQ_START_TOKEN;
+
+	return seq_hlist_start_rcu(head, pos - 1);
+}
+EXPORT_SYMBOL(seq_hlist_start_head_rcu);
+
+/**
+ * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU
+ * @v:    the current iterator
+ * @head: the head of the hlist
+ * @pos:  the current posision
+ *
+ * Called at seq_file->op->next().
+ */
+struct hlist_node *seq_hlist_next_rcu(void *v, struct hlist_head *head,
+				      loff_t *ppos)
+{
+	struct hlist_node *node = v;
+
+	++*ppos;
+	if (v == SEQ_START_TOKEN)
+		return rcu_dereference(head->first);
+	else
+		return rcu_dereference(node->next);
+}
+EXPORT_SYMBOL(seq_hlist_next_rcu);
--- a/include/linux/seq_file.h	2010-02-18 15:08:53.256872028 -0800
+++ b/include/linux/seq_file.h	2010-02-18 15:09:14.128997914 -0800
@@ -127,23 +127,32 @@ int seq_release_private(struct inode *, 
 /*
  * Helpers for iteration over list_head-s in seq_files
  */
-
 extern struct list_head *seq_list_start(struct list_head *head,
-		loff_t pos);
+					loff_t pos);
 extern struct list_head *seq_list_start_head(struct list_head *head,
-		loff_t pos);
+					     loff_t pos);
 extern struct list_head *seq_list_next(void *v, struct list_head *head,
-		loff_t *ppos);
-
+				       loff_t *ppos);
+extern struct list_head *seq_list_start_rcu(struct list_head *head,
+					    loff_t pos);
+extern struct list_head *seq_list_start_head_rcu(struct list_head *head,
+						 loff_t pos);
+extern struct list_head *seq_list_next_rcu(void *v, struct list_head *head,
+					   loff_t *ppos);
 /*
  * Helpers for iteration over hlist_head-s in seq_files
  */
-
 extern struct hlist_node *seq_hlist_start(struct hlist_head *head,
-		loff_t pos);
+					  loff_t pos);
 extern struct hlist_node *seq_hlist_start_head(struct hlist_head *head,
-		loff_t pos);
+					       loff_t pos);
 extern struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head,
-		loff_t *ppos);
+					 loff_t *ppos);
 
+extern struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head,
+					      loff_t pos);
+extern struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head,
+						   loff_t pos);
+extern struct hlist_node *seq_hlist_next_rcu(void *v, struct hlist_head *head,
+					     loff_t *ppos);
 #endif
--- a/include/linux/rculist.h	2010-02-18 15:25:03.681496691 -0800
+++ b/include/linux/rculist.h	2010-02-18 15:33:26.352872829 -0800
@@ -406,6 +406,11 @@ static inline void hlist_add_after_rcu(s
 		n->next->pprev = &n->next;
 }
 
+#define __hlist_for_each_rcu(pos, head)			\
+	for (pos = rcu_dereference((head)->first);	\
+	     pos && ({ prefetch(pos->next); 1; });	\
+	     pos = rcu_dereference(pos->next))
+
 /**
  * hlist_for_each_entry_rcu - iterate over rcu list of given type
  * @tpos:	the type * to use as a loop cursor.

-- 


^ permalink raw reply

* [PATCH 2/2] packet: convert socket list to RCU
From: Stephen Hemminger @ 2010-02-19  5:41 UTC (permalink / raw)
  To: David S. Miller, Li Zefan; +Cc: netdev, linux-kernel
In-Reply-To: <20100219054145.959067404@vyatta.com>

[-- Attachment #1: packet-list-rcu.patch --]
[-- Type: text/plain, Size: 5413 bytes --]

Convert AF_PACKET to use RCU, eliminating one more reader/writer lock.

I needed to create some minor additional socket list RCU infrastructure
to make this work. Note: there is no need for a real sk_del_node_init_rcu(), 
because sk_del_node_init is doing the equivalent thing to 
hlst_del_init_rcu already; but added some comments to try and make that obvious.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 include/net/netns/packet.h |    4 ++--
 include/net/sock.h         |   10 ++++++++++
 net/packet/af_packet.c     |   42 ++++++++++++++++++++----------------------
 3 files changed, 32 insertions(+), 24 deletions(-)

--- a/include/net/netns/packet.h	2010-02-18 15:08:59.532872158 -0800
+++ b/include/net/netns/packet.h	2010-02-18 15:09:16.433496523 -0800
@@ -4,11 +4,11 @@
 #ifndef __NETNS_PACKET_H__
 #define __NETNS_PACKET_H__
 
-#include <linux/list.h>
+#include <linux/rculist.h>
 #include <linux/spinlock.h>
 
 struct netns_packet {
-	rwlock_t		sklist_lock;
+	spinlock_t		sklist_lock;
 	struct hlist_head	sklist;
 };
 
--- a/net/packet/af_packet.c	2010-02-18 15:08:59.520873035 -0800
+++ b/net/packet/af_packet.c	2010-02-18 15:10:33.908871539 -0800
@@ -1262,18 +1262,15 @@ static int packet_release(struct socket 
 	net = sock_net(sk);
 	po = pkt_sk(sk);
 
-	write_lock_bh(&net->packet.sklist_lock);
-	sk_del_node_init(sk);
+	spin_lock_bh(&net->packet.sklist_lock);
+	sk_del_node_init_rcu(sk);
 	sock_prot_inuse_add(net, sk->sk_prot, -1);
-	write_unlock_bh(&net->packet.sklist_lock);
-
-	/*
-	 *	Unhook packet receive handler.
-	 */
+	spin_unlock_bh(&net->packet.sklist_lock);
 
 	if (po->running) {
 		/*
-		 *	Remove the protocol hook
+		 * Remove from protocol table
+		 *  does synchronize_net()
 		 */
 		dev_remove_pack(&po->prot_hook);
 		po->running = 0;
@@ -1478,10 +1475,11 @@ static int packet_create(struct net *net
 		po->running = 1;
 	}
 
-	write_lock_bh(&net->packet.sklist_lock);
-	sk_add_node(sk, &net->packet.sklist);
+	spin_lock_bh(&net->packet.sklist_lock);
+	sk_add_node_rcu(sk, &net->packet.sklist);
 	sock_prot_inuse_add(net, &packet_proto, 1);
-	write_unlock_bh(&net->packet.sklist_lock);
+	spin_unlock_bh(&net->packet.sklist_lock);
+
 	return 0;
 out:
 	return err;
@@ -2075,8 +2073,8 @@ static int packet_notifier(struct notifi
 	struct net_device *dev = data;
 	struct net *net = dev_net(dev);
 
-	read_lock(&net->packet.sklist_lock);
-	sk_for_each(sk, node, &net->packet.sklist) {
+	rcu_read_lock();
+	sk_for_each_rcu(sk, node, &net->packet.sklist) {
 		struct packet_sock *po = pkt_sk(sk);
 
 		switch (msg) {
@@ -2115,7 +2113,7 @@ static int packet_notifier(struct notifi
 			break;
 		}
 	}
-	read_unlock(&net->packet.sklist_lock);
+	rcu_read_unlock();
 	return NOTIFY_DONE;
 }
 
@@ -2512,24 +2510,24 @@ static struct notifier_block packet_netd
 #ifdef CONFIG_PROC_FS
 
 static void *packet_seq_start(struct seq_file *seq, loff_t *pos)
-	__acquires(seq_file_net(seq)->packet.sklist_lock)
+	__acquires(RCU)
 {
 	struct net *net = seq_file_net(seq);
-	read_lock(&net->packet.sklist_lock);
-	return seq_hlist_start_head(&net->packet.sklist, *pos);
+
+	rcu_read_lock();
+	return seq_hlist_start_head_rcu(&net->packet.sklist, *pos);
 }
 
 static void *packet_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
 	struct net *net = seq_file_net(seq);
-	return seq_hlist_next(v, &net->packet.sklist, pos);
+	return seq_hlist_next_rcu(v, &net->packet.sklist, pos);
 }
 
 static void packet_seq_stop(struct seq_file *seq, void *v)
-	__releases(seq_file_net(seq)->packet.sklist_lock)
+	__releases(RCU)
 {
-	struct net *net = seq_file_net(seq);
-	read_unlock(&net->packet.sklist_lock);
+	rcu_read_unlock();
 }
 
 static int packet_seq_show(struct seq_file *seq, void *v)
@@ -2581,7 +2579,7 @@ static const struct file_operations pack
 
 static int __net_init packet_net_init(struct net *net)
 {
-	rwlock_init(&net->packet.sklist_lock);
+	spin_lock_init(&net->packet.sklist_lock);
 	INIT_HLIST_HEAD(&net->packet.sklist);
 
 	if (!proc_net_fops_create(net, "packet", 0, &packet_seq_fops))
--- a/include/net/sock.h	2010-02-18 15:08:59.548872240 -0800
+++ b/include/net/sock.h	2010-02-18 15:09:16.437496392 -0800
@@ -381,6 +381,7 @@ static __inline__ void __sk_del_node(str
 	__hlist_del(&sk->sk_node);
 }
 
+/* NB: equivalent to hlist_del_init_rcu */
 static __inline__ int __sk_del_node_init(struct sock *sk)
 {
 	if (sk_hashed(sk)) {
@@ -421,6 +422,7 @@ static __inline__ int sk_del_node_init(s
 	}
 	return rc;
 }
+#define sk_del_node_init_rcu(sk)	sk_del_node_init(sk)
 
 static __inline__ int __sk_nulls_del_node_init_rcu(struct sock *sk)
 {
@@ -454,6 +456,12 @@ static __inline__ void sk_add_node(struc
 	__sk_add_node(sk, list);
 }
 
+static __inline__ void sk_add_node_rcu(struct sock *sk, struct hlist_head *list)
+{
+	sock_hold(sk);
+	hlist_add_head_rcu(&sk->sk_node, list);
+}
+
 static __inline__ void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list)
 {
 	hlist_nulls_add_head_rcu(&sk->sk_nulls_node, list);
@@ -478,6 +486,8 @@ static __inline__ void sk_add_bind_node(
 
 #define sk_for_each(__sk, node, list) \
 	hlist_for_each_entry(__sk, node, list, sk_node)
+#define sk_for_each_rcu(__sk, node, list) \
+	hlist_for_each_entry_rcu(__sk, node, list, sk_node)
 #define sk_nulls_for_each(__sk, node, list) \
 	hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
 #define sk_nulls_for_each_rcu(__sk, node, list) \

-- 


^ permalink raw reply

* Re: NAT regression in next tree
From: Stephen Hemminger @ 2010-02-19  5:51 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: David Miller, netdev, netfilter-devel
In-Reply-To: <4B7E2587.3050608@trash.net>

On Fri, 19 Feb 2010 06:45:43 +0100
Patrick McHardy <kaber@trash.net> wrote:

> Stephen Hemminger wrote:
> > Something in net-next tree broke bridging of virtual nets.
> > My local VM's can no longer access external networks.
> > 
> > It is a NAT problem. One of the recent netfilter changes is causing
> > the packets to not have there source address rewritten.
> > 
> > I see:
> >     VM1  -- 192.168.100.0/24 -- HOST -- 192.168.1.0/24 -- ROUTER
> >                            virbr0    eth0
> > 
> > Even a simple ping from VM1 doesn't get responded to because
> > the 192.168.100.X source address is not getting rewritten.
> 
> I'll try to reproduce it locally. What is the HEAD of the broken
> tree you're running?

commit 37ee3d5b3e979a168536e7e2f15bd1e769cb4122
Author: Patrick McHardy <kaber@trash.net>
Date:   Thu Feb 18 19:04:44 2010 +0100

    netfilter: nf_defrag_ipv4: fix compilation error with NF_CONNTRACK=n



-- 

^ permalink raw reply

* [RFC 2/2] SCTP: fix sparse warning
From: Stephen Hemminger @ 2010-02-19  5:55 UTC (permalink / raw)
  To: Vlad Yasevich, Sridhar Samudrala, David S. Miller,
	Paul E. McKenney
  Cc: netdev, linux-sctp
In-Reply-To: <20100219055520.223027612@vyatta.com>

[-- Attachment #1: sctp-sparse.patch --]
[-- Type: text/plain, Size: 767 bytes --]

The variable node shadows earlier one in same function.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

--- a/net/sctp/socket.c	2010-02-18 10:06:57.656887238 -0800
+++ b/net/sctp/socket.c	2010-02-18 10:07:09.894132363 -0800
@@ -5478,7 +5478,7 @@ pp_found:
 		 */
 		int reuse = sk->sk_reuse;
 		struct sock *sk2;
-		struct hlist_node *node;
+		struct hlist_node *node2;
 
 		SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
 		if (pp->fastreuse && sk->sk_reuse &&
@@ -5495,7 +5495,7 @@ pp_found:
 		 * that this port/socket (sk) combination are already
 		 * in an endpoint.
 		 */
-		sk_for_each_bound(sk2, node, &pp->owner) {
+		sk_for_each_bound(sk2, node2, &pp->owner) {
 			struct sctp_endpoint *ep2;
 			ep2 = sctp_sk(sk2)->ep;
 

-- 


^ permalink raw reply

* [RFC 1/2] sctp: convert hash list to RCU
From: Stephen Hemminger @ 2010-02-19  5:55 UTC (permalink / raw)
  To: Vlad Yasevich, Sridhar Samudrala, David S. Miller,
	Paul E. McKenney
  Cc: netdev, linux-sctp
In-Reply-To: <20100219055520.223027612@vyatta.com>

[-- Attachment #1: sctp-rcu.patch --]
[-- Type: text/plain, Size: 9193 bytes --]

This patch converts existing SCTP hash list to using RCU
rather than reader/writer lock. Also, get rid of no longer used
locking wrappers.

In future, the SCTP hash locking should be broken out from the
hash structure because of the wasted space for the hash locks
and associated holes. A single lock per hashlist is sufficient
now that RCU is used.

Compile tested only. I can't think of an SCTP stress application.

P.s: Some janitor ought to go through and remove the locking
macros here.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


--- a/include/net/sctp/sctp.h	2010-02-18 09:44:42.664390403 -0800
+++ b/include/net/sctp/sctp.h	2010-02-18 09:52:48.004478538 -0800
@@ -206,10 +206,6 @@ extern struct kmem_cache *sctp_bucket_ca
 #define sctp_local_bh_enable()  local_bh_enable()
 #define sctp_spin_lock(lock)    spin_lock(lock)
 #define sctp_spin_unlock(lock)  spin_unlock(lock)
-#define sctp_write_lock(lock)   write_lock(lock)
-#define sctp_write_unlock(lock) write_unlock(lock)
-#define sctp_read_lock(lock)    read_lock(lock)
-#define sctp_read_unlock(lock)  read_unlock(lock)
 
 /* sock lock wrappers. */
 #define sctp_lock_sock(sk)       lock_sock(sk)
@@ -649,6 +645,9 @@ static inline int sctp_vtag_hashfn(__u16
 #define sctp_for_each_hentry(epb, node, head) \
 	hlist_for_each_entry(epb, node, head, node)
 
+#define sctp_for_each_hentry_rcu(epb, node, head) \
+	hlist_for_each_entry_rcu(epb, node, head, node)
+
 /* Is a socket of this style? */
 #define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))
 static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style)
--- a/include/net/sctp/structs.h	2010-02-18 09:47:29.964390311 -0800
+++ b/include/net/sctp/structs.h	2010-02-18 09:57:26.792896287 -0800
@@ -111,7 +111,7 @@ struct sctp_bind_hashbucket {
 
 /* Used for hashing all associations.  */
 struct sctp_hashbucket {
-	rwlock_t	lock;
+	spinlock_t	lock;
 	struct hlist_head	chain;
 } __attribute__((__aligned__(8)));
 
@@ -1371,6 +1371,8 @@ struct sctp_endpoint {
 	/* SCTP-AUTH: endpoint shared keys */
 	struct list_head endpoint_shared_keys;
 	__u16 active_key_id;
+
+	struct rcu_head rcu;
 };
 
 /* Recover the outter endpoint structure. */
--- a/net/sctp/endpointola.c	2010-02-18 09:43:22.868887786 -0800
+++ b/net/sctp/endpointola.c	2010-02-18 10:00:55.807210206 -0800
@@ -247,9 +247,9 @@ void sctp_endpoint_free(struct sctp_endp
 }
 
 /* Final destructor for endpoint.  */
-static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
+static void sctp_endpoint_destroy_rcu(struct rcu_head *rcu)
 {
-	SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return);
+	struct sctp_endpoint *ep = container_of(rcu, struct sctp_endpoint, rcu);
 
 	/* Free up the HMAC transform. */
 	crypto_free_hash(sctp_sk(ep->base.sk)->hmac);
@@ -286,6 +286,13 @@ static void sctp_endpoint_destroy(struct
 	}
 }
 
+static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
+{
+	SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return);
+	call_rcu(&ep->rcu, sctp_endpoint_destroy_rcu);
+}
+
+
 /* Hold a reference to an endpoint. */
 void sctp_endpoint_hold(struct sctp_endpoint *ep)
 {
@@ -338,8 +345,9 @@ static struct sctp_association *__sctp_e
 
 	hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport);
 	head = &sctp_assoc_hashtable[hash];
-	read_lock(&head->lock);
-	sctp_for_each_hentry(epb, node, &head->chain) {
+
+	rcu_read_lock();
+	sctp_for_each_hentry_rcu(epb, node, &head->chain) {
 		asoc = sctp_assoc(epb);
 		if (asoc->ep != ep || rport != asoc->peer.port)
 			goto next;
@@ -352,7 +360,7 @@ static struct sctp_association *__sctp_e
 next:
 		asoc = NULL;
 	}
-	read_unlock(&head->lock);
+	rcu_read_unlock();
 	return asoc;
 }
 
--- a/net/sctp/input.c	2010-02-18 09:51:39.104889498 -0800
+++ b/net/sctp/input.c	2010-02-18 10:02:42.972601804 -0800
@@ -704,9 +704,9 @@ static void __sctp_hash_endpoint(struct 
 	epb->hashent = sctp_ep_hashfn(epb->bind_addr.port);
 	head = &sctp_ep_hashtable[epb->hashent];
 
-	sctp_write_lock(&head->lock);
-	hlist_add_head(&epb->node, &head->chain);
-	sctp_write_unlock(&head->lock);
+	sctp_spin_lock(&head->lock);
+	hlist_add_head_rcu(&epb->node, &head->chain);
+	sctp_spin_unlock(&head->lock);
 }
 
 /* Add an endpoint to the hash. Local BH-safe. */
@@ -732,9 +732,9 @@ static void __sctp_unhash_endpoint(struc
 
 	head = &sctp_ep_hashtable[epb->hashent];
 
-	sctp_write_lock(&head->lock);
-	__hlist_del(&epb->node);
-	sctp_write_unlock(&head->lock);
+	sctp_spin_lock(&head->lock);
+	hlist_del_rcu(&epb->node);
+	sctp_spin_unlock(&head->lock);
 }
 
 /* Remove endpoint from the hash.  Local BH-safe. */
@@ -756,8 +756,8 @@ static struct sctp_endpoint *__sctp_rcv_
 
 	hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port));
 	head = &sctp_ep_hashtable[hash];
-	read_lock(&head->lock);
-	sctp_for_each_hentry(epb, node, &head->chain) {
+	rcu_read_lock();
+	sctp_for_each_hentry_rcu(epb, node, &head->chain) {
 		ep = sctp_ep(epb);
 		if (sctp_endpoint_is_match(ep, laddr))
 			goto hit;
@@ -767,7 +767,7 @@ static struct sctp_endpoint *__sctp_rcv_
 
 hit:
 	sctp_endpoint_hold(ep);
-	read_unlock(&head->lock);
+	rcu_read_unlock();
 	return ep;
 }
 
@@ -784,9 +784,9 @@ static void __sctp_hash_established(stru
 
 	head = &sctp_assoc_hashtable[epb->hashent];
 
-	sctp_write_lock(&head->lock);
-	hlist_add_head(&epb->node, &head->chain);
-	sctp_write_unlock(&head->lock);
+	sctp_spin_lock(&head->lock);
+	hlist_add_head_rcu(&epb->node, &head->chain);
+	sctp_spin_unlock(&head->lock);
 }
 
 /* Add an association to the hash. Local BH-safe. */
@@ -813,9 +813,9 @@ static void __sctp_unhash_established(st
 
 	head = &sctp_assoc_hashtable[epb->hashent];
 
-	sctp_write_lock(&head->lock);
-	__hlist_del(&epb->node);
-	sctp_write_unlock(&head->lock);
+	sctp_spin_lock(&head->lock);
+	hlist_del_rcu(&epb->node);
+	sctp_spin_unlock(&head->lock);
 }
 
 /* Remove association from the hash table.  Local BH-safe. */
@@ -847,22 +847,23 @@ static struct sctp_association *__sctp_l
 	 */
 	hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port));
 	head = &sctp_assoc_hashtable[hash];
-	read_lock(&head->lock);
-	sctp_for_each_hentry(epb, node, &head->chain) {
+
+	rcu_read_lock();
+	sctp_for_each_hentry_rcu(epb, node, &head->chain) {
 		asoc = sctp_assoc(epb);
 		transport = sctp_assoc_is_match(asoc, local, peer);
 		if (transport)
 			goto hit;
 	}
 
-	read_unlock(&head->lock);
+	rcu_read_unlock();
 
 	return NULL;
 
 hit:
 	*pt = transport;
 	sctp_association_hold(asoc);
-	read_unlock(&head->lock);
+	rcu_read_unlock();
 	return asoc;
 }
 
--- a/net/sctp/protocol.c	2010-02-18 09:42:04.556389428 -0800
+++ b/net/sctp/protocol.c	2010-02-18 09:53:03.360663641 -0800
@@ -1204,7 +1204,7 @@ SCTP_STATIC __init int sctp_init(void)
 		goto err_ahash_alloc;
 	}
 	for (i = 0; i < sctp_assoc_hashsize; i++) {
-		rwlock_init(&sctp_assoc_hashtable[i].lock);
+		spin_lock_init(&sctp_assoc_hashtable[i].lock);
 		INIT_HLIST_HEAD(&sctp_assoc_hashtable[i].chain);
 	}
 
@@ -1218,7 +1218,7 @@ SCTP_STATIC __init int sctp_init(void)
 		goto err_ehash_alloc;
 	}
 	for (i = 0; i < sctp_ep_hashsize; i++) {
-		rwlock_init(&sctp_ep_hashtable[i].lock);
+		spin_lock_init(&sctp_ep_hashtable[i].lock);
 		INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain);
 	}
 
--- a/net/sctp/proc.c	2010-02-18 10:03:50.428764115 -0800
+++ b/net/sctp/proc.c	2010-02-18 10:05:09.961659526 -0800
@@ -208,9 +208,9 @@ static int sctp_eps_seq_show(struct seq_
 		return -ENOMEM;
 
 	head = &sctp_ep_hashtable[hash];
-	sctp_local_bh_disable();
-	read_lock(&head->lock);
-	sctp_for_each_hentry(epb, node, &head->chain) {
+
+	rcu_read_lock_bh();
+	sctp_for_each_hentry_rcu(epb, node, &head->chain) {
 		ep = sctp_ep(epb);
 		sk = epb->sk;
 		seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk,
@@ -221,8 +221,7 @@ static int sctp_eps_seq_show(struct seq_
 		sctp_seq_dump_local_addrs(seq, epb);
 		seq_printf(seq, "\n");
 	}
-	read_unlock(&head->lock);
-	sctp_local_bh_enable();
+	rcu_read_unlock_bh();
 
 	return 0;
 }
@@ -312,9 +311,9 @@ static int sctp_assocs_seq_show(struct s
 		return -ENOMEM;
 
 	head = &sctp_assoc_hashtable[hash];
-	sctp_local_bh_disable();
-	read_lock(&head->lock);
-	sctp_for_each_hentry(epb, node, &head->chain) {
+
+	rcu_read_lock_bh();
+	sctp_for_each_hentry_rcu(epb, node, &head->chain) {
 		assoc = sctp_assoc(epb);
 		sk = epb->sk;
 		seq_printf(seq,
@@ -339,8 +338,7 @@ static int sctp_assocs_seq_show(struct s
 			assoc->rtx_data_chunks);
 		seq_printf(seq, "\n");
 	}
-	read_unlock(&head->lock);
-	sctp_local_bh_enable();
+	rcu_read_unlock_bh();
 
 	return 0;
 }
@@ -425,9 +423,9 @@ static int sctp_remaddr_seq_show(struct 
 		return -ENOMEM;
 
 	head = &sctp_assoc_hashtable[hash];
-	sctp_local_bh_disable();
-	read_lock(&head->lock);
-	sctp_for_each_hentry(epb, node, &head->chain) {
+
+	rcu_read_lock_bh();
+	sctp_for_each_hentry_rcu(epb, node, &head->chain) {
 		assoc = sctp_assoc(epb);
 		list_for_each_entry(tsp, &assoc->peer.transport_addr_list,
 					transports) {
@@ -475,9 +473,7 @@ static int sctp_remaddr_seq_show(struct 
 			seq_printf(seq, "\n");
 		}
 	}
-
-	read_unlock(&head->lock);
-	sctp_local_bh_enable();
+	rcu_read_unlock_bh();
 
 	return 0;
 

-- 


^ permalink raw reply

* linux-next: build failure after final merge (net tree)
From: Stephen Rothwell @ 2010-02-19  6:37 UTC (permalink / raw)
  To: David Miller, netdev; +Cc: linux-next, linux-kernel, Kristoffer Glembo

[-- Attachment #1: Type: text/plain, Size: 1347 bytes --]

Hi Dave,

After merging the scsi-post-merge tree, today's linux-next build (powerpc
allyesconfig) failed like this:

drivers/net/greth.c: In function 'greth_of_probe':
drivers/net/greth.c:1414: error: implicit declaration of function 'of_ioremap'
drivers/net/greth.c:1414: error: 'struct of_device' has no member named 'resource'
drivers/net/greth.c:1415: error: 'struct of_device' has no member named 'resource'
drivers/net/greth.c:1426: error: 'struct of_device' has no member named 'irqs'
drivers/net/greth.c:1580: error: implicit declaration of function 'of_iounmap'
drivers/net/greth.c:1580: error: 'struct of_device' has no member named 'resource'
drivers/net/greth.c:1580: error: 'struct of_device' has no member named 'resource'
drivers/net/greth.c: In function 'greth_of_remove':
drivers/net/greth.c:1605: error: 'struct of_device' has no member named 'resource'
drivers/net/greth.c:1605: error: 'struct of_device' has no member named 'resource'

Caused by commit d4c41139df6e74c6fff0cbac43e51cab782133be ("net: Add
Aeroflex Gaisler 10/100/1G Ethernet MAC driver").

I assume that this driver was written and tested only on Sparc ... maybe
it should depend on SPARC?

I have reverted that commit for today.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: linux-next: build failure after final merge (net tree)
From: David Miller @ 2010-02-19  6:53 UTC (permalink / raw)
  To: sfr; +Cc: netdev, linux-next, linux-kernel, kristoffer
In-Reply-To: <20100219173713.e3f9f386.sfr@canb.auug.org.au>

From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Fri, 19 Feb 2010 17:37:13 +1100

> I assume that this driver was written and tested only on Sparc ... maybe
> it should depend on SPARC?
> 
> I have reverted that commit for today.

I'll take a look at what it really depends upon.

Thanks.

^ permalink raw reply

* Re: NAT regression in next tree
From: Patrick McHardy @ 2010-02-19  7:06 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev, netfilter-devel
In-Reply-To: <20100218215106.557be6b0@nehalam>

[-- Attachment #1: Type: text/plain, Size: 991 bytes --]

Stephen Hemminger wrote:
> On Fri, 19 Feb 2010 06:45:43 +0100
> Patrick McHardy <kaber@trash.net> wrote:
> 
>> Stephen Hemminger wrote:
>>> Something in net-next tree broke bridging of virtual nets.
>>> My local VM's can no longer access external networks.
>>>
>>> It is a NAT problem. One of the recent netfilter changes is causing
>>> the packets to not have there source address rewritten.
>>>
>>> I see:
>>>     VM1  -- 192.168.100.0/24 -- HOST -- 192.168.1.0/24 -- ROUTER
>>>                            virbr0    eth0
>>>
>>> Even a simple ping from VM1 doesn't get responded to because
>>> the 192.168.100.X source address is not getting rewritten.
>> I'll try to reproduce it locally. What is the HEAD of the broken
>> tree you're running?
> 
> commit 37ee3d5b3e979a168536e7e2f15bd1e769cb4122
> Author: Patrick McHardy <kaber@trash.net>
> Date:   Thu Feb 18 19:04:44 2010 +0100
> 
>     netfilter: nf_defrag_ipv4: fix compilation error with NF_CONNTRACK=n

This patch should fix it.


[-- Attachment #2: x --]
[-- Type: text/plain, Size: 1085 bytes --]

commit 4bac6b180771f7ef5275b1a6d88e630ca3a3d6f0
Author: Patrick McHardy <kaber@trash.net>
Date:   Fri Feb 19 08:03:28 2010 +0100

    netfilter: restore POST_ROUTING hook in NF_HOOK_COND
    
    Commit 2249065 ("netfilter: get rid of the grossness in netfilter.h")
    inverted the logic for conditional hook invocation, breaking the
    POST_ROUTING hook invoked by ip_output().
    
    Correct the logic and remove an unnecessary initialization.
    
    Reported-by: Stephen Hemminger <shemminger@vyatta.com>
    Signed-off-by: Patrick McHardy <kaber@trash.net>

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 7007945..89341c3 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -212,8 +212,9 @@ NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sk_buff *skb,
 	     struct net_device *in, struct net_device *out,
 	     int (*okfn)(struct sk_buff *), bool cond)
 {
-	int ret = 1;
-	if (cond ||
+	int ret;
+
+	if (!cond ||
 	    (ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN) == 1))
 		ret = okfn(skb);
 	return ret;

^ permalink raw reply related

* Re: NAT regression in next tree
From: Eric Dumazet @ 2010-02-19  7:20 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Stephen Hemminger, David Miller, netdev, netfilter-devel
In-Reply-To: <4B7E386E.4070502@trash.net>

Le vendredi 19 février 2010 à 08:06 +0100, Patrick McHardy a écrit :
> Stephen Hemminger wrote:
> > On Fri, 19 Feb 2010 06:45:43 +0100
> > Patrick McHardy <kaber@trash.net> wrote:
> > 
> >> Stephen Hemminger wrote:
> >>> Something in net-next tree broke bridging of virtual nets.
> >>> My local VM's can no longer access external networks.
> >>>
> >>> It is a NAT problem. One of the recent netfilter changes is causing
> >>> the packets to not have there source address rewritten.
> >>>
> >>> I see:
> >>>     VM1  -- 192.168.100.0/24 -- HOST -- 192.168.1.0/24 -- ROUTER
> >>>                            virbr0    eth0
> >>>
> >>> Even a simple ping from VM1 doesn't get responded to because
> >>> the 192.168.100.X source address is not getting rewritten.
> >> I'll try to reproduce it locally. What is the HEAD of the broken
> >> tree you're running?
> > 
> > commit 37ee3d5b3e979a168536e7e2f15bd1e769cb4122
> > Author: Patrick McHardy <kaber@trash.net>
> > Date:   Thu Feb 18 19:04:44 2010 +0100
> > 
> >     netfilter: nf_defrag_ipv4: fix compilation error with NF_CONNTRACK=n
> 
> This patch should fix it.
> 
> pièce jointe document texte brut (x)
> commit 4bac6b180771f7ef5275b1a6d88e630ca3a3d6f0
> Author: Patrick McHardy <kaber@trash.net>
> Date:   Fri Feb 19 08:03:28 2010 +0100
> 
>     netfilter: restore POST_ROUTING hook in NF_HOOK_COND
>     
>     Commit 2249065 ("netfilter: get rid of the grossness in netfilter.h")
>     inverted the logic for conditional hook invocation, breaking the
>     POST_ROUTING hook invoked by ip_output().
>     
>     Correct the logic and remove an unnecessary initialization.
>     
>     Reported-by: Stephen Hemminger <shemminger@vyatta.com>
>     Signed-off-by: Patrick McHardy <kaber@trash.net>
> 
> diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
> index 7007945..89341c3 100644
> --- a/include/linux/netfilter.h
> +++ b/include/linux/netfilter.h
> @@ -212,8 +212,9 @@ NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sk_buff *skb,
>  	     struct net_device *in, struct net_device *out,
>  	     int (*okfn)(struct sk_buff *), bool cond)
>  {
> -	int ret = 1;
> -	if (cond ||
> +	int ret;
> +
> +	if (!cond ||
>  	    (ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN) == 1))
>  		ret = okfn(skb);
>  	return ret;

I dont quite get it

Original code was :


#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond)                \
({int __ret;                                                                  \
if ((cond) || (__ret = nf_hook_thresh(pf, hook, (skb), indev, outdev, okfn, INT_MIN)) == 1)\
       __ret = (okfn)(skb);                                                   \
__ret;})


There was no condition inversion.



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

^ permalink raw reply

* Re: NAT regression in next tree
From: Patrick McHardy @ 2010-02-19  7:27 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Stephen Hemminger, David Miller, netdev, netfilter-devel
In-Reply-To: <1266564056.2877.15.camel@edumazet-laptop>

Eric Dumazet wrote:
> Le vendredi 19 février 2010 à 08:06 +0100, Patrick McHardy a écrit :
>>     netfilter: restore POST_ROUTING hook in NF_HOOK_COND
>>     
>>     Commit 2249065 ("netfilter: get rid of the grossness in netfilter.h")
>>     inverted the logic for conditional hook invocation, breaking the
>>     POST_ROUTING hook invoked by ip_output().
>>     
>>     Correct the logic and remove an unnecessary initialization.
>>     
>>     Reported-by: Stephen Hemminger <shemminger@vyatta.com>
>>     Signed-off-by: Patrick McHardy <kaber@trash.net>
>>
>> diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
>> index 7007945..89341c3 100644
>> --- a/include/linux/netfilter.h
>> +++ b/include/linux/netfilter.h
>> @@ -212,8 +212,9 @@ NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sk_buff *skb,
>>  	     struct net_device *in, struct net_device *out,
>>  	     int (*okfn)(struct sk_buff *), bool cond)
>>  {
>> -	int ret = 1;
>> -	if (cond ||
>> +	int ret;
>> +
>> +	if (!cond ||
>>  	    (ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN) == 1))
>>  		ret = okfn(skb);
>>  	return ret;
> 
> I dont quite get it
> 
> Original code was :
> 
> 
> #define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond)                \
> ({int __ret;                                                                  \
> if ((cond) || (__ret = nf_hook_thresh(pf, hook, (skb), indev, outdev, okfn, INT_MIN)) == 1)\
>        __ret = (okfn)(skb);                                                   \
> __ret;})
> 
> 
> There was no condition inversion.

Right, I quoted the wrong patch, it was actually broken in
23f3733 ("netfilter: reduce NF_HOOK by one argument"), which
moved the cond check from nf_hook_thresh() to NF_HOOK_COND().
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: linux-next: build failure after final merge (net tree)
From: David Miller @ 2010-02-19  7:33 UTC (permalink / raw)
  To: sfr; +Cc: netdev, linux-next, linux-kernel, kristoffer
In-Reply-To: <20100219173713.e3f9f386.sfr@canb.auug.org.au>

From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Fri, 19 Feb 2010 17:37:13 +1100

> I assume that this driver was written and tested only on Sparc
> ... maybe it should depend on SPARC?

Indeed, it should.  I thought for some reason that all OF
platforms have of_remap() and of_device->resource[], oh
well :-)

Will commit the following, thanks!

net: Make GRETH driver depend on SPARC.

Reported by Stephen Rothwell.

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 17ff15f..46af867 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -997,7 +997,7 @@ config ETHOC
 
 config GRETH
 	tristate "Aeroflex Gaisler GRETH Ethernet MAC support"
-	depends on OF
+	depends on SPARC
 	select PHYLIB
 	select CRC32
 	help
-- 
1.6.6.1

^ permalink raw reply related

* Re: [PATCH] mlx4: replace the dma_sync_single_range_for_cpu/device API
From: FUJITA Tomonori @ 2010-02-19  7:44 UTC (permalink / raw)
  To: davem; +Cc: fujita.tomonori, netdev, rolandd, eli, linux-kernel
In-Reply-To: <adavde35rr9.fsf@roland-alpha.cisco.com>

On Thu, 11 Feb 2010 14:31:22 -0800
Roland Dreier <rdreier@cisco.com> wrote:

>  > > There are only two users of the dma_sync_single_range_for_cpu/device
>  > > API in mainline (mlx4 and ssb). The
>  > > dma_sync_single_range_for_cpu/device API has never been documented and
>  > > the dma_sync_single_for_cpu/device API also support a partial sync.
>  > > 
>  > > This converts mlx4 to use the dma_sync_single_for_cpu/device API
>  > > (preparations for the removal of the dma_sync_single_range_for_cpu/device API).
>  > > 
>  > > Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
>  > 
>  > Acked-by: David S. Miller <davem@davemloft.net>
> 
> Dave, please go ahead and merge this -- this affects the mlx4 ethernet
> driver, so it's your area anyway.

Seems that net-next still doesn't have this. Can you please merge
this?

Thanks,

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox