unix_schedule_gc() and wait_for_unix_gc() share some code. Let's consolidate the two. Signed-off-by: Kuniyuki Iwashima --- net/unix/af_unix.c | 2 +- net/unix/af_unix.h | 2 +- net/unix/garbage.c | 28 +++++++++------------------- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 34952242bd81..e518116f8171 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -733,7 +733,7 @@ static void unix_release_sock(struct sock *sk, int embrion) /* ---- Socket is dead now and most probably destroyed ---- */ - unix_schedule_gc(); + unix_schedule_gc(NULL); } struct unix_peercred { 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); diff --git a/net/unix/garbage.c b/net/unix/garbage.c index fe1f74345b66..78323d43e63e 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -279,8 +279,6 @@ void unix_update_edges(struct unix_sock *receiver) } } -static void wait_for_unix_gc(struct scm_fp_list *fpl); - int unix_prepare_fpl(struct scm_fp_list *fpl) { struct unix_vertex *vertex; @@ -302,7 +300,7 @@ int unix_prepare_fpl(struct scm_fp_list *fpl) if (!fpl->edges) goto err; - wait_for_unix_gc(fpl); + unix_schedule_gc(fpl->user); return 0; @@ -614,21 +612,9 @@ static void unix_gc(struct work_struct *work) static DECLARE_WORK(unix_gc_work, unix_gc); -void unix_schedule_gc(void) -{ - if (READ_ONCE(unix_graph_state) == UNIX_GRAPH_NOT_CYCLIC) - return; - - if (READ_ONCE(gc_in_progress)) - return; - - WRITE_ONCE(gc_in_progress, true); - queue_work(system_dfl_wq, &unix_gc_work); -} - #define UNIX_INFLIGHT_SANE_USER (SCM_MAX_FD * 8) -static void wait_for_unix_gc(struct scm_fp_list *fpl) +void unix_schedule_gc(struct user_struct *user) { if (READ_ONCE(unix_graph_state) == UNIX_GRAPH_NOT_CYCLIC) return; @@ -636,11 +622,15 @@ static void wait_for_unix_gc(struct scm_fp_list *fpl) /* Penalise users who want to send AF_UNIX sockets * but whose sockets have not been received yet. */ - if (READ_ONCE(fpl->user->unix_inflight) < UNIX_INFLIGHT_SANE_USER) + if (user && + READ_ONCE(user->unix_inflight) < UNIX_INFLIGHT_SANE_USER) return; - unix_schedule_gc(); + if (!READ_ONCE(gc_in_progress)) { + WRITE_ONCE(gc_in_progress, true); + queue_work(system_dfl_wq, &unix_gc_work); + } - if (READ_ONCE(unix_graph_cyclic_sccs)) + if (user && READ_ONCE(unix_graph_cyclic_sccs)) flush_work(&unix_gc_work); } -- 2.52.0.rc1.455.g30608eb744-goog