--- /dev/null
+From 0b9aefea860063bb39e36bd7fe6c7087fed0ba87 Mon Sep 17 00:00:00 2001
+From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Date: Sat, 1 Apr 2017 11:00:21 -0300
+Subject: tcp: minimize false-positives on TCP/GRO check
+
+From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+
+commit 0b9aefea860063bb39e36bd7fe6c7087fed0ba87 upstream.
+
+Markus Trippelsdorf reported that after commit dcb17d22e1c2 ("tcp: warn
+on bogus MSS and try to amend it") the kernel started logging the
+warning for a NIC driver that doesn't even support GRO.
+
+It was diagnosed that it was possibly caused on connections that were
+using TCP Timestamps but some packets lacked the Timestamps option. As
+we reduce rcv_mss when timestamps are used, the lack of them would cause
+the packets to be bigger than expected, although this is a valid case.
+
+As this warning is more as a hint, getting a clean-cut on the
+threshold is probably not worth the execution time spent on it. This
+patch thus alleviates the false-positives with 2 quick checks: by
+accounting for the entire TCP option space and also checking against the
+interface MTU if it's available.
+
+These changes, specially the MTU one, might mask some real positives,
+though if they are really happening, it's possible that sooner or later
+it will be triggered anyway.
+
+Reported-by: Markus Trippelsdorf <markus@trippelsdorf.de>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Salvatore Bonaccorso <carnil@debian.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv4/tcp_input.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -129,7 +129,8 @@ int sysctl_tcp_invalid_ratelimit __read_
+ #define REXMIT_LOST 1 /* retransmit packets marked lost */
+ #define REXMIT_NEW 2 /* FRTO-style transmit of unsent/new packets */
+
+-static void tcp_gro_dev_warn(struct sock *sk, const struct sk_buff *skb)
++static void tcp_gro_dev_warn(struct sock *sk, const struct sk_buff *skb,
++ unsigned int len)
+ {
+ static bool __once __read_mostly;
+
+@@ -140,8 +141,9 @@ static void tcp_gro_dev_warn(struct sock
+
+ rcu_read_lock();
+ dev = dev_get_by_index_rcu(sock_net(sk), skb->skb_iif);
+- pr_warn("%s: Driver has suspect GRO implementation, TCP performance may be compromised.\n",
+- dev ? dev->name : "Unknown driver");
++ if (!dev || len >= dev->mtu)
++ pr_warn("%s: Driver has suspect GRO implementation, TCP performance may be compromised.\n",
++ dev ? dev->name : "Unknown driver");
+ rcu_read_unlock();
+ }
+ }
+@@ -164,8 +166,10 @@ static void tcp_measure_rcv_mss(struct s
+ if (len >= icsk->icsk_ack.rcv_mss) {
+ icsk->icsk_ack.rcv_mss = min_t(unsigned int, len,
+ tcp_sk(sk)->advmss);
+- if (unlikely(icsk->icsk_ack.rcv_mss != len))
+- tcp_gro_dev_warn(sk, skb);
++ /* Account for possibly-removed options */
++ if (unlikely(len > icsk->icsk_ack.rcv_mss +
++ MAX_TCP_OPTION_SPACE))
++ tcp_gro_dev_warn(sk, skb, len);
+ } else {
+ /* Otherwise, we make more careful check taking into account,
+ * that SACKs block is variable.