Patch "af_unix: conditionally use freezable blocking calls in read" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
af_unix: conditionally use freezable blocking calls in read
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
af_unix-conditionally-use-freezable-blocking-calls-in-read.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Thu Dec 8 07:18:57 CET 2016
From: WANG Cong <[email protected]>
Date: Thu, 17 Nov 2016 15:55:26 -0800
Subject: af_unix: conditionally use freezable blocking calls in read
From: WANG Cong <[email protected]>
[ Upstream commit 06a77b07e3b44aea2b3c0e64de420ea2cfdcbaa9 ]
Commit 2b15af6f95 ("af_unix: use freezable blocking calls in read") converts schedule_timeout() to its freezable version, it was probably correct at that time, but later, commit 2b514574f7e8 ("net: af_unix: implement splice for stream af_unix sockets") breaks the strong requirement for a freezable sleep, according to commit 0f9548ca1091:
We shouldn't try_to_freeze if locks are held. Holding a lock can cause a deadlock if the lock is later acquired in the suspend or hibernate path (e.g. by dpm). Holding a lock can also cause a deadlock in the case of cgroup_freezer if a lock is held inside a frozen cgroup that is later acquired by a process outside that group.
The pipe_lock is still held at that point.
So use freezable version only for the recvmsg call path, avoid impact for Android.
--- net/unix/af_unix.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
net/unix/af_unix.c +11 -6
@@ -2194,7 +2194,8 @@ out:* Sleep until more data has arrived. But check for races.. */ static long unix_stream_data_wait (struct sock *sk,long timeo, -struct sk_buff *last,unsigned int last_len) +struct sk_buff *last,unsigned int last_len, +bool freezable) {struct sk_buff *tail;DEFINE_WAIT (wait);
@@ -2215,7 +2216,10 @@ static long unix_stream_data_wait(structsk_set_bit (SOCKWQ_ASYNC_WAITDATA , sk);unix_state_unlock (sk); - timeo =freezable_schedule_timeout (timeo); +if (freezable) + timeo =freezable_schedule_timeout (timeo); +else + timeo =schedule_timeout (timeo);unix_state_lock (sk);if (sock_flag (sk,SOCK_DEAD ))
@@ -2245,7 +2249,8 @@ struct unix_stream_read_state {unsigned int splice_flags; }; -static int unix_stream_read_generic (struct unix_stream_read_state *state) +static int unix_stream_read_generic (struct unix_stream_read_state *state, +bool freezable) {struct scm_cookie scm;struct socket *sock = state->socket;
@@ -2324,7 +2329,7 @@ again:mutex_unlock (&u->iolock); timeo =unix_stream_data_wait (sk, timeo, last, - last_len); + last_len, freezable);if (signal_pending (current)) { err =sock_intr_errno (timeo);
@@ -2466,7 +2471,7 @@ static int unix_stream_recvmsg(struct so .flags = flags }; -return unix_stream_read_generic (&state); +return unix_stream_read_generic (&state, true); } static ssize_t skb_unix_socket_splice(struct sock *sk,
@@ -2512,7 +2517,7 @@ static ssize_t unix_stream_splice_read(s flags & SPLICE_F_NONBLOCK) state.flags =MSG_DONTWAIT ; -return unix_stream_read_generic (&state); +return unix_stream_read_generic (&state, false); }static int unix_shutdown (struct socket *sock,int mode)
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/net-sched-respect-rcu-grace-period-on-cls-destruction.patch queue-4.4/af_unix-conditionally-use-freezable-blocking-calls-in-read.patch queue-4.4/netlink-call-cb-done-from-a-worker-thread.patch queue-4.4/net-check-dead-netns-for-peernet2id_alloc.patch