]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 Sep 2019 18:12:50 +0000 (20:12 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 Sep 2019 18:12:50 +0000 (20:12 +0200)
added patches:
tcp-make-sure-epollout-wont-be-missed.patch

queue-4.9/series
queue-4.9/tcp-make-sure-epollout-wont-be-missed.patch [new file with mode: 0644]

index 5ccd9e2029e30e1e4c0ce108475996cbaf595be0..ad568171de789e3cd49c6302f52f2e6a81e542ee 100644 (file)
@@ -55,3 +55,4 @@ scsi-ufs-fix-rx_termination_force_enable-define-valu.patch
 tcp-fix-tcp_rtx_queue_tail-in-case-of-empty-retransm.patch
 alsa-usb-audio-fix-a-stack-buffer-overflow-bug-in-check_input_term.patch
 alsa-usb-audio-fix-an-oob-bug-in-parse_audio_mixer_unit.patch
+tcp-make-sure-epollout-wont-be-missed.patch
diff --git a/queue-4.9/tcp-make-sure-epollout-wont-be-missed.patch b/queue-4.9/tcp-make-sure-epollout-wont-be-missed.patch
new file mode 100644 (file)
index 0000000..6b7d31f
--- /dev/null
@@ -0,0 +1,82 @@
+From foo@baz Mon 02 Sep 2019 08:05:10 PM CEST
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 16 Aug 2019 21:26:22 -0700
+Subject: tcp: make sure EPOLLOUT wont be missed
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit ef8d8ccdc216f797e66cb4a1372f5c4c285ce1e4 ]
+
+As Jason Baron explained in commit 790ba4566c1a ("tcp: set SOCK_NOSPACE
+under memory pressure"), it is crucial we properly set SOCK_NOSPACE
+when needed.
+
+However, Jason patch had a bug, because the 'nonblocking' status
+as far as sk_stream_wait_memory() is concerned is governed
+by MSG_DONTWAIT flag passed at sendmsg() time :
+
+    long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
+
+So it is very possible that tcp sendmsg() calls sk_stream_wait_memory(),
+and that sk_stream_wait_memory() returns -EAGAIN with SOCK_NOSPACE
+cleared, if sk->sk_sndtimeo has been set to a small (but not zero)
+value.
+
+This patch removes the 'noblock' variable since we must always
+set SOCK_NOSPACE if -EAGAIN is returned.
+
+It also renames the do_nonblock label since we might reach this
+code path even if we were in blocking mode.
+
+Fixes: 790ba4566c1a ("tcp: set SOCK_NOSPACE under memory pressure")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Jason Baron <jbaron@akamai.com>
+Reported-by: Vladimir Rutsky  <rutsky@google.com>
+Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Acked-by: Jason Baron <jbaron@akamai.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/stream.c |   16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+--- a/net/core/stream.c
++++ b/net/core/stream.c
+@@ -118,7 +118,6 @@ int sk_stream_wait_memory(struct sock *s
+       int err = 0;
+       long vm_wait = 0;
+       long current_timeo = *timeo_p;
+-      bool noblock = (*timeo_p ? false : true);
+       DEFINE_WAIT(wait);
+       if (sk_stream_memory_free(sk))
+@@ -131,11 +130,8 @@ int sk_stream_wait_memory(struct sock *s
+               if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
+                       goto do_error;
+-              if (!*timeo_p) {
+-                      if (noblock)
+-                              set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+-                      goto do_nonblock;
+-              }
++              if (!*timeo_p)
++                      goto do_eagain;
+               if (signal_pending(current))
+                       goto do_interrupted;
+               sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
+@@ -167,7 +163,13 @@ out:
+ do_error:
+       err = -EPIPE;
+       goto out;
+-do_nonblock:
++do_eagain:
++      /* Make sure that whenever EAGAIN is returned, EPOLLOUT event can
++       * be generated later.
++       * When TCP receives ACK packets that make room, tcp_check_space()
++       * only calls tcp_new_space() if SOCK_NOSPACE is set.
++       */
++      set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+       err = -EAGAIN;
+       goto out;
+ do_interrupted: