From da8fc7a39be897426e1ac05aa90263abf40621b7 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Sat, 15 Nov 2025 02:08:34 +0000 Subject: af_unix: Don't trigger GC from close() if unnecessary. We have been triggering GC on every close() if there is even one inflight AF_UNIX socket. This is because the old GC implementation had no idea of the graph shape formed by SCM_RIGHTS references. The new GC knows whether there could be a cyclic reference or not, and we can do better. Let's not trigger GC from close() if there is no cyclic reference or GC is already in progress. While at it, unix_gc() is renamed to unix_schedule_gc() as it does not actually perform GC since commit 8b90a9f819dc ("af_unix: Run GC on only one CPU."). Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20251115020935.2643121-4-kuniyu@google.com Signed-off-by: Jakub Kicinski --- net/unix/af_unix.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'net/unix/af_unix.h') diff --git a/net/unix/af_unix.h b/net/unix/af_unix.h index 59db179df9bb..0fb5b348ad94 100644 --- a/net/unix/af_unix.h +++ b/net/unix/af_unix.h @@ -24,13 +24,12 @@ struct unix_skb_parms { #define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb)) /* GC for SCM_RIGHTS */ -extern unsigned int unix_tot_inflight; void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver); void unix_del_edges(struct scm_fp_list *fpl); void unix_update_edges(struct unix_sock *receiver); int unix_prepare_fpl(struct scm_fp_list *fpl); void unix_destroy_fpl(struct scm_fp_list *fpl); -void unix_gc(void); +void unix_schedule_gc(void); void wait_for_unix_gc(struct scm_fp_list *fpl); /* SOCK_DIAG */ -- cgit From 384900542dc85f3aac7918fea8e7ef62141e3ea6 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Sat, 15 Nov 2025 02:08:35 +0000 Subject: af_unix: Don't call wait_for_unix_gc() on every sendmsg(). We have been calling wait_for_unix_gc() on every sendmsg() in case there are too many inflight AF_UNIX sockets. This is also because the old GC implementation had poor knowledge of the inflight sockets and had to suspect every sendmsg(). This was improved by commit d9f21b361333 ("af_unix: Try to run GC async."), but we do not even need to call wait_for_unix_gc() if the process is not sending AF_UNIX sockets. The wait_for_unix_gc() call only helps when a malicious process continues to create cyclic references, and we can detect that in a better place and slow it down. Let's move wait_for_unix_gc() to unix_prepare_fpl() that is called only when AF_UNIX socket fd is passed via SCM_RIGHTS. Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20251115020935.2643121-5-kuniyu@google.com Signed-off-by: Jakub Kicinski --- net/unix/af_unix.h | 1 - 1 file changed, 1 deletion(-) (limited to 'net/unix/af_unix.h') diff --git a/net/unix/af_unix.h b/net/unix/af_unix.h index 0fb5b348ad94..2f1bfe3217c1 100644 --- a/net/unix/af_unix.h +++ b/net/unix/af_unix.h @@ -30,7 +30,6 @@ void unix_update_edges(struct unix_sock *receiver); int unix_prepare_fpl(struct scm_fp_list *fpl); void unix_destroy_fpl(struct scm_fp_list *fpl); void unix_schedule_gc(void); -void wait_for_unix_gc(struct scm_fp_list *fpl); /* SOCK_DIAG */ long unix_inq_len(struct sock *sk); -- cgit From 24fa77dad25c2f55cc4615c09df2201ef72c66f4 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Sat, 15 Nov 2025 02:08:38 +0000 Subject: af_unix: Consolidate unix_schedule_gc() and wait_for_unix_gc(). unix_schedule_gc() and wait_for_unix_gc() share some code. Let's consolidate the two. Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20251115020935.2643121-8-kuniyu@google.com Signed-off-by: Jakub Kicinski --- net/unix/af_unix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/unix/af_unix.h') diff --git a/net/unix/af_unix.h b/net/unix/af_unix.h index 2f1bfe3217c1..c4f1b2da363d 100644 --- a/net/unix/af_unix.h +++ b/net/unix/af_unix.h @@ -29,7 +29,7 @@ void unix_del_edges(struct scm_fp_list *fpl); void unix_update_edges(struct unix_sock *receiver); int unix_prepare_fpl(struct scm_fp_list *fpl); void unix_destroy_fpl(struct scm_fp_list *fpl); -void unix_schedule_gc(void); +void unix_schedule_gc(struct user_struct *user); /* SOCK_DIAG */ long unix_inq_len(struct sock *sk); -- cgit