[PATCH net] af_unix: Avoid a wakeup if data has been not arrived

From: Bin Zhong
Date: Wed Jan 10 2024 - 03:47:22 EST


In the following scenarios, unnecessary wake-up may occur.
When a thread sends a piece of data and then immediately
calls recv to wait for the server's data, the server, upon
receiving this thread's data, calls back unix_write_space
to wake up this thread.

Therefore, add the filtering conditions of EPOLLIN and
EPOLLERR in the callback function of the waiting queue in
the unix_stream_data_wait function to reduce unnecessary
wake-ups.

Signed-off-by: Bin Zhong <zhongbin@xxxxxxxxxxxxx>
---
net/unix/af_unix.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index ac1f2bc18fc9..bd4e7beb02d5 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2500,6 +2500,14 @@ static int unix_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
return recv_actor(sk, skb);
}

+static int unix_stream_data_wake_function(wait_queue_entry_t *wait, unsigned int mode,
+ int sync, void *key)
+{
+ if (key && !(key_to_poll(key) & (EPOLLIN | EPOLLERR)))
+ return 0;
+ return autoremove_wake_function(wait, mode, sync, key);
+}
+
/*
* Sleep until more data has arrived. But check for races..
*/
@@ -2509,7 +2517,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo,
{
unsigned int state = TASK_INTERRUPTIBLE | freezable * TASK_FREEZABLE;
struct sk_buff *tail;
- DEFINE_WAIT(wait);
+ DEFINE_WAIT_FUNC(wait, unix_stream_data_wake_function);

unix_state_lock(sk);

--
2.25.1