Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next] openvswitch: Add support for checksums on UDP tunnels.
From: Jesse Gross @ 2015-01-29  0:32 UTC (permalink / raw)
  To: Pravin Shelar
  Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA,
	David Miller

Currently, it isn't possible to request checksums on the outer UDP
header of tunnels - the TUNNEL_CSUM flag is ignored. This adds
support for requesting that UDP checksums be computed on transmit
and properly reported if they are present on receive.

Signed-off-by: Jesse Gross <jesse@nicira.com>
---
 include/net/geneve.h           | 2 +-
 net/ipv4/geneve.c              | 6 +++---
 net/openvswitch/vport-geneve.c | 2 +-
 net/openvswitch/vport-vxlan.c  | 7 +++++--
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/include/net/geneve.h b/include/net/geneve.h
index 03aa2ad..14fb8d3 100644
--- a/include/net/geneve.h
+++ b/include/net/geneve.h
@@ -90,7 +90,7 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
 		    struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos,
 		    __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port,
 		    __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt,
-		    bool xnet);
+		    bool csum, bool xnet);
 #endif /*ifdef CONFIG_INET */
 
 #endif /*ifdef__NET_GENEVE_H */
diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c
index 93e5119..5a4828b 100644
--- a/net/ipv4/geneve.c
+++ b/net/ipv4/geneve.c
@@ -107,13 +107,13 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
 		    struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos,
 		    __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port,
 		    __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt,
-		    bool xnet)
+		    bool csum, bool xnet)
 {
 	struct genevehdr *gnvh;
 	int min_headroom;
 	int err;
 
-	skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx);
+	skb = udp_tunnel_handle_offloads(skb, csum);
 	if (IS_ERR(skb))
 		return PTR_ERR(skb);
 
@@ -138,7 +138,7 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
 
 	return udp_tunnel_xmit_skb(rt, skb, src, dst,
 				   tos, ttl, df, src_port, dst_port, xnet,
-				   gs->sock->sk->sk_no_check_tx);
+				   !csum);
 }
 EXPORT_SYMBOL_GPL(geneve_xmit_skb);
 
diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c
index 7ca3d45..bf02fd5 100644
--- a/net/openvswitch/vport-geneve.c
+++ b/net/openvswitch/vport-geneve.c
@@ -212,7 +212,7 @@ static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb)
 			      tun_key->ipv4_dst, tun_key->ipv4_tos,
 			      tun_key->ipv4_ttl, df, sport, dport,
 			      tun_key->tun_flags, vni, opts_len, opts,
-			      false);
+			      !!(tun_key->tun_flags & TUNNEL_CSUM), false);
 	if (err < 0)
 		ip_rt_put(rt);
 	return err;
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index 3cc983b..ff07d40 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -74,7 +74,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
 	__be64 key;
 	__be16 flags;
 
-	flags = TUNNEL_KEY;
+	flags = TUNNEL_KEY | (udp_hdr(skb)->check != 0 ? TUNNEL_CSUM : 0);
 	vxlan_port = vxlan_vport(vport);
 	if (vxlan_port->exts & VXLAN_F_GBP)
 		flags |= TUNNEL_VXLAN_OPT;
@@ -230,6 +230,7 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
 	__be16 src_port;
 	__be16 df;
 	int err;
+	u32 vxflags;
 
 	if (unlikely(!OVS_CB(skb)->egress_tun_info)) {
 		err = -EINVAL;
@@ -251,11 +252,13 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
 	src_port = udp_flow_src_port(net, skb, 0, 0, true);
 	md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8);
 	md.gbp = vxlan_ext_gbp(skb);
+	vxflags = vxlan_port->exts |
+		      (tun_key->tun_flags & TUNNEL_CSUM ? VXLAN_F_UDP_CSUM : 0);
 
 	err = vxlan_xmit_skb(rt, skb, fl.saddr, tun_key->ipv4_dst,
 			     tun_key->ipv4_tos, tun_key->ipv4_ttl, df,
 			     src_port, dst_port,
-			     &md, false, vxlan_port->exts);
+			     &md, false, vxflags);
 	if (err < 0)
 		ip_rt_put(rt);
 	return err;
-- 
1.9.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

^ permalink raw reply related

* Re: [PATCH v2 linux-trace 1/8] tracing: attach eBPF programs to tracepoints and syscalls
From: Namhyung Kim @ 2015-01-29  0:46 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Steven Rostedt, Ingo Molnar, Arnaldo Carvalho de Melo, Jiri Olsa,
	Masami Hiramatsu, linux-api, netdev, linux-kernel
In-Reply-To: <1422417973-10195-2-git-send-email-ast@plumgrid.com>

Hi Alexei,

On Tue, Jan 27, 2015 at 08:06:06PM -0800, Alexei Starovoitov wrote:
> User interface:
> fd = open("/sys/kernel/debug/tracing/__event__/filter")
> 
> write(fd, "bpf_123")
> 
> where 123 is process local FD associated with eBPF program previously loaded.
> __event__ is static tracepoint event or syscall.
> (kprobe support is in next patch)
> Once program is successfully attached to tracepoint event, the tracepoint
> will be auto-enabled
> 
> close(fd)
> auto-disables tracepoint event and detaches eBPF program from it
> 
> eBPF programs can call in-kernel helper functions to:
> - lookup/update/delete elements in maps
> - memcmp
> - fetch_ptr/u64/u32/u16/u8 values from unsafe address via probe_kernel_read(),
>   so that eBPF program can walk any kernel data structures
> 
> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
> ---

[SNIP]
> diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
> index b03a0ea77b99..70482817231a 100644
> --- a/kernel/trace/trace_events.c
> +++ b/kernel/trace/trace_events.c
> @@ -1084,6 +1084,26 @@ event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
>  	return r;
>  }
>  
> +static int event_filter_release(struct inode *inode, struct file *filp)
> +{
> +	struct ftrace_event_file *file;
> +	char buf[2] = "0";
> +
> +	mutex_lock(&event_mutex);
> +	file = event_file_data(filp);
> +	if (file) {
> +		if (file->flags & TRACE_EVENT_FL_BPF) {
> +			/* auto-disable the filter */
> +			ftrace_event_enable_disable(file, 0);

Hmm.. what if user already enabled an event, attached a bpf filter and
then detached the filter - I'm not sure we can always auto-disable
it..


> +
> +			/* if BPF filter was used, clear it on fd close */
> +			apply_event_filter(file, buf);
> +		}
> +	}
> +	mutex_unlock(&event_mutex);
> +	return 0;
> +}
> +
>  static ssize_t
>  event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
>  		   loff_t *ppos)
> @@ -1107,8 +1127,18 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
>  
>  	mutex_lock(&event_mutex);
>  	file = event_file_data(filp);
> -	if (file)
> +	if (file) {
> +		/*
> +		 * note to user space tools:
> +		 * write() into debugfs/tracing/events/xxx/filter file
> +		 * must be done with the same privilege level as open()
> +		 */
>  		err = apply_event_filter(file, buf);
> +		if (!err && file->flags & TRACE_EVENT_FL_BPF)
> +			/* once filter is applied, auto-enable it */
> +			ftrace_event_enable_disable(file, 1);
> +	}
> +
>  	mutex_unlock(&event_mutex);
>  
>  	free_page((unsigned long) buf);
> @@ -1363,6 +1393,7 @@ static const struct file_operations ftrace_event_filter_fops = {
>  	.open = tracing_open_generic,
>  	.read = event_filter_read,
>  	.write = event_filter_write,
> +	.release = event_filter_release,
>  	.llseek = default_llseek,
>  };
>  
> diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
> index ced69da0ff55..e0303b3cc9fb 100644
> --- a/kernel/trace/trace_events_filter.c
> +++ b/kernel/trace/trace_events_filter.c
> @@ -23,6 +23,9 @@
>  #include <linux/mutex.h>
>  #include <linux/perf_event.h>
>  #include <linux/slab.h>
> +#include <linux/bpf.h>
> +#include <trace/bpf_trace.h>
> +#include <linux/filter.h>
>  
>  #include "trace.h"
>  #include "trace_output.h"
> @@ -541,6 +544,21 @@ static int filter_match_preds_cb(enum move_type move, struct filter_pred *pred,
>  	return WALK_PRED_DEFAULT;
>  }
>  
> +unsigned int trace_filter_call_bpf(struct event_filter *filter, void *ctx)
> +{
> +	unsigned int ret;
> +
> +	if (in_nmi()) /* not supported yet */
> +		return 0;

But doesn't this mean to auto-disable all attached events during NMI
as returning 0 will prevent the event going to ring buffer?

I think it'd be better to keep an attached event in a soft-disabled
state like event trigger and give control of enabling to users..

Thanks,
Namhyung


> +
> +	rcu_read_lock();
> +	ret = BPF_PROG_RUN(filter->prog, ctx);
> +	rcu_read_unlock();
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(trace_filter_call_bpf);

^ permalink raw reply

* Re: A problem about ICMP packet-too-big message handler
From: Yang Yingliang @ 2015-01-29  1:04 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Martin Lau, netdev, David S. Miller
In-Reply-To: <1422449109.29618.42.camel@edumazet-glaptop2.roam.corp.google.com>

On 2015/1/28 20:45, Eric Dumazet wrote:
> On Wed, 2015-01-28 at 14:46 +0800, Yang Yingliang wrote:
>> On 2015/1/28 13:19, Martin Lau wrote:
>>> On Tue, Jan 27, 2015 at 08:58:53PM +0800, Yang Yingliang wrote:
>>>> Hi,
>>>>
>>>> My kernel is 3.10 LTS.
>>>>
>>>> I got a problem here about handling ICMP packet-too-big message.
>>>>
>>>> Before sending a packet-too-big packet :
>>> The expires should be set by the host _receiving_ the icmpv6 too-big.
>>>
>>> Can you spell out some details of the outgoing icmpv6 too-big packet?
>>> like, the src/dst ip of the icmpv6 and the original ip packet that triggered the
>>> too-big.
>>>
>>
>> I don't send too-big packet to trigger the err handling.
>>
>> I just only send a ICMPv6 packet which type is ICMPV6_PKT_TOOBIG.
> 
> You meant : you received an ICMPv6 packet, or you send it ?

Received an ICMPv6 packet.

Regards,
Yang

^ permalink raw reply

* [PATCH net-next v2 2/5] tcp: fix the timid additive increase on stretch ACKs
From: Neal Cardwell @ 2015-01-29  1:01 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Neal Cardwell, Yuchung Cheng, Eric Dumazet
In-Reply-To: <1422493299-22114-1-git-send-email-ncardwell@google.com>

tcp_cong_avoid_ai() was too timid (snd_cwnd increased too slowly) on
"stretch ACKs" -- cases where the receiver ACKed more than 1 packet in
a single ACK. For example, suppose w is 10 and we get a stretch ACK
for 20 packets, so acked is 20. We ought to increase snd_cwnd by 2
(since acked/w = 20/10 = 2), but instead we were only increasing cwnd
by 1. This patch fixes that behavior.

Reported-by: Eyal Perry <eyalpe@mellanox.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 net/ipv4/tcp_cong.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 60bc170..389fe7a 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -373,16 +373,19 @@ u32 tcp_slow_start(struct tcp_sock *tp, u32 acked)
 }
 EXPORT_SYMBOL_GPL(tcp_slow_start);
 
-/* In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd (or alternative w) */
+/* In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd (or alternative w),
+ * for every packet that was ACKed.
+ */
 void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked)
 {
+	tp->snd_cwnd_cnt += acked;
 	if (tp->snd_cwnd_cnt >= w) {
-		if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-			tp->snd_cwnd++;
-		tp->snd_cwnd_cnt = 0;
-	} else {
-		tp->snd_cwnd_cnt += acked;
+		u32 delta = tp->snd_cwnd_cnt / w;
+
+		tp->snd_cwnd_cnt -= delta * w;
+		tp->snd_cwnd += delta;
 	}
+	tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_cwnd_clamp);
 }
 EXPORT_SYMBOL_GPL(tcp_cong_avoid_ai);
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH net-next v2 0/5] fix stretch ACK bugs in TCP CUBIC and Reno
From: Neal Cardwell @ 2015-01-29  1:01 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Neal Cardwell

This patch series fixes the TCP CUBIC and Reno congestion control
modules to properly handle stretch ACKs in their respective additive
increase modes, and in the transitions from slow start to additive
increase.

This finishes the project started by commit 9f9843a751d0a2057 ("tcp:
properly handle stretch acks in slow start"), which fixed behavior for
TCP congestion control when handling stretch ACKs in slow start mode.

Motivation: In the Jan 2015 netdev thread 'BW regression after "tcp:
refine TSO autosizing"', Eyal Perry documented a regression that Eric
Dumazet determined was caused by improper handling of TCP stretch
ACKs.

Background: LRO, GRO, delayed ACKs, and middleboxes can cause "stretch
ACKs" that cover more than the RFC-specified maximum of 2
packets. These stretch ACKs can cause serious performance shortfalls
in common congestion control algorithms, like Reno and CUBIC, which
were designed and tuned years ago with receiver hosts that were not
using LRO or GRO, and were instead ACKing every other packet.

Testing: at Google we have been using this approach for handling
stretch ACKs for CUBIC datacenter and Internet traffic for several
years, with good results.

v2:
 * fixed return type of tcp_slow_start() to be u32 instead of int

Neal Cardwell (5):
  tcp: stretch ACK fixes prep
  tcp: fix the timid additive increase on stretch ACKs
  tcp: fix stretch ACK bugs in Reno
  tcp: fix stretch ACK bugs in CUBIC
  tcp: fix timing issue in CUBIC slope calculation

 include/net/tcp.h       |  4 ++--
 net/ipv4/tcp_bic.c      |  2 +-
 net/ipv4/tcp_cong.c     | 32 ++++++++++++++++++++------------
 net/ipv4/tcp_cubic.c    | 39 +++++++++++++++++----------------------
 net/ipv4/tcp_scalable.c |  3 ++-
 net/ipv4/tcp_veno.c     |  2 +-
 net/ipv4/tcp_yeah.c     |  2 +-
 7 files changed, 44 insertions(+), 40 deletions(-)

-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply

* [PATCH net-next v2 4/5] tcp: fix stretch ACK bugs in CUBIC
From: Neal Cardwell @ 2015-01-29  1:01 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Neal Cardwell, Yuchung Cheng, Eric Dumazet
In-Reply-To: <1422493299-22114-1-git-send-email-ncardwell@google.com>

Change CUBIC to properly handle stretch ACKs in additive increase mode
by passing in the count of ACKed packets to tcp_cong_avoid_ai().

In addition, because we are now precisely accounting for stretch ACKs,
including delayed ACKs, we can now remove the delayed ACK tracking and
estimation code that tracked recent delayed ACK behavior in
ca->delayed_ack.

Reported-by: Eyal Perry <eyalpe@mellanox.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 net/ipv4/tcp_cubic.c | 31 +++++++++----------------------
 1 file changed, 9 insertions(+), 22 deletions(-)

diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index df4bc4d..ffc045d 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -93,9 +93,7 @@ struct bictcp {
 	u32	epoch_start;	/* beginning of an epoch */
 	u32	ack_cnt;	/* number of acks */
 	u32	tcp_cwnd;	/* estimated tcp cwnd */
-#define ACK_RATIO_SHIFT	4
-#define ACK_RATIO_LIMIT (32u << ACK_RATIO_SHIFT)
-	u16	delayed_ack;	/* estimate the ratio of Packets/ACKs << 4 */
+	u16	unused;
 	u8	sample_cnt;	/* number of samples to decide curr_rtt */
 	u8	found;		/* the exit point is found? */
 	u32	round_start;	/* beginning of each round */
@@ -114,7 +112,6 @@ static inline void bictcp_reset(struct bictcp *ca)
 	ca->bic_K = 0;
 	ca->delay_min = 0;
 	ca->epoch_start = 0;
-	ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
 	ca->ack_cnt = 0;
 	ca->tcp_cwnd = 0;
 	ca->found = 0;
@@ -205,12 +202,12 @@ static u32 cubic_root(u64 a)
 /*
  * Compute congestion window to use.
  */
-static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
+static inline void bictcp_update(struct bictcp *ca, u32 cwnd, u32 acked)
 {
 	u32 delta, bic_target, max_cnt;
 	u64 offs, t;
 
-	ca->ack_cnt++;	/* count the number of ACKs */
+	ca->ack_cnt += acked;	/* count the number of ACKed packets */
 
 	if (ca->last_cwnd == cwnd &&
 	    (s32)(tcp_time_stamp - ca->last_time) <= HZ / 32)
@@ -221,7 +218,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
 
 	if (ca->epoch_start == 0) {
 		ca->epoch_start = tcp_time_stamp;	/* record beginning */
-		ca->ack_cnt = 1;			/* start counting */
+		ca->ack_cnt = acked;			/* start counting */
 		ca->tcp_cwnd = cwnd;			/* syn with cubic */
 
 		if (ca->last_max_cwnd <= cwnd) {
@@ -301,7 +298,6 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
 		}
 	}
 
-	ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack;
 	if (ca->cnt == 0)			/* cannot be zero */
 		ca->cnt = 1;
 }
@@ -317,11 +313,12 @@ static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 	if (tp->snd_cwnd <= tp->snd_ssthresh) {
 		if (hystart && after(ack, ca->end_seq))
 			bictcp_hystart_reset(sk);
-		tcp_slow_start(tp, acked);
-	} else {
-		bictcp_update(ca, tp->snd_cwnd);
-		tcp_cong_avoid_ai(tp, ca->cnt, 1);
+		acked = tcp_slow_start(tp, acked);
+		if (!acked)
+			return;
 	}
+	bictcp_update(ca, tp->snd_cwnd, acked);
+	tcp_cong_avoid_ai(tp, ca->cnt, acked);
 }
 
 static u32 bictcp_recalc_ssthresh(struct sock *sk)
@@ -411,20 +408,10 @@ static void hystart_update(struct sock *sk, u32 delay)
  */
 static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)
 {
-	const struct inet_connection_sock *icsk = inet_csk(sk);
 	const struct tcp_sock *tp = tcp_sk(sk);
 	struct bictcp *ca = inet_csk_ca(sk);
 	u32 delay;
 
-	if (icsk->icsk_ca_state == TCP_CA_Open) {
-		u32 ratio = ca->delayed_ack;
-
-		ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT;
-		ratio += cnt;
-
-		ca->delayed_ack = clamp(ratio, 1U, ACK_RATIO_LIMIT);
-	}
-
 	/* Some calls are for duplicates without timetamps */
 	if (rtt_us < 0)
 		return;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* Re: A problem about ICMP packet-too-big message handler
From: Hannes Frederic Sowa @ 2015-01-28  8:42 UTC (permalink / raw)
  To: Yang Yingliang; +Cc: netdev, David S. Miller
In-Reply-To: <54C78B8D.1070104@huawei.com>

On Di, 2015-01-27 at 20:58 +0800, Yang Yingliang wrote:
> Hi,
> 
> My kernel is 3.10 LTS.
> 
> I got a problem here about handling ICMP packet-too-big message.
> 
> Before sending a packet-too-big packet :
> 
> # ip -6 route list table local
> local ::1 dev lo  metric 0 
> local fe80:: dev lo  metric 0 
> local fe80:: dev lo  metric 0 
> local fe80:: dev lo  metric 0 
> local fe80:: dev lo  metric 0 
> local fe80:: dev lo  metric 0 
> local fe80:: dev lo  metric 0 
> local fe80::1 dev lo  metric 0 	//It  does not have expire value

Did you just add a local route or do you also have a corresponding IPv6
address bound to loopback?

Bye,
Hannes

^ permalink raw reply

* [PATCH net-next v2 3/5] tcp: fix stretch ACK bugs in Reno
From: Neal Cardwell @ 2015-01-29  1:01 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Neal Cardwell, Yuchung Cheng, Eric Dumazet
In-Reply-To: <1422493299-22114-1-git-send-email-ncardwell@google.com>

Change Reno to properly handle stretch ACKs in additive increase mode
by passing in the count of ACKed packets to tcp_cong_avoid_ai().

In addition, if snd_cwnd crosses snd_ssthresh during slow start
processing, and we then exit slow start mode, we need to carry over
any remaining "credit" for packets ACKed and apply that to additive
increase by passing this remaining "acked" count to
tcp_cong_avoid_ai().

Reported-by: Eyal Perry <eyalpe@mellanox.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 net/ipv4/tcp_cong.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 389fe7a..d694088 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -404,11 +404,13 @@ void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 		return;
 
 	/* In "safe" area, increase. */
-	if (tp->snd_cwnd <= tp->snd_ssthresh)
-		tcp_slow_start(tp, acked);
+	if (tp->snd_cwnd <= tp->snd_ssthresh) {
+		acked = tcp_slow_start(tp, acked);
+		if (!acked)
+			return;
+	}
 	/* In dangerous area, increase slowly. */
-	else
-		tcp_cong_avoid_ai(tp, tp->snd_cwnd, 1);
+	tcp_cong_avoid_ai(tp, tp->snd_cwnd, acked);
 }
 EXPORT_SYMBOL_GPL(tcp_reno_cong_avoid);
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH net-next v2 1/5] tcp: stretch ACK fixes prep
From: Neal Cardwell @ 2015-01-29  1:01 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Neal Cardwell, Yuchung Cheng, Eric Dumazet
In-Reply-To: <1422493299-22114-1-git-send-email-ncardwell@google.com>

LRO, GRO, delayed ACKs, and middleboxes can cause "stretch ACKs" that
cover more than the RFC-specified maximum of 2 packets. These stretch
ACKs can cause serious performance shortfalls in common congestion
control algorithms that were designed and tuned years ago with
receiver hosts that were not using LRO or GRO, and were instead
politely ACKing every other packet.

This patch series fixes Reno and CUBIC to handle stretch ACKs.

This patch prepares for the upcoming stretch ACK bug fix patches. It
adds an "acked" parameter to tcp_cong_avoid_ai() to allow for future
fixes to tcp_cong_avoid_ai() to correctly handle stretch ACKs, and
changes all congestion control algorithms to pass in 1 for the ACKed
count. It also changes tcp_slow_start() to return the number of packet
ACK "credits" that were not processed in slow start mode, and can be
processed by the congestion control module in additive increase mode.

In future patches we will fix tcp_cong_avoid_ai() to handle stretch
ACKs, and fix Reno and CUBIC handling of stretch ACKs in slow start
and additive increase mode.

Reported-by: Eyal Perry <eyalpe@mellanox.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 include/net/tcp.h       |  4 ++--
 net/ipv4/tcp_bic.c      |  2 +-
 net/ipv4/tcp_cong.c     | 11 +++++++----
 net/ipv4/tcp_cubic.c    |  2 +-
 net/ipv4/tcp_scalable.c |  3 ++-
 net/ipv4/tcp_veno.c     |  2 +-
 net/ipv4/tcp_yeah.c     |  2 +-
 7 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index b8fdc6b..7c280a4 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -843,8 +843,8 @@ void tcp_get_available_congestion_control(char *buf, size_t len);
 void tcp_get_allowed_congestion_control(char *buf, size_t len);
 int tcp_set_allowed_congestion_control(char *allowed);
 int tcp_set_congestion_control(struct sock *sk, const char *name);
-void tcp_slow_start(struct tcp_sock *tp, u32 acked);
-void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w);
+u32 tcp_slow_start(struct tcp_sock *tp, u32 acked);
+void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked);
 
 u32 tcp_reno_ssthresh(struct sock *sk);
 void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 acked);
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
index bb395d4..c037644 100644
--- a/net/ipv4/tcp_bic.c
+++ b/net/ipv4/tcp_bic.c
@@ -150,7 +150,7 @@ static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 		tcp_slow_start(tp, acked);
 	else {
 		bictcp_update(ca, tp->snd_cwnd);
-		tcp_cong_avoid_ai(tp, ca->cnt);
+		tcp_cong_avoid_ai(tp, ca->cnt, 1);
 	}
 }
 
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 63c29db..60bc170 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -360,25 +360,28 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
  * ABC caps N to 2. Slow start exits when cwnd grows over ssthresh and
  * returns the leftover acks to adjust cwnd in congestion avoidance mode.
  */
-void tcp_slow_start(struct tcp_sock *tp, u32 acked)
+u32 tcp_slow_start(struct tcp_sock *tp, u32 acked)
 {
 	u32 cwnd = tp->snd_cwnd + acked;
 
 	if (cwnd > tp->snd_ssthresh)
 		cwnd = tp->snd_ssthresh + 1;
+	acked -= cwnd - tp->snd_cwnd;
 	tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp);
+
+	return acked;
 }
 EXPORT_SYMBOL_GPL(tcp_slow_start);
 
 /* In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd (or alternative w) */
-void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w)
+void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked)
 {
 	if (tp->snd_cwnd_cnt >= w) {
 		if (tp->snd_cwnd < tp->snd_cwnd_clamp)
 			tp->snd_cwnd++;
 		tp->snd_cwnd_cnt = 0;
 	} else {
-		tp->snd_cwnd_cnt++;
+		tp->snd_cwnd_cnt += acked;
 	}
 }
 EXPORT_SYMBOL_GPL(tcp_cong_avoid_ai);
@@ -402,7 +405,7 @@ void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 		tcp_slow_start(tp, acked);
 	/* In dangerous area, increase slowly. */
 	else
-		tcp_cong_avoid_ai(tp, tp->snd_cwnd);
+		tcp_cong_avoid_ai(tp, tp->snd_cwnd, 1);
 }
 EXPORT_SYMBOL_GPL(tcp_reno_cong_avoid);
 
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index 6b60024..df4bc4d 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -320,7 +320,7 @@ static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 		tcp_slow_start(tp, acked);
 	} else {
 		bictcp_update(ca, tp->snd_cwnd);
-		tcp_cong_avoid_ai(tp, ca->cnt);
+		tcp_cong_avoid_ai(tp, ca->cnt, 1);
 	}
 }
 
diff --git a/net/ipv4/tcp_scalable.c b/net/ipv4/tcp_scalable.c
index 6824afb..333bcb2 100644
--- a/net/ipv4/tcp_scalable.c
+++ b/net/ipv4/tcp_scalable.c
@@ -25,7 +25,8 @@ static void tcp_scalable_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 	if (tp->snd_cwnd <= tp->snd_ssthresh)
 		tcp_slow_start(tp, acked);
 	else
-		tcp_cong_avoid_ai(tp, min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT));
+		tcp_cong_avoid_ai(tp, min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT),
+				  1);
 }
 
 static u32 tcp_scalable_ssthresh(struct sock *sk)
diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c
index a4d2d2d..112151e 100644
--- a/net/ipv4/tcp_veno.c
+++ b/net/ipv4/tcp_veno.c
@@ -159,7 +159,7 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 				/* In the "non-congestive state", increase cwnd
 				 *  every rtt.
 				 */
-				tcp_cong_avoid_ai(tp, tp->snd_cwnd);
+				tcp_cong_avoid_ai(tp, tp->snd_cwnd, 1);
 			} else {
 				/* In the "congestive state", increase cwnd
 				 * every other rtt.
diff --git a/net/ipv4/tcp_yeah.c b/net/ipv4/tcp_yeah.c
index cd72732..17d3566 100644
--- a/net/ipv4/tcp_yeah.c
+++ b/net/ipv4/tcp_yeah.c
@@ -92,7 +92,7 @@ static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 
 	} else {
 		/* Reno */
-		tcp_cong_avoid_ai(tp, tp->snd_cwnd);
+		tcp_cong_avoid_ai(tp, tp->snd_cwnd, 1);
 	}
 
 	/* The key players are v_vegas.beg_snd_una and v_beg_snd_nxt.
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH net-next v2 5/5] tcp: fix timing issue in CUBIC slope calculation
From: Neal Cardwell @ 2015-01-29  1:01 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Neal Cardwell, Yuchung Cheng, Eric Dumazet
In-Reply-To: <1422493299-22114-1-git-send-email-ncardwell@google.com>

This patch fixes a bug in CUBIC that causes cwnd to increase slightly
too slowly when multiple ACKs arrive in the same jiffy.

If cwnd is supposed to increase at a rate of more than once per jiffy,
then CUBIC was sometimes too slow. Because the bic_target is
calculated for a future point in time, calculated with time in
jiffies, the cwnd can increase over the course of the jiffy while the
bic_target calculated as the proper CUBIC cwnd at time
t=tcp_time_stamp+rtt does not increase, because tcp_time_stamp only
increases on jiffy tick boundaries.

So since the cnt is set to:
	ca->cnt = cwnd / (bic_target - cwnd);
as cwnd increases but bic_target does not increase due to jiffy
granularity, the cnt becomes too large, causing cwnd to increase
too slowly.

For example:
- suppose at the beginning of a jiffy, cwnd=40, bic_target=44
- so CUBIC sets:
   ca->cnt =  cwnd / (bic_target - cwnd) = 40 / (44 - 40) = 40/4 = 10
- suppose we get 10 acks, each for 1 segment, so tcp_cong_avoid_ai()
   increases cwnd to 41
- so CUBIC sets:
   ca->cnt =  cwnd / (bic_target - cwnd) = 41 / (44 - 41) = 41 / 3 = 13

So now CUBIC will wait for 13 packets to be ACKed before increasing
cwnd to 42, insted of 10 as it should.

The fix is to avoid adjusting the slope (determined by ca->cnt)
multiple times within a jiffy, and instead skip to compute the Reno
cwnd, the "TCP friendliness" code path.

Reported-by: Eyal Perry <eyalpe@mellanox.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 net/ipv4/tcp_cubic.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index ffc045d..4b276d1 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -213,6 +213,13 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd, u32 acked)
 	    (s32)(tcp_time_stamp - ca->last_time) <= HZ / 32)
 		return;
 
+	/* The CUBIC function can update ca->cnt at most once per jiffy.
+	 * On all cwnd reduction events, ca->epoch_start is set to 0,
+	 * which will force a recalculation of ca->cnt.
+	 */
+	if (ca->epoch_start && tcp_time_stamp == ca->last_time)
+		goto tcp_friendliness;
+
 	ca->last_cwnd = cwnd;
 	ca->last_time = tcp_time_stamp;
 
@@ -280,6 +287,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd, u32 acked)
 	if (ca->last_max_cwnd == 0 && ca->cnt > 20)
 		ca->cnt = 20;	/* increase cwnd 5% per RTT */
 
+tcp_friendliness:
 	/* TCP Friendly */
 	if (tcp_friendliness) {
 		u32 scale = beta_scale;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH v2] bridge: dont send notification when skb->len == 0 in rtnl_bridge_notify
From: roopa @ 2015-01-29  0:23 UTC (permalink / raw)
  To: netdev, davem, stephen, rami.rosen

From: Roopa Prabhu <roopa@cumulusnetworks.com>

Reported in: https://bugzilla.kernel.org/show_bug.cgi?id=92081

This patch avoids calling rtnl_notify if the device ndo_bridge_getlink
handler does not return any bytes in the skb.

Alternately, the skb->len check can be moved inside rtnl_notify.

For the bridge vlan case described in 92081, there is also a fix needed
in bridge driver to generate a proper notification. Will fix that in
subsequent patch.

v2: rebase patch on net tree

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
 net/core/rtnetlink.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 9cf6fe9..446cbaf 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2895,12 +2895,16 @@ static int rtnl_bridge_notify(struct net_device *dev, u16 flags)
 			goto errout;
 	}
 
+	if (!skb->len)
+		goto errout;
+
 	rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
 	return 0;
 errout:
 	WARN_ON(err == -EMSGSIZE);
 	kfree_skb(skb);
-	rtnl_set_sk_err(net, RTNLGRP_LINK, err);
+	if (err)
+		rtnl_set_sk_err(net, RTNLGRP_LINK, err);
 	return err;
 }
 
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 2/3] net: davinci_emac: Get device dm816x MAC address using the cpsw code
From: Tony Lindgren @ 2015-01-28 19:33 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-omap, Brian Hutchinson, Felipe Balbi
In-Reply-To: <1422473586-18100-1-git-send-email-tony@atomide.com>

At least on dm81xx, we can get the davinci_emac MAC address the same
way as on am33xx cpsw.

Let's also use ether_addr_copy() for davinci_emac while at it.

Cc: Brian Hutchinson <b.hutchman@gmail.com>
Cc: Felipe Balbi <balbi@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/net/ethernet/ti/davinci_emac.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 5fae435..a716938 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -69,6 +69,7 @@
 #include <asm/irq.h>
 #include <asm/page.h>
 
+#include "cpsw.h"
 #include "davinci_cpdma.h"
 
 static int debug_level;
@@ -1838,7 +1839,7 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
 	if (!is_valid_ether_addr(pdata->mac_addr)) {
 		mac_addr = of_get_mac_address(np);
 		if (mac_addr)
-			memcpy(pdata->mac_addr, mac_addr, ETH_ALEN);
+			ether_addr_copy(pdata->mac_addr, mac_addr);
 	}
 
 	of_property_read_u32(np, "ti,davinci-ctrl-reg-offset",
@@ -1879,6 +1880,22 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
 	return  pdata;
 }
 
+static int davinci_emac_try_get_mac(struct platform_device *pdev,
+				    int instance, u8 *mac_addr)
+{
+	int error = -EINVAL;
+
+	if (!pdev->dev.of_node)
+		return error;
+
+	if (of_device_is_compatible(pdev->dev.of_node, "ti,dm816-emac"))
+		error = cpsw_am33xx_cm_get_macid(&pdev->dev, 0x30,
+						 instance,
+						 mac_addr);
+
+	return error;
+}
+
 /**
  * davinci_emac_probe - EMAC device probe
  * @pdev: The DaVinci EMAC device that we are removing
@@ -2009,6 +2026,10 @@ static int davinci_emac_probe(struct platform_device *pdev)
 	}
 	ndev->irq = res->start;
 
+	rc = davinci_emac_try_get_mac(pdev, res_ctrl ? 0 : 1, priv->mac_addr);
+	if (!rc)
+		ether_addr_copy(ndev->dev_addr, priv->mac_addr);
+
 	if (!is_valid_ether_addr(priv->mac_addr)) {
 		/* Use random MAC if none passed */
 		eth_hw_addr_random(ndev);
-- 
2.1.4

^ permalink raw reply related

* Re: [RFC] net: tcp: null pointer crash in __inet_put_port
From: Eric Dumazet @ 2015-01-28 21:03 UTC (permalink / raw)
  To: Harout Hedeshian; +Cc: netdev
In-Reply-To: <1422460613-10782-1-git-send-email-harouth@codeaurora.org>

On Wed, 2015-01-28 at 08:56 -0700, Harout Hedeshian wrote:
> Hello,
> 
> We are observing a crash in __inet_put_port() wherein icsk_bind_hash
> is null (stack trace below).
> 
> net/ipv4/inet_hashtables.c:
> tb = inet_csk(sk)->icsk_bind_hash;
> __sk_del_bind_node(sk);
> tb->num_owners--;       <-- tb is unconditionally dereferenced here
> 
> From the RAM dumps: [D:0xFFFFFFC0222FB6F8] icsk_bind_hash = 0x0 = ,
> 
> The caller of inet_put_port() in this case is tcp_set_state() which
> already does a null check on this particular field before calling
> inet_put_port().
> 
> net/ipv4/tcp.c:
> if (inet_csk(sk)->icsk_bind_hash &&
>    !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
> 	inet_put_port(sk);
> 
> It seems that inet_put_port() does some locking by disabling bottom
> halves, but this locking is happening after the null check.
> 
> Additionally, I see tcp_v4_destroy_sock() also calling inet_put_port()
> after doing a similar null check. However, I am unsure if it would
> ever be called on the same socket.
> 
> Does the proposed solution of locking the bottom halves from
> tcp_set_state() make any sense here? Or use some other locking mechanism
> directly on the socket?

>  net/ipv4/tcp.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 3075723..f3b5714 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -1910,9 +1910,11 @@ void tcp_set_state(struct sock *sk, int state)
>  			TCP_INC_STATS(sock_net(sk), TCP_MIB_ESTABRESETS);
>  
>  		sk->sk_prot->unhash(sk);
> +		local_bh_disable();
>  		if (inet_csk(sk)->icsk_bind_hash &&
>  		    !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
>  			inet_put_port(sk);
> +		local_bh_enable();
>  		/* fall through */
>  	default:
>  		if (oldstate == TCP_ESTABLISHED)


I don't think it makes sense.

tcp_set_state() should only be used on a locked socket.

I believe you are papering over another bug.

bh are disabled in inet_put_port because of the spin_lock() that can be
taken both from process and softirq contexts.

^ permalink raw reply

* [GIT] [3.20] NFC update
From: Samuel Ortiz @ 2015-01-29  0:52 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev

Hi David,

This is the first NFC pull request for 3.20.

With this one we have:

- Secure element support for the ST Micro st21nfca driver. This depends
  on a few HCI internal changes in order for example to support more
  than one secure element per controller.

- ACPI support for NXP's pn544 HCI driver. This controller is found on
  many x86 SoCs and is typically enumerated on the ACPI bus there.

- A few st21nfca and st21nfcb fixes. Since they're not critical fixes,
  I assumed it's too late for a 3.19 inclusion. Please let me know if
  you'd prefer to see them going through a net pull request instead.


The following changes since commit 7aee42c6764bae75d0eb2f674f0874193de90c05:

  cxgb3: re-use native hex2bin() (2015-01-25 00:09:41 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-next.git tags/nfc-next-3.20-1

for you to fetch changes up to 0a5942c8e1480db4b8ee7a8d643e4945ef2f8fed:

  NFC: Add ACPI support for NXP PN544 (2015-01-28 01:09:08 +0100)

----------------------------------------------------------------
Christophe Ricard (23):
      NFC: dts: st21nfca: Fix compatible string spelling to follow other drivers
      NFC: dts: st21nfcb: Fix compatible string spelling to follow other drivers
      NFC: st21nfcb: Fix "WARNING: invalid free of devm_ allocated data"
      NFC: st21nfca: Remove unreachable code
      NFC: st21nfcb: Avoid use of skb after free
      NFC: nfc_enable_se Remove useless blank line at beginning of function
      NFC: nfc_disable_se Remove useless blank line at beginning of function
      NFC: st21nfca: Remove skb_pipe_list and skb_pipe_info useless allocation
      NFC: st21nfca: Remove checkpatch.pl warning Possible unnecessary 'out of memory' message
      NFC: st21nfca: Fix some skb memory leaks
      NFC: st21nfcb: Fix "NULL pointer dereference" possible error
      NFC: st21nfcb: Remove useless include
      NFC: st21nfcb: Fix copy/paste error in comment
      NFC: hci: Change event_received handler gate parameter to pipe
      NFC: hci: Add pipes table to reference them with a tuple {gate, host}
      NFC: hci: Change nfc_hci_send_response gate parameter to pipe
      NFC: hci: Reference every pipe information according to notification
      NFC: hci: Add cmd_received handler
      NFC: pn544: Change event_received gate parameter to pipe
      NFC: microread: Change event_received gate parameter to pipe
      NFC: hci: Remove nfc_hci_pipe2gate function
      NFC: st21nfca: Adding support for secure element
      NFC: dts: st21nfca: Document ese-present & uicc-present DTS property

Robert Dolca (2):
      NFC: PN544: GPIO access that may sleep
      NFC: Add ACPI support for NXP PN544

 .../devicetree/bindings/net/nfc/st21nfca.txt       |  11 +-
 .../devicetree/bindings/net/nfc/st21nfcb.txt       |   4 +-
 drivers/nfc/microread/microread.c                  |   3 +-
 drivers/nfc/pn544/i2c.c                            | 133 ++++++-
 drivers/nfc/pn544/pn544.c                          |   3 +-
 drivers/nfc/st21nfca/Makefile                      |   2 +-
 drivers/nfc/st21nfca/i2c.c                         |  23 +-
 drivers/nfc/st21nfca/st21nfca.c                    | 186 +++++++---
 drivers/nfc/st21nfca/st21nfca.h                    |  21 +-
 drivers/nfc/st21nfca/st21nfca_se.c                 | 390 +++++++++++++++++++++
 drivers/nfc/st21nfca/st21nfca_se.h                 |  63 ++++
 drivers/nfc/st21nfcb/i2c.c                         |  19 +-
 drivers/nfc/st21nfcb/ndlc.c                        |   3 +-
 include/linux/platform_data/st21nfca.h             |   2 +
 include/linux/platform_data/st21nfcb.h             |   4 +-
 include/net/nfc/hci.h                              |  25 +-
 net/nfc/core.c                                     |   2 -
 net/nfc/hci/command.c                              |  23 +-
 net/nfc/hci/core.c                                 |  97 +++--
 net/nfc/hci/hci.h                                  |  10 +-
 net/nfc/hci/hcp.c                                  |  11 -
 21 files changed, 886 insertions(+), 149 deletions(-)
 create mode 100644 drivers/nfc/st21nfca/st21nfca_se.c
 create mode 100644 drivers/nfc/st21nfca/st21nfca_se.h

^ permalink raw reply

* Bug in netlink_bind
From: Ivan Delalande @ 2015-01-28 23:46 UTC (permalink / raw)
  To: netdev, pablo

Hi,

I’ve been trying to debug some of our tests that began failing when
upgrading to 3.18. Our actual failure is caused by the condition added
in commit 97840cb to nfnetlink_bind but the bug has probably been
introduced by 0329274.

Our tests execute the following code, at some point:

	localAddr.nl_groups =
		  NF_NETLINK_CONNTRACK_NEW
		| NF_NETLINK_CONNTRACK_UPDATE
		| NF_NETLINK_CONNTRACK_DESTROY;
	int ret = bind(sd, (sockaddr*)&localAddr, sizeof(localAddr));

these constants are from include/uapi/linux/netfilter/nfnetlink_compat.h
and used as a bit set:

	#define NF_NETLINK_CONNTRACK_NEW        0x00000001
	#define NF_NETLINK_CONNTRACK_UPDATE     0x00000002
	#define NF_NETLINK_CONNTRACK_DESTROY    0x00000004

but, if I understand correctly, internally, constants from
include/uapi/linux/netfilter/nfnetlink.h are used instead:

	enum nfnetlink_groups {
		NFNLGRP_NONE,
		NFNLGRP_CONNTRACK_NEW,
		NFNLGRP_CONNTRACK_UPDATE,
		NFNLGRP_CONNTRACK_DESTROY,

	...

	static const int nfnl_group2type[NFNLGRP_MAX+1] = {
		[NFNLGRP_CONNTRACK_NEW]     = NFNL_SUBSYS_CTNETLINK,
		[NFNLGRP_CONNTRACK_UPDATE]  = NFNL_SUBSYS_CTNETLINK,
		[NFNLGRP_CONNTRACK_DESTROY] = NFNL_SUBSYS_CTNETLINK,

Now in netlink_bind (net/netlink/af_netlink.c), our localAddr.nl_groups
value is assigned to the groups variable and tested with test_bit:

	for (group = 0; group < nlk->ngroups; group++) {
		if (!test_bit(group, &groups)) {
			continue;
		}
		err = nlk->netlink_bind(group);

In our case, for group = 0, bit 0 is indeed set because nl_groups was
ORed with NF_NETLINK_CONNTRACK_NEW (= 1), so nlk->netlink_bind is called
with 0, that is nfnetlink_bind(0) (net/netfilter/nfnetlink.c):

	if (group <= NFNLGRP_NONE || group > NFNLGRP_MAX)
		return -EINVAL;

	type = nfnl_group2type[group];

And so, with this condition added by 97840cb, the syscall fails with
EINVAL. But it means that, before this commit, we would have tried to
get nfnl_group2type[0].
In the same way, with NF_NETLINK_CONNTRACK_UPDATE (= 2),
nfnetlink_bind(1) would have been called and fetched nfnl_group2type[1],
which is declared as nfnl_group2type[NFNLGRP_CONNTRACK_NEW] =
NFNL_SUBSYS_CTNETLINK, and so on.

So, am I missing something or are the group values incorrectly
interpreted differently between netlink_bind and nfnetlink_bind, with a
difference of one? I tried a really naive patch and it made this part of
ours tests pass:

	diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
	index b6bf8e8..d2c65b0 100644
	--- a/net/netlink/af_netlink.c
	+++ b/net/netlink/af_netlink.c
	@@ -1479,7 +1479,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
			for (group = 0; group < nlk->ngroups; group++) {
				if (!test_bit(group, &groups))
					continue;
	-                       err = nlk->netlink_bind(group);
	+                       err = nlk->netlink_bind(group + 1);
				if (!err)
					continue;
				netlink_unbind(group, groups, nlk);


But that was really to test if this would fix my problem, I haven’t
really looked if the value nlk->ngroups was still correct with that or
if there was any other nlk->netlink_bind than netlink_bind that would be
affected.

Thanks,
-- 
Ivan "Colona" Delalande
Arista Networks

^ permalink raw reply

* Re: [PATCH net] sunvnet: set queue mapping when doing packet copies
From: Sowmini Varadhan @ 2015-01-28 16:48 UTC (permalink / raw)
  To: David L Stevens; +Cc: David Miller, netdev
In-Reply-To: <54C90AED.7040404@oracle.com>

On (01/28/15 11:14), David L Stevens wrote:
> 
>  This patch fixes a bug where vnet_skb_shape() didn't set the already-selected
>  queue mapping when a packet copy was required. This results in using the
>  wrong queue index for stops/starts, hung tx queues and watchdog timeouts
>  under heavy load.

Acked-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>

^ permalink raw reply

* Re: [PATCH net-next 1/5] tcp: stretch ACK fixes prep
From: David Miller @ 2015-01-28 23:00 UTC (permalink / raw)
  To: ncardwell; +Cc: netdev, ycheng, edumazet
In-Reply-To: <1422390883-15603-2-git-send-email-ncardwell@google.com>

From: Neal Cardwell <ncardwell@google.com>
Date: Tue, 27 Jan 2015 15:34:39 -0500

> -void tcp_slow_start(struct tcp_sock *tp, u32 acked);
 ...
> +int tcp_slow_start(struct tcp_sock *tp, u32 acked);
 ...
 ...
> @@ -360,25 +360,28 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
>   * ABC caps N to 2. Slow start exits when cwnd grows over ssthresh and
>   * returns the leftover acks to adjust cwnd in congestion avoidance mode.
>   */
> -void tcp_slow_start(struct tcp_sock *tp, u32 acked)
> +int tcp_slow_start(struct tcp_sock *tp, u32 acked)
>  {
>  	u32 cwnd = tp->snd_cwnd + acked;
>  
>  	if (cwnd > tp->snd_ssthresh)
>  		cwnd = tp->snd_ssthresh + 1;
> +	acked -= cwnd - tp->snd_cwnd;
>  	tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp);
> +
> +	return acked;
>  }

'acked' is a u32, please have this function return a u32 as well.

In fact in all the call sites the return value gets assigned into a
local u32 variable as well, so I have no idea why you're using 'int'
here.

Thanks.

^ permalink raw reply

* [Patch iproute2] skbedit: print action too
From: Cong Wang @ 2015-01-28 22:52 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang, Jamal Hadi Salim, Stephen Hemminger

Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 tc/m_skbedit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c
index 36323a9..c5deee0 100644
--- a/tc/m_skbedit.c
+++ b/tc/m_skbedit.c
@@ -193,7 +193,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
 		fprintf(f, " mark %d", *mark);
 	}
 
-	fprintf(f, "\n\t index %d ref %d bind %d", p->index, p->refcnt, p->bindcnt);
+	fprintf(f, " %s\n\t index %d ref %d bind %d", action_n2a(p->action, b1, sizeof (b1)), p->index, p->refcnt, p->bindcnt);
 
 	if (show_stats) {
 		if (tb[TCA_SKBEDIT_TM]) {
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH] net, ethernet, LLVMLinux: Add missing MODULE_DEVICE_TABLE()
From: Behan Webster @ 2015-01-29  1:36 UTC (permalink / raw)
  To: sathya.perla
  Cc: behanw, ajit.khaparde, linux-kernel, netdev, subbu.seetharaman,
	Arnd Bergmann

Missing MODULE_DEVICE_TABLE for pci ids from benet driver found by clang.

Signed-off-by: Behan Webster <behanw@converseincode.com>
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Cc: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/ethernet/emulex/benet/be_main.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index d48806b..709400a 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -26,7 +26,6 @@
 #include <net/vxlan.h>
 
 MODULE_VERSION(DRV_VER);
-MODULE_DEVICE_TABLE(pci, be_dev_ids);
 MODULE_DESCRIPTION(DRV_DESC " " DRV_VER);
 MODULE_AUTHOR("Emulex Corporation");
 MODULE_LICENSE("GPL");
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH v2 linux-trace 4/8] samples: bpf: simple tracing example in C
From: Arnaldo Carvalho de Melo @ 2015-01-28 16:24 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Steven Rostedt, Ingo Molnar, Namhyung Kim, Jiri Olsa,
	Masami Hiramatsu, linux-api, netdev, linux-kernel
In-Reply-To: <1422417973-10195-5-git-send-email-ast@plumgrid.com>

Em Tue, Jan 27, 2015 at 08:06:09PM -0800, Alexei Starovoitov escreveu:
> diff --git a/samples/bpf/tracex1_kern.c b/samples/bpf/tracex1_kern.c
> new file mode 100644
> index 000000000000..7849ceb4bce6
> --- /dev/null
> +++ b/samples/bpf/tracex1_kern.c
> @@ -0,0 +1,28 @@
> +#include <linux/skbuff.h>
> +#include <linux/netdevice.h>
> +#include <uapi/linux/bpf.h>
> +#include <trace/bpf_trace.h>
> +#include "bpf_helpers.h"
> +
> +SEC("events/net/netif_receive_skb")
> +int bpf_prog1(struct bpf_context *ctx)
> +{
> +	/*
> +	 * attaches to /sys/kernel/debug/tracing/events/net/netif_receive_skb
> +	 * prints events for loobpack device only
> +	 */
> +	char devname[] = "lo";
> +	struct net_device *dev;
> +	struct sk_buff *skb = 0;
> +
> +	skb = (struct sk_buff *) ctx->arg1;
> +	dev = bpf_fetch_ptr(&skb->dev);
> +	if (bpf_memcmp(dev->name, devname, 2) == 0)

I'm only starting to look at all this, so bear with me... But why do we
need to have it as "bpf_memcmp"? Can't we simply use it as "memcmp" and
have it use the right function?

Less typing, perhaps we would need to have a:

#define memcmp bpf_memcmp(s1, s2, n) bpf_memcmp(s1, s2, n)

in bpf_helpers.h to have it work?

- Arnaldo

> +		/* print event using default tracepoint format */
> +		return 1;
> +
> +	/* drop event */
> +	return 0;
> +}

^ permalink raw reply

* Re: [PATCH] bridge: dont send notification when skb->len == 0 in rtnl_bridge_notify
From: David Miller @ 2015-01-28  7:05 UTC (permalink / raw)
  To: roopa; +Cc: netdev, stephen, rami.rosen
In-Reply-To: <1422423984-29743-1-git-send-email-roopa@cumulusnetworks.com>

From: roopa@cumulusnetworks.com
Date: Tue, 27 Jan 2015 21:46:24 -0800

> From: Roopa Prabhu <roopa@cumulusnetworks.com>
> 
> Reported in: https://bugzilla.kernel.org/show_bug.cgi?id=92081
> 
> This patch avoids calling rtnl_notify if the device ndo_bridge_getlink
> handler does not return any bytes in the skb.
> 
> Alternately, the skb->len check can be moved inside rtnl_notify.
> 
> For the bridge vlan case described in 92081, there is also a fix needed
> in bridge driver to generate a proper notification. Will fix that in
> subsequent patch.
> 
> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>

This doesn't apply to the 'net' tree, is there something I missed?

^ permalink raw reply

* Re: A problem about ICMP packet-too-big message handler
From: Eric Dumazet @ 2015-01-28 12:45 UTC (permalink / raw)
  To: Yang Yingliang; +Cc: Martin Lau, netdev, David S. Miller
In-Reply-To: <54C885D3.70808@huawei.com>

On Wed, 2015-01-28 at 14:46 +0800, Yang Yingliang wrote:
> On 2015/1/28 13:19, Martin Lau wrote:
> > On Tue, Jan 27, 2015 at 08:58:53PM +0800, Yang Yingliang wrote:
> >> Hi,
> >>
> >> My kernel is 3.10 LTS.
> >>
> >> I got a problem here about handling ICMP packet-too-big message.
> >>
> >> Before sending a packet-too-big packet :
> > The expires should be set by the host _receiving_ the icmpv6 too-big.
> > 
> > Can you spell out some details of the outgoing icmpv6 too-big packet?
> > like, the src/dst ip of the icmpv6 and the original ip packet that triggered the
> > too-big.
> > 
> 
> I don't send too-big packet to trigger the err handling.
> 
> I just only send a ICMPv6 packet which type is ICMPV6_PKT_TOOBIG.

You meant : you received an ICMPv6 packet, or you send it ?

^ permalink raw reply

* [PATCH] cxgb4: Remove preprocessor check for CONFIG_CXGB4_DCB
From: Hariprasad Shenai @ 2015-01-28 16:19 UTC (permalink / raw)
  To: netdev; +Cc: davem, leedom, anish, nirranjan, praveenm, Hariprasad Shenai

In commit dc9daab226aa ("cxgb4: Added support in debugfs to dump
sge_qinfo") a preprocessor check for CONFIG_CXGB4_DCB got added, which should
have been CONFIG_CHELSIO_T4_DCB.

Reported-by: Paul Bolle <pebolle@tiscal.nl>
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c |   24 +++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 47c0869..61c000a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -1229,6 +1229,28 @@ static const struct file_operations rss_vf_config_debugfs_fops = {
 	.release = seq_release_private
 };
 
+/**
+ * ethqset2pinfo - return port_info of an Ethernet Queue Set
+ * @adap: the adapter
+ * @qset: Ethernet Queue Set
+ */
+static inline struct port_info *ethqset2pinfo(struct adapter *adap, int qset)
+{
+	int pidx;
+
+	for_each_port(adap, pidx) {
+		struct port_info *pi = adap2pinfo(adap, pidx);
+
+		if (qset >= pi->first_qset &&
+		    qset < pi->first_qset + pi->nqsets)
+			return pi;
+	}
+
+	/* should never happen! */
+	BUG_ON(1);
+	return NULL;
+}
+
 static int sge_qinfo_show(struct seq_file *seq, void *v)
 {
 	struct adapter *adap = seq->private;
@@ -1272,7 +1294,7 @@ do { \
 		T("TxQ inuse:", q.in_use);
 		T("TxQ CIDX:", q.cidx);
 		T("TxQ PIDX:", q.pidx);
-#ifdef CONFIG_CXGB4_DCB
+#ifdef CONFIG_CHELSIO_T4_DCB
 		T("DCB Prio:", dcb_prio);
 		S3("u", "DCB PGID:",
 		   (ethqset2pinfo(adap, base_qset + i)->dcb.pgid >>
-- 
1.7.1

^ permalink raw reply related

* [PATCH 3/3] net: davinci_emac: Get device MAC on 3517
From: Tony Lindgren @ 2015-01-28 19:33 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-omap
In-Reply-To: <1422473586-18100-1-git-send-email-tony@atomide.com>

Looks like on 3517 davinci_emac MAC address registers have a
different layout compared to dm816x and am33xx.

Let's add a function to get the 3517 MAC address.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/boot/dts/am3517.dtsi          |  1 +
 drivers/net/ethernet/ti/davinci_emac.c | 35 +++++++++++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/am3517.dtsi b/arch/arm/boot/dts/am3517.dtsi
index 5a452fd..c90724b 100644
--- a/arch/arm/boot/dts/am3517.dtsi
+++ b/arch/arm/boot/dts/am3517.dtsi
@@ -31,6 +31,7 @@
 			status = "disabled";
 			reg = <0x5c000000 0x30000>;
 			interrupts = <67 68 69 70>;
+			syscon = <&omap3_scm_general>;
 			ti,davinci-ctrl-reg-offset = <0x10000>;
 			ti,davinci-ctrl-mod-reg-offset = <0>;
 			ti,davinci-ctrl-ram-offset = <0x20000>;
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index a716938..aeebc0a 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -52,6 +52,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/semaphore.h>
 #include <linux/phy.h>
 #include <linux/bitops.h>
@@ -65,6 +66,7 @@
 #include <linux/of_mdio.h>
 #include <linux/of_irq.h>
 #include <linux/of_net.h>
+#include <linux/mfd/syscon.h>
 
 #include <asm/irq.h>
 #include <asm/page.h>
@@ -1880,6 +1882,33 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
 	return  pdata;
 }
 
+static int davinci_emac_3517_get_macid(struct device *dev, u16 offset,
+				       int slave, u8 *mac_addr)
+{
+	u32 macid_lsb;
+	u32 macid_msb;
+	struct regmap *syscon;
+
+	syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
+	if (IS_ERR(syscon)) {
+		if (PTR_ERR(syscon) == -ENODEV)
+			return 0;
+		return PTR_ERR(syscon);
+	}
+
+	regmap_read(syscon, offset, &macid_lsb);
+	regmap_read(syscon, offset + 4, &macid_msb);
+
+	mac_addr[0] = (macid_msb >> 16) & 0xff;
+	mac_addr[1] = (macid_msb >> 8)  & 0xff;
+	mac_addr[2] = macid_msb & 0xff;
+	mac_addr[3] = (macid_lsb >> 16) & 0xff;
+	mac_addr[4] = (macid_lsb >> 8)  & 0xff;
+	mac_addr[5] = macid_lsb & 0xff;
+
+	return 0;
+}
+
 static int davinci_emac_try_get_mac(struct platform_device *pdev,
 				    int instance, u8 *mac_addr)
 {
@@ -1888,7 +1917,11 @@ static int davinci_emac_try_get_mac(struct platform_device *pdev,
 	if (!pdev->dev.of_node)
 		return error;
 
-	if (of_device_is_compatible(pdev->dev.of_node, "ti,dm816-emac"))
+	if (of_device_is_compatible(pdev->dev.of_node, "ti,am3517-emac"))
+		error = davinci_emac_3517_get_macid(&pdev->dev, 0x110,
+						    0, mac_addr);
+	else if (of_device_is_compatible(pdev->dev.of_node,
+					 "ti,dm816-emac"))
 		error = cpsw_am33xx_cm_get_macid(&pdev->dev, 0x30,
 						 instance,
 						 mac_addr);
-- 
2.1.4

^ permalink raw reply related

* Re: [patch net-next] hisilicon: add some missing curly braces
From: Ding Tianhong @ 2015-01-29  2:50 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Zhangfei Gao, David S. Miller, Arnd Bergmann, netdev,
	kernel-janitors
In-Reply-To: <20150128185833.GA10259@mwanda>

On 2015/1/29 2:58, Dan Carpenter wrote:
> The if block was supposed to have curly braces.  In the current code we
> complain about dropped rx packets when we shouldn't.
> 
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> 
Acked-by: Ding Tianhong <dingtianhong@huawei.com>

Good catch. thanks;

Hi David, this patch looks good to me, and I was preparing a series patches for hip04,
I could add this patch to the series or you could apply this alone as your wish.:)

Ding

> diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c
> index 525214e..c02b81b 100644
> --- a/drivers/net/ethernet/hisilicon/hip04_eth.c
> +++ b/drivers/net/ethernet/hisilicon/hip04_eth.c
> @@ -567,10 +567,11 @@ static irqreturn_t hip04_mac_interrupt(int irq, void *dev_id)
>  	writel_relaxed(DEF_INT_MASK, priv->base + PPE_RINT);
>  
>  	if (unlikely(ists & DEF_INT_ERR)) {
> -		if (ists & (RCV_NOBUF | RCV_DROP))
> +		if (ists & (RCV_NOBUF | RCV_DROP)) {
>  			stats->rx_errors++;
>  			stats->rx_dropped++;
>  			netdev_err(ndev, "rx drop\n");
> +		}
>  		if (ists & TX_DROP) {
>  			stats->tx_dropped++;
>  			netdev_err(ndev, "tx drop\n");
> 
> 

^ 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