Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next,1/1] hyperv: Add an error message to rndis_filter_set_device_mac()
From: David Miller @ 2012-11-30 20:03 UTC (permalink / raw)
  To: haiyangz; +Cc: netdev, kys, olaf, jasowang, linux-kernel, devel
In-Reply-To: <1354303421-26149-1-git-send-email-haiyangz@microsoft.com>

From: Haiyang Zhang <haiyangz@microsoft.com>
Date: Fri, 30 Nov 2012 11:23:41 -0800

> This message indicates an error returned from the host when changing MAC address.
> 
> Reported-by: Michal Kubecek <mkubecek@suse.com>
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>

Applied.

^ permalink raw reply

* Re: [PATCH] ipv6: unify logic evaluating inet6_dev's accept_ra property
From: David Miller @ 2012-11-30 20:02 UTC (permalink / raw)
  To: shmulik.ladkani; +Cc: netdev, yoshfuji, tgraf, tore
In-Reply-To: <20121130215113.7a81bc16.shmulik.ladkani@gmail.com>

From: Shmulik Ladkani <shmulik.ladkani@gmail.com>
Date: Fri, 30 Nov 2012 21:51:13 +0200

> BTW the "Not like this" style has many occurrences in net/ipv6.
> One of which was the comment relocated by my patch :-)

Patches to fix this are more than welcome :-)

^ permalink raw reply

* Re: [PATCH] smsc: RFC: Workaround for problems with lan8710 phy auto MDI-X
From: David Miller @ 2012-11-30 20:00 UTC (permalink / raw)
  To: bhutchings; +Cc: jkosina, pt, otavio, javier, chohnstaedt, netdev, linux-kernel
In-Reply-To: <1354302880.2640.1.camel@bwh-desktop.uk.solarflarecom.com>

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Fri, 30 Nov 2012 19:14:40 +0000

> On Fri, 2012-11-30 at 12:23 -0500, David Miller wrote:
>> From: Jiri Kosina <jkosina@suse.cz>
>> Date: Fri, 30 Nov 2012 16:23:30 +0100 (CET)
>> 
>> > Of course it'd be far better if faulty hardware can be autodetected in 
>> > runtime.
>> 
>> That is how this must be handled.
> 
> Well, we also have the recent extension to ETHTOOL_SSET for forcing
> MDI-X on or off.  If it's not possible to detect the faulty hardware
> then the driver can implement this.

Agreed.

^ permalink raw reply

* Re: [PATCH] ipv6: unify logic evaluating inet6_dev's accept_ra property
From: Shmulik Ladkani @ 2012-11-30 19:51 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, yoshfuji, tgraf, tore
In-Reply-To: <20121130.120943.1397811156693287841.davem@davemloft.net>

Hi,

On Fri, 30 Nov 2012 12:09:43 -0500 (EST) David Miller <davem@davemloft.net> wrote:
> From: Shmulik Ladkani <shmulik.ladkani@gmail.com>
> Date: Thu, 29 Nov 2012 11:26:19 +0200
> 
> > +	/*
> > +	 * If forwarding is enabled, RA are not accepted unless the special
> > +	 * hybrid mode (accept_ra=2) is enabled.
> > +	 */
> 
> Please format this comment correctly, in the networking we use
> the style:
> 
> 	/* That looks
> 	 * like this.
> 	 */
> 
> 	/*
> 	 * Not
> 	 * like this.
> 	 */
> 
> Thanks.

Ok. Will amend shortly.

BTW the "Not like this" style has many occurrences in net/ipv6.
One of which was the comment relocated by my patch :-)

Regards,
Shmulik

^ permalink raw reply

* [PATCH v3 net-next] net: move inet_dport/inet_num in sock_common
From: Eric Dumazet @ 2012-11-30 19:49 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Ling Ma, Ben Hutchings, Joe Perches

From: Eric Dumazet <edumazet@google.com>

commit 68835aba4d9b (net: optimize INET input path further)
moved some fields used for tcp/udp sockets lookup in the first cache
line of struct sock_common.

This patch moves inet_dport/inet_num as well, filling a 32bit hole
on 64 bit arches and reducing number of cache line misses in lookups.

Also change INET_MATCH()/INET_TW_MATCH() to perform the ports match
before addresses match, as this check is more discriminant.

Remove the hash check from MATCH() macros because we dont need to
re validate the hash value after taking a refcount on socket, and
use likely/unlikely compiler hints, as the sk_hash/hash check
makes the following conditional tests 100% predicted by cpu.

Introduce skc_addrpair/skc_portpair pair values to better
document the alignment requirements of the port/addr pairs
used in the various MATCH() macros, and remove some casts.

The namespace check can also be done at last.

This slightly improves TCP/UDP lookup times.

IP/TCP early demux needs inet->rx_dst_ifindex and
TCP needs inet->min_ttl, lets group them together in same cache line.

With help from Ben Hutchings & Joe Perches.

Idea of this patch came after Ling Ma proposal to move skc_hash
to the beginning of struct sock_common, and should allow him
to submit a final version of his patch. My tests show an improvement
doing so.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Ben Hutchings <bhutchings@solarflare.com>
Cc: Joe Perches <joe@perches.com>
Cc: Ling Ma <ling.ma.program@gmail.com>
---
v3: fix a typo
    rx_dst_ifindex moves right before min_ttl

 include/linux/ipv6.h             |   32 ++++++++++---------
 include/net/inet_hashtables.h    |   48 +++++++++++++++--------------
 include/net/inet_sock.h          |    8 +++-
 include/net/inet_timewait_sock.h |    7 +++-
 include/net/sock.h               |   25 ++++++++++++---
 net/ipv4/inet_hashtables.c       |   36 +++++++++++++--------
 net/ipv6/inet6_hashtables.c      |   27 +++++++++++-----
 7 files changed, 115 insertions(+), 68 deletions(-)

diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 5e11905..12729e9 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -364,20 +364,22 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk)
 #define inet_v6_ipv6only(__sk)		0
 #endif /* IS_ENABLED(CONFIG_IPV6) */
 
-#define INET6_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif)\
-	(((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net)	&& \
-	 ((*((__portpair *)&(inet_sk(__sk)->inet_dport))) == (__ports)) && \
-	 ((__sk)->sk_family		== AF_INET6)		&& \
-	 ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr))	&& \
-	 ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr))	&& \
-	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-
-#define INET6_TW_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif) \
-	(((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net)	&& \
-	 (*((__portpair *)&(inet_twsk(__sk)->tw_dport)) == (__ports))	&& \
-	 ((__sk)->sk_family	       == PF_INET6)			&& \
-	 (ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_daddr, (__saddr)))	&& \
-	 (ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_rcv_saddr, (__daddr))) && \
-	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
+#define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif)	\
+	((inet_sk(__sk)->inet_portpair == (__ports))		&&	\
+	 ((__sk)->sk_family == AF_INET6)			&&	\
+	 ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr))	&&	\
+	 ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr))	&&	\
+	 (!(__sk)->sk_bound_dev_if	||				\
+	   ((__sk)->sk_bound_dev_if == (__dif))) 		&&	\
+	 net_eq(sock_net(__sk), (__net)))
+
+#define INET6_TW_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif)	   \
+	((inet_twsk(__sk)->tw_portpair == (__ports))			&& \
+	 ((__sk)->sk_family == AF_INET6)				&& \
+	 ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_daddr, (__saddr))	&& \
+	 ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_rcv_saddr, (__daddr)) && \
+	 (!(__sk)->sk_bound_dev_if	||				   \
+	  ((__sk)->sk_bound_dev_if == (__dif)))				&& \
+	 net_eq(sock_net(__sk), (__net)))
 
 #endif /* _IPV6_H */
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 54be028..d1de4fb 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -299,30 +299,34 @@ typedef __u64 __bitwise __addrpair;
 				   (((__force __u64)(__be32)(__daddr)) << 32) | \
 				   ((__force __u64)(__be32)(__saddr)));
 #endif /* __BIG_ENDIAN */
-#define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
-	(((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) &&	\
-	 ((*((__addrpair *)&(inet_sk(__sk)->inet_daddr))) == (__cookie))  &&	\
-	 ((*((__portpair *)&(inet_sk(__sk)->inet_dport))) == (__ports))   &&	\
-	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#define INET_TW_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
-	(((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) &&	\
-	 ((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) &&	\
-	 ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&	\
-	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
+#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif)	\
+	((inet_sk(__sk)->inet_portpair == (__ports))		&&	\
+	 (inet_sk(__sk)->inet_addrpair == (__cookie))		&&	\
+	 (!(__sk)->sk_bound_dev_if	||				\
+	   ((__sk)->sk_bound_dev_if == (__dif))) 		&& 	\
+	 net_eq(sock_net(__sk), (__net)))
+#define INET_TW_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif)\
+	((inet_twsk(__sk)->tw_portpair == (__ports))	&&		\
+	 (inet_twsk(__sk)->tw_addrpair == (__cookie))	&&		\
+	 (!(__sk)->sk_bound_dev_if	||				\
+	   ((__sk)->sk_bound_dev_if == (__dif)))	&&		\
+	 net_eq(sock_net(__sk), (__net)))
 #else /* 32-bit arch */
 #define INET_ADDR_COOKIE(__name, __saddr, __daddr)
-#define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)	\
-	(((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net))	&&	\
-	 (inet_sk(__sk)->inet_daddr	== (__saddr))		&&	\
-	 (inet_sk(__sk)->inet_rcv_saddr	== (__daddr))		&&	\
-	 ((*((__portpair *)&(inet_sk(__sk)->inet_dport))) == (__ports))	&&	\
-	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#define INET_TW_MATCH(__sk, __net, __hash,__cookie, __saddr, __daddr, __ports, __dif)	\
-	(((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net))	&&	\
-	 (inet_twsk(__sk)->tw_daddr	== (__saddr))		&&	\
-	 (inet_twsk(__sk)->tw_rcv_saddr	== (__daddr))		&&	\
-	 ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&	\
-	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
+#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \
+	((inet_sk(__sk)->inet_portpair == (__ports))	&&		\
+	 (inet_sk(__sk)->inet_daddr	== (__saddr))	&&		\
+	 (inet_sk(__sk)->inet_rcv_saddr	== (__daddr))	&&		\
+	 (!(__sk)->sk_bound_dev_if	||				\
+	   ((__sk)->sk_bound_dev_if == (__dif))) 	&&		\
+	 net_eq(sock_net(__sk), (__net)))
+#define INET_TW_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \
+	((inet_twsk(__sk)->tw_portpair == (__ports))	&&		\
+	 (inet_twsk(__sk)->tw_daddr	== (__saddr))	&&		\
+	 (inet_twsk(__sk)->tw_rcv_saddr	== (__daddr))	&&		\
+	 (!(__sk)->sk_bound_dev_if	||				\
+	   ((__sk)->sk_bound_dev_if == (__dif))) 	&&		\
+	 net_eq(sock_net(__sk), (__net)))
 #endif /* 64-bit arch */
 
 /*
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 256c1ed..a4196cb 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -144,9 +144,11 @@ struct inet_sock {
 	/* Socket demultiplex comparisons on incoming packets. */
 #define inet_daddr		sk.__sk_common.skc_daddr
 #define inet_rcv_saddr		sk.__sk_common.skc_rcv_saddr
+#define inet_addrpair		sk.__sk_common.skc_addrpair
+#define inet_dport		sk.__sk_common.skc_dport
+#define inet_num		sk.__sk_common.skc_num
+#define inet_portpair		sk.__sk_common.skc_portpair
 
-	__be16			inet_dport;
-	__u16			inet_num;
 	__be32			inet_saddr;
 	__s16			uc_ttl;
 	__u16			cmsg_flags;
@@ -154,6 +156,7 @@ struct inet_sock {
 	__u16			inet_id;
 
 	struct ip_options_rcu __rcu	*inet_opt;
+	int			rx_dst_ifindex;
 	__u8			tos;
 	__u8			min_ttl;
 	__u8			mc_ttl;
@@ -170,7 +173,6 @@ struct inet_sock {
 	int			uc_index;
 	int			mc_index;
 	__be32			mc_addr;
-	int			rx_dst_ifindex;
 	struct ip_mc_socklist __rcu	*mc_list;
 	struct inet_cork_full	cork;
 };
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index ba52c83..7d658d5 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -112,6 +112,11 @@ struct inet_timewait_sock {
 #define tw_net			__tw_common.skc_net
 #define tw_daddr        	__tw_common.skc_daddr
 #define tw_rcv_saddr    	__tw_common.skc_rcv_saddr
+#define tw_addrpair		__tw_common.skc_addrpair
+#define tw_dport		__tw_common.skc_dport
+#define tw_num			__tw_common.skc_num
+#define tw_portpair		__tw_common.skc_portpair
+
 	int			tw_timeout;
 	volatile unsigned char	tw_substate;
 	unsigned char		tw_rcv_wscale;
@@ -119,8 +124,6 @@ struct inet_timewait_sock {
 	/* Socket demultiplex comparisons on incoming packets. */
 	/* these three are in inet_sock */
 	__be16			tw_sport;
-	__be16			tw_dport;
-	__u16			tw_num;
 	kmemcheck_bitfield_begin(flags);
 	/* And these are ours. */
 	unsigned int		tw_ipv6only     : 1,
diff --git a/include/net/sock.h b/include/net/sock.h
index c945fba..c4132c1 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -132,6 +132,8 @@ struct net;
  *	@skc_rcv_saddr: Bound local IPv4 addr
  *	@skc_hash: hash value used with various protocol lookup tables
  *	@skc_u16hashes: two u16 hash values used by UDP lookup tables
+ *	@skc_dport: placeholder for inet_dport/tw_dport
+ *	@skc_num: placeholder for inet_num/tw_num
  *	@skc_family: network address family
  *	@skc_state: Connection state
  *	@skc_reuse: %SO_REUSEADDR setting
@@ -149,16 +151,29 @@ struct net;
  *	for struct sock and struct inet_timewait_sock.
  */
 struct sock_common {
-	/* skc_daddr and skc_rcv_saddr must be grouped :
-	 * cf INET_MATCH() and INET_TW_MATCH()
+	/* skc_daddr and skc_rcv_saddr must be grouped on a 8 bytes aligned
+	 * address on 64bit arches : cf INET_MATCH() and INET_TW_MATCH()
 	 */
-	__be32			skc_daddr;
-	__be32			skc_rcv_saddr;
-
+	union {
+		unsigned long	skc_addrpair;
+		struct {
+			__be32	skc_daddr;
+			__be32	skc_rcv_saddr;
+		};
+	};
 	union  {
 		unsigned int	skc_hash;
 		__u16		skc_u16hashes[2];
 	};
+	/* skc_dport && skc_num must be grouped as well */
+	union {
+		u32		skc_portpair;
+		struct {
+			__be16	skc_dport;
+			__u16	skc_num;
+		};
+	};
+
 	unsigned short		skc_family;
 	volatile unsigned char	skc_state;
 	unsigned char		skc_reuse;
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 7880af9..fa3ae81 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -237,12 +237,14 @@ struct sock *__inet_lookup_established(struct net *net,
 	rcu_read_lock();
 begin:
 	sk_nulls_for_each_rcu(sk, node, &head->chain) {
-		if (INET_MATCH(sk, net, hash, acookie,
-					saddr, daddr, ports, dif)) {
+		if (sk->sk_hash != hash)
+			continue;
+		if (likely(INET_MATCH(sk, net, acookie,
+				      saddr, daddr, ports, dif))) {
 			if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt)))
 				goto begintw;
-			if (unlikely(!INET_MATCH(sk, net, hash, acookie,
-				saddr, daddr, ports, dif))) {
+			if (unlikely(!INET_MATCH(sk, net, acookie,
+						 saddr, daddr, ports, dif))) {
 				sock_put(sk);
 				goto begin;
 			}
@@ -260,14 +262,18 @@ begin:
 begintw:
 	/* Must check for a TIME_WAIT'er before going to listener hash. */
 	sk_nulls_for_each_rcu(sk, node, &head->twchain) {
-		if (INET_TW_MATCH(sk, net, hash, acookie,
-					saddr, daddr, ports, dif)) {
+		if (sk->sk_hash != hash)
+			continue;
+		if (likely(INET_TW_MATCH(sk, net, acookie,
+					 saddr, daddr, ports,
+					 dif))) {
 			if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) {
 				sk = NULL;
 				goto out;
 			}
-			if (unlikely(!INET_TW_MATCH(sk, net, hash, acookie,
-				 saddr, daddr, ports, dif))) {
+			if (unlikely(!INET_TW_MATCH(sk, net, acookie,
+						    saddr, daddr, ports,
+						    dif))) {
 				sock_put(sk);
 				goto begintw;
 			}
@@ -314,10 +320,12 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
 
 	/* Check TIME-WAIT sockets first. */
 	sk_nulls_for_each(sk2, node, &head->twchain) {
-		tw = inet_twsk(sk2);
+		if (sk2->sk_hash != hash)
+			continue;
 
-		if (INET_TW_MATCH(sk2, net, hash, acookie,
-					saddr, daddr, ports, dif)) {
+		if (likely(INET_TW_MATCH(sk2, net, acookie,
+					 saddr, daddr, ports, dif))) {
+			tw = inet_twsk(sk2);
 			if (twsk_unique(sk, sk2, twp))
 				goto unique;
 			else
@@ -328,8 +336,10 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
 
 	/* And established part... */
 	sk_nulls_for_each(sk2, node, &head->chain) {
-		if (INET_MATCH(sk2, net, hash, acookie,
-					saddr, daddr, ports, dif))
+		if (sk2->sk_hash != hash)
+			continue;
+		if (likely(INET_MATCH(sk2, net, acookie,
+				      saddr, daddr, ports, dif)))
 			goto not_unique;
 	}
 
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 73f1a00..dea17fd 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -87,11 +87,13 @@ struct sock *__inet6_lookup_established(struct net *net,
 	rcu_read_lock();
 begin:
 	sk_nulls_for_each_rcu(sk, node, &head->chain) {
-		/* For IPV6 do the cheaper port and family tests first. */
-		if (INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) {
+		if (sk->sk_hash != hash)
+			continue;
+		if (likely(INET6_MATCH(sk, net, saddr, daddr, ports, dif))) {
 			if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt)))
 				goto begintw;
-			if (!INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) {
+			if (unlikely(!INET6_MATCH(sk, net, saddr, daddr,
+						  ports, dif))) {
 				sock_put(sk);
 				goto begin;
 			}
@@ -104,12 +106,16 @@ begin:
 begintw:
 	/* Must check for a TIME_WAIT'er before going to listener hash. */
 	sk_nulls_for_each_rcu(sk, node, &head->twchain) {
-		if (INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) {
+		if (sk->sk_hash != hash)
+			continue;
+		if (likely(INET6_TW_MATCH(sk, net, saddr, daddr,
+					  ports, dif))) {
 			if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) {
 				sk = NULL;
 				goto out;
 			}
-			if (!INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) {
+			if (unlikely(!INET6_TW_MATCH(sk, net, saddr, daddr,
+						     ports, dif))) {
 				sock_put(sk);
 				goto begintw;
 			}
@@ -236,9 +242,12 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
 
 	/* Check TIME-WAIT sockets first. */
 	sk_nulls_for_each(sk2, node, &head->twchain) {
-		tw = inet_twsk(sk2);
+		if (sk2->sk_hash != hash)
+			continue;
 
-		if (INET6_TW_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) {
+		if (likely(INET6_TW_MATCH(sk2, net, saddr, daddr,
+					  ports, dif))) {
+			tw = inet_twsk(sk2);
 			if (twsk_unique(sk, sk2, twp))
 				goto unique;
 			else
@@ -249,7 +258,9 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
 
 	/* And established part... */
 	sk_nulls_for_each(sk2, node, &head->chain) {
-		if (INET6_MATCH(sk2, net, hash, saddr, daddr, ports, dif))
+		if (sk2->sk_hash != hash)
+			continue;
+		if (likely(INET6_MATCH(sk2, net, saddr, daddr, ports, dif)))
 			goto not_unique;
 	}
 

^ permalink raw reply related

* RE: [PATCH] [trivial] wireless: mwifiex: Fix typo in wireless/mwifiex driver
From: Bing Zhao @ 2012-11-30 19:30 UTC (permalink / raw)
  To: Masanari Iida, linux-wireless@vger.kernel.org, trivial@kernel.org,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <1354280911-4866-1-git-send-email-standby24x7@gmail.com>

Hi Masanari,

Thanks for your patch.

> Subject: [PATCH] [trivial] wireless: mwifiex: Fix typo in wireless/mwifiex driver
> 
> Correct spelling typo in wireless/mwifiex driver.
> 
> Signed-off-by: Masanari Iida <standby24x7@gmail.com>

Acked-by: Bing Zhao <bzhao@marvell.com>

Regards,
Bing

> ---
>  drivers/net/wireless/mwifiex/sta_ioctl.c | 2 +-
>  drivers/net/wireless/mwifiex/usb.c       | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
> index 552d72e..21035e6 100644
> --- a/drivers/net/wireless/mwifiex/sta_ioctl.c
> +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
> @@ -463,7 +463,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
>  	}
> 
>  	if (adapter->hs_activated) {
> -		dev_dbg(adapter->dev, "cmd: HS Already actived\n");
> +		dev_dbg(adapter->dev, "cmd: HS Already activated\n");
>  		return true;
>  	}
> 
> diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
> index 22a5916..5eb3b33 100644
> --- a/drivers/net/wireless/mwifiex/usb.c
> +++ b/drivers/net/wireless/mwifiex/usb.c
> @@ -351,7 +351,7 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
>  	card->udev = udev;
>  	card->intf = intf;
> 
> -	pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocl=%#x\n",
> +	pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n",
>  		 udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass,
>  		 udev->descriptor.bDeviceSubClass,
>  		 udev->descriptor.bDeviceProtocol);
> --
> 1.8.0.1.347.gf94c325

^ permalink raw reply

* [PATCH net-next, 1/1] hyperv: Add an error message to rndis_filter_set_device_mac()
From: Haiyang Zhang @ 2012-11-30 19:23 UTC (permalink / raw)
  To: davem, netdev; +Cc: olaf, jasowang, linux-kernel, devel, haiyangz

This message indicates an error returned from the host when changing MAC address.

Reported-by: Michal Kubecek <mkubecek@suse.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>

---
 drivers/net/hyperv/rndis_filter.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 7fdeb52..2b657d4 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -605,8 +605,11 @@ int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac)
 		return -EBUSY;
 	} else {
 		set_complete = &request->response_msg.msg.set_complete;
-		if (set_complete->status != RNDIS_STATUS_SUCCESS)
+		if (set_complete->status != RNDIS_STATUS_SUCCESS) {
+			netdev_err(ndev, "Fail to set MAC on host side:0x%x\n",
+				   set_complete->status);
 			ret = -EINVAL;
+		}
 	}
 
 cleanup:
-- 
1.7.4.1

^ permalink raw reply related

* Re: [PATCH] smsc: RFC: Workaround for problems with lan8710 phy auto MDI-X
From: Ben Hutchings @ 2012-11-30 19:14 UTC (permalink / raw)
  To: David Miller
  Cc: jkosina, pt, otavio, javier, chohnstaedt, netdev, linux-kernel
In-Reply-To: <20121130.122302.1825816242500143123.davem@davemloft.net>

On Fri, 2012-11-30 at 12:23 -0500, David Miller wrote:
> From: Jiri Kosina <jkosina@suse.cz>
> Date: Fri, 30 Nov 2012 16:23:30 +0100 (CET)
> 
> > Of course it'd be far better if faulty hardware can be autodetected in 
> > runtime.
> 
> That is how this must be handled.

Well, we also have the recent extension to ETHTOOL_SSET for forcing
MDI-X on or off.  If it's not possible to detect the faulty hardware
then the driver can implement this.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: iputils: ping -I <iface>
From: Ben Greear @ 2012-11-30 19:11 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki; +Cc: Jan Synacek, netdev
In-Reply-To: <50B90326.2010302@linux-ipv6.org>

On 11/30/2012 11:04 AM, YOSHIFUJI Hideaki wrote:
> (2012年11月30日 15:06), Jan Synacek wrote:
>> On 11/29/2012 08:48 PM, Ben Greear wrote:
>>> On 11/29/2012 06:12 AM, Jan Synacek wrote:
>>>> Hello,
>>>>
>>>> There seems to be a bug(?) when calling ping with -I lo:
>>>>
>>>> $ ping -I lo kernel.org
>>>>
>>>> PING kernel.org (149.20.4.69) from 192.168.1.10 lo: 56(84) bytes of data.
>>>> ^C
>>>>
>>>> Note that 192.168.1.10 is my primary interface's address (em1). However, no
>>>> replies are coming back.
>>>>
>>>> $ ping -I em1 kernel.org
>>>>
>>>> PING kernel.org (149.20.4.69) from 192.168.1.10 em1: 56(84) bytes of data.
>>>> 64 bytes from pub2.kernel.org (149.20.4.69): icmp_seq=1 ttl=42 time=202 ms
>>>> 64 bytes from pub2.kernel.org (149.20.4.69): icmp_seq=2 ttl=42 time=187 ms
>>>> ^C
>>>>
>>>> Works as expected.
>>>>
>>>> I know that binding to loopback probably doesn't make much sense, but I think
>>>> that ping should be able to cope with that.
>>>
>>> I think it would be wrong if ping worked as you suggest.  Binding to an
>>> interface means use that interface as the source of your packets, and having
>>> it bind hard helps when using systems with multiple NICs on same subnet
>>> (or possibly, same IP).
>>
>> I just wanted to point out that if I call ping with -I lo, its 'from' address is
>> wrong (in my case 192.168.1.10) and nothing happens (that's, I guess, expected
>> if it really bound to loopback). If I call ping with the -I <the same address>
>> or -I em1 (the same address again), it works as expected. I'm sorry if I wasn't
>> clear enough.
>>
>>>
>>>> Also, it would be nice to mention the difference between -I <ip> and -I <iface>
>>>> in the manpage.
>>>
>>> In my opinion, -I <iface> should use SO_BINDTODEVICE, but at least in
>>> older versions of ping it did not.
>>
>> Ping does use SO_BINDTODEVICE.
>
> So far, -I device is related to source address selection (using
> SO_BINDTODEVICE) and outgoing device (using in_pktinfo).
> On the other hand, -I addr is, in fact, related to source
> address selection (and it is enfoced by bind), only.
>
> Something like this:
>
>         -I interface
>                interface is either an address, or an interface name.  If
>                interface is an address, it sets source address to
>                specified interface address.   If  interface
>                in  an  interface name, it tells the command to use that
>                interface.  For ping6, when doing ping to a link-local
>                scope address, link specification (by the
>                '%'-notation in destination, or by this option) is
>                required.
>
> BUT, even with -I device, net/ipv4/dev_inet.c:inet_select_addr()
> may select an address from other interfaces, AFAIK).
>
> Should we check if the selected source address blongs to the actual
> device?

Maybe have -D <iface-name> and -P <source-address>
options?

Where -D uses SO_BINDTODEVICE, and -P binds to a source IP?

Would have to keep the -I logic similar to what it does now for
backwards compatibility...

Thanks,
Ben

>
> --yoshfuji
>


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply

* Re: pull request: wireless 2012-11-30
From: John W. Linville @ 2012-11-30 19:07 UTC (permalink / raw)
  To: David Miller; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20121130.134018.1859855439413083920.davem@davemloft.net>

On Fri, Nov 30, 2012 at 01:40:18PM -0500, David Miller wrote:
> From: "John W. Linville" <linville@tuxdriver.com>
> Date: Fri, 30 Nov 2012 13:25:00 -0500
> 
> > I have a couple of stragglers intended for 3.7...
> > 
> > The iwlwifi patch fixes a bug in CCK basic rate calculations.
> > 
> > The mac80211 patch removes an unnecessary function call that was
> > generating a lot of log SPAM.
> 
> Pulled, thanks John.
> 
> I want to warn you ahead of time that these might not make it.

Yes, I suspect that might be the case -- but it won't make it if I
don't send it... :-)

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: iputils: ping -I <iface>
From: YOSHIFUJI Hideaki @ 2012-11-30 19:04 UTC (permalink / raw)
  To: Jan Synacek; +Cc: Ben Greear, netdev, YOSHIFUJI Hideaki
In-Reply-To: <50B84CCB.7000502@redhat.com>

(2012年11月30日 15:06), Jan Synacek wrote:
> On 11/29/2012 08:48 PM, Ben Greear wrote:
>> On 11/29/2012 06:12 AM, Jan Synacek wrote:
>>> Hello,
>>>
>>> There seems to be a bug(?) when calling ping with -I lo:
>>>
>>> $ ping -I lo kernel.org
>>>
>>> PING kernel.org (149.20.4.69) from 192.168.1.10 lo: 56(84) bytes of data.
>>> ^C
>>>
>>> Note that 192.168.1.10 is my primary interface's address (em1). However, no
>>> replies are coming back.
>>>
>>> $ ping -I em1 kernel.org
>>>
>>> PING kernel.org (149.20.4.69) from 192.168.1.10 em1: 56(84) bytes of data.
>>> 64 bytes from pub2.kernel.org (149.20.4.69): icmp_seq=1 ttl=42 time=202 ms
>>> 64 bytes from pub2.kernel.org (149.20.4.69): icmp_seq=2 ttl=42 time=187 ms
>>> ^C
>>>
>>> Works as expected.
>>>
>>> I know that binding to loopback probably doesn't make much sense, but I think
>>> that ping should be able to cope with that.
>>
>> I think it would be wrong if ping worked as you suggest.  Binding to an
>> interface means use that interface as the source of your packets, and having
>> it bind hard helps when using systems with multiple NICs on same subnet
>> (or possibly, same IP).
> 
> I just wanted to point out that if I call ping with -I lo, its 'from' address is
> wrong (in my case 192.168.1.10) and nothing happens (that's, I guess, expected
> if it really bound to loopback). If I call ping with the -I <the same address>
> or -I em1 (the same address again), it works as expected. I'm sorry if I wasn't
> clear enough.
> 
>>
>>> Also, it would be nice to mention the difference between -I <ip> and -I <iface>
>>> in the manpage.
>>
>> In my opinion, -I <iface> should use SO_BINDTODEVICE, but at least in
>> older versions of ping it did not.
> 
> Ping does use SO_BINDTODEVICE.

So far, -I device is related to source address selection (using
SO_BINDTODEVICE) and outgoing device (using in_pktinfo).
On the other hand, -I addr is, in fact, related to source
address selection (and it is enfoced by bind), only.

Something like this:

       -I interface
              interface is either an address, or an interface name.  If
              interface is an address, it sets source address to
              specified interface address.   If  interface
              in  an  interface name, it tells the command to use that
              interface.  For ping6, when doing ping to a link-local
              scope address, link specification (by the
              '%'-notation in destination, or by this option) is
              required.

BUT, even with -I device, net/ipv4/dev_inet.c:inet_select_addr()
may select an address from other interfaces, AFAIK).

Should we check if the selected source address blongs to the actual
device?

--yoshfuji

^ permalink raw reply

* Re: [PATCH] MAINTAINERS: fix bouncing tun/tap entries
From: Max Krasnyansky @ 2012-11-30 18:52 UTC (permalink / raw)
  To: David Miller; +Cc: jslaby, netdev, jirislaby, linux-kernel
In-Reply-To: <20121130.122813.1136966656907114890.davem@davemloft.net>

On 11/30/2012 09:28 AM, David Miller wrote:
> From: Jiri Slaby <jslaby@suse.cz>
> Date: Fri, 30 Nov 2012 18:05:40 +0100
> 
>> Delivery to the following recipient failed permanently:
>>
>>      vtun@office.satix.net
>>
>> Technical details of permanent failure:
>> DNS Error: Domain name not found
>>
>> Of course:
>> $ host office.satix.net
>> Host office.satix.net not found: 3(NXDOMAIN)
>>
>> ===========
>>
>> And "Change of Email Address Notification":
>> Old Address        New Address           Email Subject
>> ------------------------------------------------------
>> maxk@qualcomm.com  maxk@qti.qualcomm.com "tuntap: multiqueue...
>>
>> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> 
> Applied.
> 

Thanks for fixing that guys.

Max

^ permalink raw reply

* Re: [PATCH v3 resend net-next 0/2] myri10ge: LRO to GRO conversion
From: Andrew Gallatin @ 2012-11-30 18:50 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20121130.134438.1284316376841704382.davem@davemloft.net>

On 11/30/12 13:44, David Miller wrote:
> From: Andrew Gallatin <gallatin@myri.com>
> Date: Fri, 30 Nov 2012 13:31:57 -0500
> 
>> I'm resending this after fixing email client issues.
> 
> Applied, thanks.
> 

Thank you.

I also want to apologize for making so many beginner mistakes,
and to thank you for your patience with me.  There has usually
been somebody more "plugged in" to the linux community that
has submitted patches for us in the past, so I'm just not used
to doing it yet.

Thanks again,

Drew

^ permalink raw reply

* Re: ip6_rt_gc_elasticity and ip6_rt_gc_min_interval race in rt6_alloc_cow() ?
From: David Miller @ 2012-11-30 18:50 UTC (permalink / raw)
  To: jbohac; +Cc: netdev, mkubecek
In-Reply-To: <20121130184336.GB7113@midget.suse.cz>

From: Jiri Bohac <jbohac@suse.cz>
Date: Fri, 30 Nov 2012 19:43:36 +0100

> I believe there is a race condition in the setting of
> ip6_rt_gc_elasticity and ip6_rt_gc_min_interval. I have not seen
> happen, though:
> 
> 1) a setting made by the user via sysctl while ip6_dst_gc() is
>    running will get lost
> 
> 2) another instance of rt6_alloc_cow() may save the temporary
>    values in the saved_* variables, making those permanent.
> 
> Am I overlooking some synchronization or should I send a
> patch to fix this?

The ipv4 routing cache had the same issue, I really and sincerely
doubt this race matters in practice.

^ permalink raw reply

* Re: [PATCH] Smack: Add missing depends on INET in Kconfig
From: Casey Schaufler @ 2012-11-30 18:47 UTC (permalink / raw)
  To: David Miller
  Cc: rdunlap, paul, sfr, linux-next, linux-kernel, netdev,
	linux-security-module
In-Reply-To: <20121130.134326.730429492162984746.davem@davemloft.net>

On 11/30/2012 10:43 AM, David Miller wrote:
> From: Randy Dunlap <rdunlap@xenotime.net>
> Date: Fri, 30 Nov 2012 09:40:09 -0800
>
>> On 11/30/2012 09:28 AM, Casey Schaufler wrote:
>>
>>> Because NETLABEL depends on INET SECURITY_SMACK
>>> has to explicitly call out the dependency.
>>>
>>> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
>>
>> Acked-by: Randy Dunlap <rdunlap@xenotime.net>
>>
>> Thanks for the quick fix.
> In what tree does this Kconfig file look like this?

James Morris' security-next

>
> In my net-next tree the current dependencies are expressed as:
>
> 	depends on NETLABEL && SECURITY_NETWORK
>

^ permalink raw reply

* Re: [PATCH v3 resend net-next 0/2] myri10ge: LRO to GRO conversion
From: David Miller @ 2012-11-30 18:44 UTC (permalink / raw)
  To: gallatin; +Cc: netdev
In-Reply-To: <1354300319-30771-1-git-send-email-gallatin@myri.com>

From: Andrew Gallatin <gallatin@myri.com>
Date: Fri, 30 Nov 2012 13:31:57 -0500

> I'm resending this after fixing email client issues.

Applied, thanks.

^ permalink raw reply

* Re: [PATCH] Smack: Add missing depends on INET in Kconfig
From: Paul Moore @ 2012-11-30 18:43 UTC (permalink / raw)
  To: Randy Dunlap, Casey Schaufler
  Cc: Stephen Rothwell, linux-next, linux-kernel,
	netdev@vger.kernel.org, linux-security-module
In-Reply-To: <50B8EF79.4080907@xenotime.net>

On Friday, November 30, 2012 09:40:09 AM Randy Dunlap wrote:
> On 11/30/2012 09:28 AM, Casey Schaufler wrote:
> > Because NETLABEL depends on INET SECURITY_SMACK
> > has to explicitly call out the dependency.
> > 
> > Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> 
> Acked-by: Randy Dunlap <rdunlap@xenotime.net>
> 
> Thanks for the quick fix.

+1

Thanks Casey.

> > ---
> > 
> >  security/smack/Kconfig |    1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/security/smack/Kconfig b/security/smack/Kconfig
> > index 9fb14ef..1be1088 100644
> > --- a/security/smack/Kconfig
> > +++ b/security/smack/Kconfig
> > @@ -1,5 +1,6 @@
> > 
> >  config SECURITY_SMACK
> >  
> >  	bool "Simplified Mandatory Access Control Kernel Support"
> > 
> > +	depends on INET
> > 
> >  	depends on NET
> >  	depends on SECURITY
> >  	select NETLABEL
> > 
> > --
-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* ip6_rt_gc_elasticity and ip6_rt_gc_min_interval race in rt6_alloc_cow() ?
From: Jiri Bohac @ 2012-11-30 18:43 UTC (permalink / raw)
  To: netdev; +Cc: mkubecek

Hi,

I came across this code in rt6_alloc_cow():


	if (rt6_bind_neighbour(rt, rt->dst.dev)) {
		struct net *net = dev_net(rt->dst.dev);
		int saved_rt_min_interval =
			net->ipv6.sysctl.ip6_rt_gc_min_interval;
		int saved_rt_elasticity =
			net->ipv6.sysctl.ip6_rt_gc_elasticity;

		if (attempts-- > 0) {
			net->ipv6.sysctl.ip6_rt_gc_elasticity = 1;
			net->ipv6.sysctl.ip6_rt_gc_min_interval = 0;

			ip6_dst_gc(&net->ipv6.ip6_dst_ops);

			net->ipv6.sysctl.ip6_rt_gc_elasticity =
				saved_rt_elasticity;
			net->ipv6.sysctl.ip6_rt_gc_min_interval =
				saved_rt_min_interval;
			goto retry;
		}

		net_warn_ratelimited("Neighbour table overflow\n");
		dst_free(&rt->dst);
		return NULL;
	}

I believe there is a race condition in the setting of
ip6_rt_gc_elasticity and ip6_rt_gc_min_interval. I have not seen
happen, though:

1) a setting made by the user via sysctl while ip6_dst_gc() is
   running will get lost

2) another instance of rt6_alloc_cow() may save the temporary
   values in the saved_* variables, making those permanent.

Am I overlooking some synchronization or should I send a
patch to fix this?


Thanks,


-- 
Jiri Bohac <jbohac@suse.cz>
SUSE Labs, SUSE CZ

^ permalink raw reply

* Re: [PATCH] Smack: Add missing depends on INET in Kconfig
From: David Miller @ 2012-11-30 18:43 UTC (permalink / raw)
  To: rdunlap
  Cc: casey, paul, sfr, linux-next, linux-kernel, netdev,
	linux-security-module
In-Reply-To: <50B8EF79.4080907@xenotime.net>

From: Randy Dunlap <rdunlap@xenotime.net>
Date: Fri, 30 Nov 2012 09:40:09 -0800

> On 11/30/2012 09:28 AM, Casey Schaufler wrote:
> 
>> Because NETLABEL depends on INET SECURITY_SMACK
>> has to explicitly call out the dependency.
>> 
>> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> 
> 
> Acked-by: Randy Dunlap <rdunlap@xenotime.net>
> 
> Thanks for the quick fix.

In what tree does this Kconfig file look like this?

In my net-next tree the current dependencies are expressed as:

	depends on NETLABEL && SECURITY_NETWORK

^ permalink raw reply

* Re: pull request: wireless 2012-11-30
From: David Miller @ 2012-11-30 18:40 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20121130182459.GB2355@tuxdriver.com>

From: "John W. Linville" <linville@tuxdriver.com>
Date: Fri, 30 Nov 2012 13:25:00 -0500

> I have a couple of stragglers intended for 3.7...
> 
> The iwlwifi patch fixes a bug in CCK basic rate calculations.
> 
> The mac80211 patch removes an unnecessary function call that was
> generating a lot of log SPAM.

Pulled, thanks John.

I want to warn you ahead of time that these might not make it.

^ permalink raw reply

* [PATCH v3 resend net-next 2/2] myri10ge: Add vlan rx for better GRO perf.
From: Andrew Gallatin @ 2012-11-30 18:31 UTC (permalink / raw)
  To: davem; +Cc: netdev, Andrew Gallatin
In-Reply-To: <1354300319-30771-1-git-send-email-gallatin@myri.com>

Unlike LRO, GRO requires that vlan tags be removed before
aggregation can occur.  Since the myri10ge NIC does not support
hardware vlan tag offload, we must remove the tag in the driver
to achieve performance comparable to LRO for vlan tagged frames.

Thanks to Eric Duzamet for his help simplifying the original patch.

Signed-off-by: Andrew Gallatin <gallatin@myri.com>
---
 drivers/net/ethernet/myricom/myri10ge/myri10ge.c |   41 ++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 84207c0..2fc984a 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -1264,6 +1264,42 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,
 	}
 }
 
+/*
+ * GRO does not support acceleration of tagged vlan frames, and
+ * this NIC does not support vlan tag offload, so we must pop
+ * the tag ourselves to be able to achieve GRO performance that
+ * is comparable to LRO.
+ */
+
+static inline void
+myri10ge_vlan_rx(struct net_device *dev, void *addr, struct sk_buff *skb)
+{
+	u8 *va;
+	struct vlan_ethhdr *veh;
+	struct skb_frag_struct *frag;
+	__wsum vsum;
+
+	va = addr;
+	va += MXGEFW_PAD;
+	veh = (struct vlan_ethhdr *)va;
+	if ((dev->features & NETIF_F_HW_VLAN_RX) == NETIF_F_HW_VLAN_RX &&
+	    veh->h_vlan_proto == ntohs(ETH_P_8021Q)) {
+		/* fixup csum if needed */
+		if (skb->ip_summed == CHECKSUM_COMPLETE) {
+			vsum = csum_partial(va + ETH_HLEN, VLAN_HLEN, 0);
+			skb->csum = csum_sub(skb->csum, vsum);
+		}
+		/* pop tag */
+		__vlan_hwaccel_put_tag(skb, ntohs(veh->h_vlan_TCI));
+		memmove(va + VLAN_HLEN, va, 2 * ETH_ALEN);
+		skb->len -= VLAN_HLEN;
+		skb->data_len -= VLAN_HLEN;
+		frag = skb_shinfo(skb)->frags;
+		frag->page_offset += VLAN_HLEN;
+		skb_frag_size_set(frag, skb_frag_size(frag) - VLAN_HLEN);
+	}
+}
+
 static inline int
 myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum)
 {
@@ -1326,6 +1362,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum)
 		skb->ip_summed = CHECKSUM_COMPLETE;
 		skb->csum = csum;
 	}
+	myri10ge_vlan_rx(mgp->dev, va, skb);
 	skb_record_rx_queue(skb, ss - &mgp->ss[0]);
 
 	napi_gro_frags(&ss->napi);
@@ -3851,6 +3888,10 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->netdev_ops = &myri10ge_netdev_ops;
 	netdev->mtu = myri10ge_initial_mtu;
 	netdev->hw_features = mgp->features | NETIF_F_RXCSUM;
+
+	/* fake NETIF_F_HW_VLAN_RX for good GRO performance */
+	netdev->hw_features |= NETIF_F_HW_VLAN_RX;
+
 	netdev->features = netdev->hw_features;
 
 	if (dac_enabled)
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 resend net-next 0/2] myri10ge: LRO to GRO conversion
From: Andrew Gallatin @ 2012-11-30 18:31 UTC (permalink / raw)
  To: davem; +Cc: netdev, Andrew Gallatin
In-Reply-To: <20121130.121705.1923519039781698493.davem@davemloft.net>

Hi,

I'm resending this after fixing email client issues.

The following patchset is a resubmission of '[PATCH resend net-next 0/3]
myri10ge: LRO to GRO conversion', and converts myri10ge from using
the old inet_lro interface to GRO, and to do vlan tag decap in
the driver so as to not suffer a performance penalty for vlan
tagged traffic due to the conversion.

Changes this time are:

- Clean up some messy indenting & parens in
  "2/3 myri10ge-Add-vlan-rx-for-better-GRO-perf"
  and store the vlan hdr csum in a variable, so now we are not calling
  csum_partial() nested so deeply it spreads across 3 lines

- Folded 3/3 myri10ge-Use-skb_fill_page_desc into 1/3
  myri10ge-Convert-from-LRO-to-GRO.patch since it is really just small
  part of the LRO removal cleanup.  It was originally a separate patch
  because I noticed the cleanup at the last second, and was too lazy
  to fold it into the first patch where it belonged.

Note that a naive LRO->GRO conversion of myri10ge will result in a
performance regression for vlan tagged frames.  This is because
myri10ge does not offer hardware vlan tag offload, and because GRO
requires hardware vlan tag offload to aggregate vlan tagged frames.

To address this performance regression, I have implemented vlan tag
popping in the myri10ge driver, as it seems to be the lesser of two
evils.  As eric.dumazet@gmail.com commented when I asked about this on
netdev: "Given GRO assumes NIC does hardware vlan
offloading, I guess I would chose to do that.  It seems unfortunate to
add vlan decap in GRO path, already very complex." 

Andrew Gallatin (2):
  myri10ge: Convert from LRO to GRO
  myri10ge: Add vlan rx for better GRO perf.

 drivers/net/ethernet/myricom/Kconfig             |    1 -
 drivers/net/ethernet/myricom/myri10ge/myri10ge.c |  275 ++++++----------------
 2 files changed, 74 insertions(+), 202 deletions(-)

-- 
1.7.9.5

^ permalink raw reply

* [PATCH v3 resend net-next 1/2] myri10ge: Convert from LRO to GRO
From: Andrew Gallatin @ 2012-11-30 18:31 UTC (permalink / raw)
  To: davem; +Cc: netdev, Andrew Gallatin
In-Reply-To: <1354300319-30771-1-git-send-email-gallatin@myri.com>

Convert myri10ge from LRO to GRO, and simplify the driver by removing
various LRO-related code which is no longer needed including
ndo_fix_features op, custom skb building from frags, and LRO
header parsing.

Signed-off-by: Andrew Gallatin <gallatin@myri.com>
---
 drivers/net/ethernet/myricom/Kconfig             |    1 -
 drivers/net/ethernet/myricom/myri10ge/myri10ge.c |  236 ++++------------------
 2 files changed, 34 insertions(+), 203 deletions(-)

diff --git a/drivers/net/ethernet/myricom/Kconfig b/drivers/net/ethernet/myricom/Kconfig
index 540f0c6..3932d08 100644
--- a/drivers/net/ethernet/myricom/Kconfig
+++ b/drivers/net/ethernet/myricom/Kconfig
@@ -23,7 +23,6 @@ config MYRI10GE
 	depends on PCI && INET
 	select FW_LOADER
 	select CRC32
-	select INET_LRO
 	---help---
 	  This driver supports Myricom Myri-10G Dual Protocol interface in
 	  Ethernet mode. If the eeprom on your board is not recent enough,
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 83516e3..84207c0 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -50,7 +50,6 @@
 #include <linux/etherdevice.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
-#include <linux/inet_lro.h>
 #include <linux/dca.h>
 #include <linux/ip.h>
 #include <linux/inet.h>
@@ -96,8 +95,6 @@ MODULE_LICENSE("Dual BSD/GPL");
 
 #define MYRI10GE_EEPROM_STRINGS_SIZE 256
 #define MYRI10GE_MAX_SEND_DESC_TSO ((65536 / 2048) * 2)
-#define MYRI10GE_MAX_LRO_DESCRIPTORS 8
-#define MYRI10GE_LRO_MAX_PKTS 64
 
 #define MYRI10GE_NO_CONFIRM_DATA htonl(0xffffffff)
 #define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff
@@ -165,8 +162,6 @@ struct myri10ge_rx_done {
 	dma_addr_t bus;
 	int cnt;
 	int idx;
-	struct net_lro_mgr lro_mgr;
-	struct net_lro_desc lro_desc[MYRI10GE_MAX_LRO_DESCRIPTORS];
 };
 
 struct myri10ge_slice_netstats {
@@ -338,11 +333,6 @@ static int myri10ge_debug = -1;	/* defaults above */
 module_param(myri10ge_debug, int, 0);
 MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)");
 
-static int myri10ge_lro_max_pkts = MYRI10GE_LRO_MAX_PKTS;
-module_param(myri10ge_lro_max_pkts, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_lro_max_pkts,
-		 "Number of LRO packets to be aggregated");
-
 static int myri10ge_fill_thresh = 256;
 module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed");
@@ -1197,36 +1187,6 @@ static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum)
 	}
 }
 
-static inline void
-myri10ge_rx_skb_build(struct sk_buff *skb, u8 * va,
-		      struct skb_frag_struct *rx_frags, int len, int hlen)
-{
-	struct skb_frag_struct *skb_frags;
-
-	skb->len = skb->data_len = len;
-	/* attach the page(s) */
-
-	skb_frags = skb_shinfo(skb)->frags;
-	while (len > 0) {
-		memcpy(skb_frags, rx_frags, sizeof(*skb_frags));
-		len -= skb_frag_size(rx_frags);
-		skb_frags++;
-		rx_frags++;
-		skb_shinfo(skb)->nr_frags++;
-	}
-
-	/* pskb_may_pull is not available in irq context, but
-	 * skb_pull() (for ether_pad and eth_type_trans()) requires
-	 * the beginning of the packet in skb_headlen(), move it
-	 * manually */
-	skb_copy_to_linear_data(skb, va, hlen);
-	skb_shinfo(skb)->frags[0].page_offset += hlen;
-	skb_frag_size_sub(&skb_shinfo(skb)->frags[0], hlen);
-	skb->data_len -= hlen;
-	skb->tail += hlen;
-	skb_pull(skb, MXGEFW_PAD);
-}
-
 static void
 myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
 			int bytes, int watchdog)
@@ -1304,18 +1264,14 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,
 	}
 }
 
-#define MYRI10GE_HLEN 64	/* The number of bytes to copy from a
-				 * page into an skb */
-
 static inline int
-myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum,
-		 bool lro_enabled)
+myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum)
 {
 	struct myri10ge_priv *mgp = ss->mgp;
 	struct sk_buff *skb;
-	struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME];
+	struct skb_frag_struct *rx_frags;
 	struct myri10ge_rx_buf *rx;
-	int i, idx, hlen, remainder, bytes;
+	int i, idx, remainder, bytes;
 	struct pci_dev *pdev = mgp->pdev;
 	struct net_device *dev = mgp->dev;
 	u8 *va;
@@ -1332,67 +1288,47 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum,
 	idx = rx->cnt & rx->mask;
 	va = page_address(rx->info[idx].page) + rx->info[idx].page_offset;
 	prefetch(va);
+
+	skb = napi_get_frags(&ss->napi);
+	if (unlikely(skb == NULL)) {
+		ss->stats.rx_dropped++;
+		for (i = 0, remainder = len; remainder > 0; i++) {
+			myri10ge_unmap_rx_page(pdev, &rx->info[idx], bytes);
+			put_page(rx->info[idx].page);
+			rx->cnt++;
+			idx = rx->cnt & rx->mask;
+			remainder -= MYRI10GE_ALLOC_SIZE;
+		}
+		return 0;
+	}
+	rx_frags = skb_shinfo(skb)->frags;
 	/* Fill skb_frag_struct(s) with data from our receive */
 	for (i = 0, remainder = len; remainder > 0; i++) {
 		myri10ge_unmap_rx_page(pdev, &rx->info[idx], bytes);
-		__skb_frag_set_page(&rx_frags[i], rx->info[idx].page);
-		rx_frags[i].page_offset = rx->info[idx].page_offset;
-		if (remainder < MYRI10GE_ALLOC_SIZE)
-			skb_frag_size_set(&rx_frags[i], remainder);
-		else
-			skb_frag_size_set(&rx_frags[i], MYRI10GE_ALLOC_SIZE);
+		skb_fill_page_desc(skb, i, rx->info[idx].page,
+				   rx->info[idx].page_offset,
+				   remainder < MYRI10GE_ALLOC_SIZE ?
+				   remainder : MYRI10GE_ALLOC_SIZE);
 		rx->cnt++;
 		idx = rx->cnt & rx->mask;
 		remainder -= MYRI10GE_ALLOC_SIZE;
 	}
 
-	if (lro_enabled) {
-		rx_frags[0].page_offset += MXGEFW_PAD;
-		skb_frag_size_sub(&rx_frags[0], MXGEFW_PAD);
-		len -= MXGEFW_PAD;
-		lro_receive_frags(&ss->rx_done.lro_mgr, rx_frags,
-				  /* opaque, will come back in get_frag_header */
-				  len, len,
-				  (void *)(__force unsigned long)csum, csum);
+	/* remove padding */
+	rx_frags[0].page_offset += MXGEFW_PAD;
+	rx_frags[0].size -= MXGEFW_PAD;
+	len -= MXGEFW_PAD;
 
-		return 1;
-	}
-
-	hlen = MYRI10GE_HLEN > len ? len : MYRI10GE_HLEN;
-
-	/* allocate an skb to attach the page(s) to. This is done
-	 * after trying LRO, so as to avoid skb allocation overheads */
-
-	skb = netdev_alloc_skb(dev, MYRI10GE_HLEN + 16);
-	if (unlikely(skb == NULL)) {
-		ss->stats.rx_dropped++;
-		do {
-			i--;
-			__skb_frag_unref(&rx_frags[i]);
-		} while (i != 0);
-		return 0;
-	}
-
-	/* Attach the pages to the skb, and trim off any padding */
-	myri10ge_rx_skb_build(skb, va, rx_frags, len, hlen);
-	if (skb_frag_size(&skb_shinfo(skb)->frags[0]) <= 0) {
-		skb_frag_unref(skb, 0);
-		skb_shinfo(skb)->nr_frags = 0;
-	} else {
-		skb->truesize += bytes * skb_shinfo(skb)->nr_frags;
+	skb->len = len;
+	skb->data_len = len;
+	skb->truesize += len;
+	if (dev->features & NETIF_F_RXCSUM) {
+		skb->ip_summed = CHECKSUM_COMPLETE;
+		skb->csum = csum;
 	}
-	skb->protocol = eth_type_trans(skb, dev);
 	skb_record_rx_queue(skb, ss - &mgp->ss[0]);
 
-	if (dev->features & NETIF_F_RXCSUM) {
-		if ((skb->protocol == htons(ETH_P_IP)) ||
-		    (skb->protocol == htons(ETH_P_IPV6))) {
-			skb->csum = csum;
-			skb->ip_summed = CHECKSUM_COMPLETE;
-		} else
-			myri10ge_vlan_ip_csum(skb, csum);
-	}
-	netif_receive_skb(skb);
+	napi_gro_frags(&ss->napi);
 	return 1;
 }
 
@@ -1480,18 +1416,11 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
 	u16 length;
 	__wsum checksum;
 
-	/*
-	 * Prevent compiler from generating more than one ->features memory
-	 * access to avoid theoretical race condition with functions that
-	 * change NETIF_F_LRO flag at runtime.
-	 */
-	bool lro_enabled = !!(ACCESS_ONCE(mgp->dev->features) & NETIF_F_LRO);
-
 	while (rx_done->entry[idx].length != 0 && work_done < budget) {
 		length = ntohs(rx_done->entry[idx].length);
 		rx_done->entry[idx].length = 0;
 		checksum = csum_unfold(rx_done->entry[idx].checksum);
-		rx_ok = myri10ge_rx_done(ss, length, checksum, lro_enabled);
+		rx_ok = myri10ge_rx_done(ss, length, checksum);
 		rx_packets += rx_ok;
 		rx_bytes += rx_ok * (unsigned long)length;
 		cnt++;
@@ -1503,9 +1432,6 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
 	ss->stats.rx_packets += rx_packets;
 	ss->stats.rx_bytes += rx_bytes;
 
-	if (lro_enabled)
-		lro_flush_all(&rx_done->lro_mgr);
-
 	/* restock receive rings if needed */
 	if (ss->rx_small.fill_cnt - ss->rx_small.cnt < myri10ge_fill_thresh)
 		myri10ge_alloc_rx_pages(mgp, &ss->rx_small,
@@ -1779,7 +1705,6 @@ static const char myri10ge_gstrings_slice_stats[][ETH_GSTRING_LEN] = {
 	"tx_pkt_start", "tx_pkt_done", "tx_req", "tx_done",
 	"rx_small_cnt", "rx_big_cnt",
 	"wake_queue", "stop_queue", "tx_linearized",
-	"LRO aggregated", "LRO flushed", "LRO avg aggr", "LRO no_desc",
 };
 
 #define MYRI10GE_NET_STATS_LEN      21
@@ -1880,14 +1805,6 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
 		data[i++] = (unsigned int)ss->tx.wake_queue;
 		data[i++] = (unsigned int)ss->tx.stop_queue;
 		data[i++] = (unsigned int)ss->tx.linearized;
-		data[i++] = ss->rx_done.lro_mgr.stats.aggregated;
-		data[i++] = ss->rx_done.lro_mgr.stats.flushed;
-		if (ss->rx_done.lro_mgr.stats.flushed)
-			data[i++] = ss->rx_done.lro_mgr.stats.aggregated /
-			    ss->rx_done.lro_mgr.stats.flushed;
-		else
-			data[i++] = 0;
-		data[i++] = ss->rx_done.lro_mgr.stats.no_desc;
 	}
 }
 
@@ -2271,67 +2188,6 @@ static void myri10ge_free_irq(struct myri10ge_priv *mgp)
 		pci_disable_msix(pdev);
 }
 
-static int
-myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
-			 void **ip_hdr, void **tcpudp_hdr,
-			 u64 * hdr_flags, void *priv)
-{
-	struct ethhdr *eh;
-	struct vlan_ethhdr *veh;
-	struct iphdr *iph;
-	u8 *va = skb_frag_address(frag);
-	unsigned long ll_hlen;
-	/* passed opaque through lro_receive_frags() */
-	__wsum csum = (__force __wsum) (unsigned long)priv;
-
-	/* find the mac header, aborting if not IPv4 */
-
-	eh = (struct ethhdr *)va;
-	*mac_hdr = eh;
-	ll_hlen = ETH_HLEN;
-	if (eh->h_proto != htons(ETH_P_IP)) {
-		if (eh->h_proto == htons(ETH_P_8021Q)) {
-			veh = (struct vlan_ethhdr *)va;
-			if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP))
-				return -1;
-
-			ll_hlen += VLAN_HLEN;
-
-			/*
-			 *  HW checksum starts ETH_HLEN bytes into
-			 *  frame, so we must subtract off the VLAN
-			 *  header's checksum before csum can be used
-			 */
-			csum = csum_sub(csum, csum_partial(va + ETH_HLEN,
-							   VLAN_HLEN, 0));
-		} else {
-			return -1;
-		}
-	}
-	*hdr_flags = LRO_IPV4;
-
-	iph = (struct iphdr *)(va + ll_hlen);
-	*ip_hdr = iph;
-	if (iph->protocol != IPPROTO_TCP)
-		return -1;
-	if (ip_is_fragment(iph))
-		return -1;
-	*hdr_flags |= LRO_TCP;
-	*tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2);
-
-	/* verify the IP checksum */
-	if (unlikely(ip_fast_csum((u8 *) iph, iph->ihl)))
-		return -1;
-
-	/* verify the  checksum */
-	if (unlikely(csum_tcpudp_magic(iph->saddr, iph->daddr,
-				       ntohs(iph->tot_len) - (iph->ihl << 2),
-				       IPPROTO_TCP, csum)))
-		return -1;
-
-	return 0;
-}
-
 static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice)
 {
 	struct myri10ge_cmd cmd;
@@ -2402,7 +2258,6 @@ static int myri10ge_open(struct net_device *dev)
 	struct myri10ge_cmd cmd;
 	int i, status, big_pow2, slice;
 	u8 *itable;
-	struct net_lro_mgr *lro_mgr;
 
 	if (mgp->running != MYRI10GE_ETH_STOPPED)
 		return -EBUSY;
@@ -2513,19 +2368,6 @@ static int myri10ge_open(struct net_device *dev)
 			goto abort_with_rings;
 		}
 
-		lro_mgr = &ss->rx_done.lro_mgr;
-		lro_mgr->dev = dev;
-		lro_mgr->features = LRO_F_NAPI;
-		lro_mgr->ip_summed = CHECKSUM_COMPLETE;
-		lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
-		lro_mgr->max_desc = MYRI10GE_MAX_LRO_DESCRIPTORS;
-		lro_mgr->lro_arr = ss->rx_done.lro_desc;
-		lro_mgr->get_frag_header = myri10ge_get_frag_header;
-		lro_mgr->max_aggr = myri10ge_lro_max_pkts;
-		lro_mgr->frag_align_pad = 2;
-		if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
-			lro_mgr->max_aggr = MAX_SKB_FRAGS;
-
 		/* must happen prior to any irq */
 		napi_enable(&(ss)->napi);
 	}
@@ -3143,15 +2985,6 @@ static int myri10ge_set_mac_address(struct net_device *dev, void *addr)
 	return 0;
 }
 
-static netdev_features_t myri10ge_fix_features(struct net_device *dev,
-	netdev_features_t features)
-{
-	if (!(features & NETIF_F_RXCSUM))
-		features &= ~NETIF_F_LRO;
-
-	return features;
-}
-
 static int myri10ge_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct myri10ge_priv *mgp = netdev_priv(dev);
@@ -3878,7 +3711,6 @@ static const struct net_device_ops myri10ge_netdev_ops = {
 	.ndo_get_stats64	= myri10ge_get_stats,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_change_mtu		= myri10ge_change_mtu,
-	.ndo_fix_features	= myri10ge_fix_features,
 	.ndo_set_rx_mode	= myri10ge_set_multicast_list,
 	.ndo_set_mac_address	= myri10ge_set_mac_address,
 };
@@ -4018,7 +3850,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	netdev->netdev_ops = &myri10ge_netdev_ops;
 	netdev->mtu = myri10ge_initial_mtu;
-	netdev->hw_features = mgp->features | NETIF_F_LRO | NETIF_F_RXCSUM;
+	netdev->hw_features = mgp->features | NETIF_F_RXCSUM;
 	netdev->features = netdev->hw_features;
 
 	if (dac_enabled)
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH v2 3/3] pppoatm: protect against freeing of vcc
From: David Woodhouse @ 2012-11-30 18:33 UTC (permalink / raw)
  To: Krzysztof Mazur
  Cc: Chas Williams (CONTRACTOR), David Laight, davem, netdev,
	linux-kernel, nathan
In-Reply-To: <20121130170007.GA25818@shrek.podlesie.net>

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

On Fri, 2012-11-30 at 18:00 +0100, Krzysztof Mazur wrote:
> On Fri, Nov 30, 2012 at 04:23:46PM +0000, David Woodhouse wrote:
> > 
> > +static void br2684_release_cb(struct atm_vcc *atmvcc)
> > +{
> > +	struct br2684_vcc *brvcc = BR2684_VCC(atmvcc);
> > +
> > +	/*
> > +	 * A race with br2684_xmit_vcc() might cause a spurious wakeup just
> > +	 * after that function *stops* the queue, and qspace might actually
> > +	 * go negative before the queue stops again. We cope with that.
> > +	 */
> 
> We cannot race with br2684_xmit_vcc() because both br2684_xmit_vcc()
> and br2684_release_cb() are called with locked sk->sk_lock.slock.

Ah, right. For some reason I thought the lock was already dropped when
->release_cb() was called. In that case I'll remove the comment. Thanks.

-- 
dwmw2


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 6171 bytes --]

^ permalink raw reply

* pull request: wireless 2012-11-30
From: John W. Linville @ 2012-11-30 18:25 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev, linux-kernel

commit 9f8933e960f98d27742727445061b0ece934e5cf

Dave,

I have a couple of stragglers intended for 3.7...

The iwlwifi patch fixes a bug in CCK basic rate calculations.

The mac80211 patch removes an unnecessary function call that was
generating a lot of log SPAM.

Please let me know if there are problems!

John

---

The following changes since commit e196c0e579902f42cf72414461fb034e5a1ffbf7:

  bonding: fix race condition in bonding_store_slaves_active (2012-11-29 13:13:15 -0500)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem

for you to fetch changes up to 9f8933e960f98d27742727445061b0ece934e5cf:

  Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem (2012-11-30 11:27:32 -0500)

----------------------------------------------------------------

Emmanuel Grumbach (1):
      iwlwifi: fix the basic CCK rates calculation

Johannes Berg (1):
      mac80211: fix remain-on-channel (non-)cancelling

John W. Linville (2):
      Merge branch 'for-john' of git://git.kernel.org/.../iwlwifi/iwlwifi-fixes
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem

 drivers/net/wireless/iwlwifi/dvm/rxon.c | 12 ++++++------
 net/mac80211/offchannel.c               |  2 --
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c
index 1089639..2830ea2 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rxon.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c
@@ -1012,12 +1012,12 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv,
 	 * As a consequence, it's not as complicated as it sounds, just add
 	 * any lower rates to the ACK rate bitmap.
 	 */
-	if (IWL_RATE_11M_INDEX < lowest_present_ofdm)
-		ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE;
-	if (IWL_RATE_5M_INDEX < lowest_present_ofdm)
-		ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE;
-	if (IWL_RATE_2M_INDEX < lowest_present_ofdm)
-		ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE;
+	if (IWL_RATE_11M_INDEX < lowest_present_cck)
+		cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE;
+	if (IWL_RATE_5M_INDEX < lowest_present_cck)
+		cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE;
+	if (IWL_RATE_2M_INDEX < lowest_present_cck)
+		cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE;
 	/* 1M already there or needed so always add */
 	cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE;
 
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 83608ac..2c84185 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -458,8 +458,6 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata)
 		list_move_tail(&roc->list, &tmp_list);
 		roc->abort = true;
 	}
-
-	ieee80211_start_next_roc(local);
 	mutex_unlock(&local->mtx);
 
 	list_for_each_entry_safe(roc, tmp, &tmp_list, list) {
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply related


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