netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kuniyuki Iwashima <kuniyu@amazon.com>
To: "David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Kuniyuki Iwashima <kuniyu@amazon.com>,
	Kuniyuki Iwashima <kuni1840@gmail.com>, <netdev@vger.kernel.org>
Subject: [PATCH v1 net-next 02/16] af_unix: Allocate struct unix_edge for each inflight AF_UNIX fd.
Date: Fri, 2 Feb 2024 19:00:44 -0800	[thread overview]
Message-ID: <20240203030058.60750-3-kuniyu@amazon.com> (raw)
In-Reply-To: <20240203030058.60750-1-kuniyu@amazon.com>

When we send fd using SCM_RIGHTS message, we allocate struct
scm_fp_list to struct scm_cookie in scm_fp_copy().  Also, we bump
each refcount of the inflight fds' struct file and save them in
scm_fp_list.fp.

Later, we clone scm_fp_list of scm_cookie and set it to skb in
unix_attach_fds().

Then, we just preallocate to skb's scm_fp_list an array of struct
unix_edge in the number of inflight AF_UNIX fds and do not use them
there because sendmsg() could fail after this point.  The actual
use will be in the next patch.

When we queue skb with inflight edges, we will set the inflight
socket's unix_vertex as unix_edge->predecessor and the receiver's
vertex as successor, and then we will link the edge to the inflight
socket's unix_vertex.edges.

Note that we set NULL to cloned scm_fp_list.edges in scm_fp_dup()
so that MSG_PEEK does not change the shape of the directed graph.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 include/net/af_unix.h |  8 ++++++++
 include/net/scm.h     |  7 +++++++
 net/core/scm.c        |  3 +++
 net/unix/af_unix.c    |  5 +++++
 net/unix/garbage.c    | 18 ++++++++++++++++++
 5 files changed, 41 insertions(+)

diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 664f6bff60ab..cab9dfb666f3 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -23,6 +23,8 @@ extern unsigned int unix_tot_inflight;
 void unix_inflight(struct user_struct *user, struct file *fp);
 void unix_notinflight(struct user_struct *user, struct file *fp);
 void unix_init_vertex(struct unix_sock *u);
+int unix_alloc_edges(struct scm_fp_list *fpl);
+void unix_free_edges(struct scm_fp_list *fpl);
 void unix_gc(void);
 void wait_for_unix_gc(struct scm_fp_list *fpl);
 
@@ -32,6 +34,12 @@ struct unix_vertex {
 	unsigned long out_degree;
 };
 
+struct unix_edge {
+	struct unix_vertex *predecessor;
+	struct unix_vertex *successor;
+	struct list_head entry;
+};
+
 struct sock *unix_peer_get(struct sock *sk);
 
 #define UNIX_HASH_MOD	(256 - 1)
diff --git a/include/net/scm.h b/include/net/scm.h
index 92276a2c5543..a1142dee086c 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -23,10 +23,17 @@ struct scm_creds {
 	kgid_t	gid;
 };
 
+#ifdef CONFIG_UNIX
+struct unix_edge;
+#endif
+
 struct scm_fp_list {
 	short			count;
 	short			count_unix;
 	short			max;
+#ifdef CONFIG_UNIX
+	struct unix_edge	*edges;
+#endif
 	struct user_struct	*user;
 	struct file		*fp[SCM_MAX_FD];
 };
diff --git a/net/core/scm.c b/net/core/scm.c
index 9cd4b0a01cd6..8661524ed6e5 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -87,6 +87,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
 		*fplp = fpl;
 		fpl->count = 0;
 		fpl->count_unix = 0;
+		fpl->edges = NULL;
 		fpl->max = SCM_MAX_FD;
 		fpl->user = NULL;
 	}
@@ -376,6 +377,8 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 	if (new_fpl) {
 		for (i = 0; i < fpl->count; i++)
 			get_file(fpl->fp[i]);
+
+		new_fpl->edges = NULL;
 		new_fpl->max = new_fpl->count;
 		new_fpl->user = get_uid(fpl->user);
 	}
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index ae145b6f77d8..0391f66546a6 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1819,6 +1819,9 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
 	for (i = scm->fp->count - 1; i >= 0; i--)
 		unix_inflight(scm->fp->user, scm->fp->fp[i]);
 
+	if (unix_alloc_edges(UNIXCB(skb).fp))
+		return -ENOMEM;
+
 	return 0;
 }
 
@@ -1829,6 +1832,8 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
 	scm->fp = UNIXCB(skb).fp;
 	UNIXCB(skb).fp = NULL;
 
+	unix_free_edges(scm->fp);
+
 	for (i = scm->fp->count - 1; i >= 0; i--)
 		unix_notinflight(scm->fp->user, scm->fp->fp[i]);
 }
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index db9ac289ce08..6a3572e43b9f 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -110,6 +110,24 @@ void unix_init_vertex(struct unix_sock *u)
 	INIT_LIST_HEAD(&vertex->entry);
 }
 
+int unix_alloc_edges(struct scm_fp_list *fpl)
+{
+	if (!fpl->count_unix)
+		return 0;
+
+	fpl->edges = kvmalloc_array(fpl->count_unix, sizeof(*fpl->edges),
+				    GFP_KERNEL_ACCOUNT);
+	if (!fpl->edges)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void unix_free_edges(struct scm_fp_list *fpl)
+{
+	kvfree(fpl->edges);
+}
+
 DEFINE_SPINLOCK(unix_gc_lock);
 unsigned int unix_tot_inflight;
 static LIST_HEAD(gc_candidates);
-- 
2.30.2


  parent reply	other threads:[~2024-02-03  3:02 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-03  3:00 [PATCH v1 net-next 00/16] af_unix: Reimplment GC Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 01/16] af_unix: Add struct unix_vertex in struct unix_sock Kuniyuki Iwashima
2024-02-03  3:00 ` Kuniyuki Iwashima [this message]
2024-02-03 20:20   ` [PATCH v1 net-next 02/16] af_unix: Allocate struct unix_edge for each inflight AF_UNIX fd kernel test robot
2024-02-03  3:00 ` [PATCH v1 net-next 03/16] af_unix: Link struct unix_edge when queuing skb Kuniyuki Iwashima
2024-02-20 12:06   ` Paolo Abeni
2024-02-03  3:00 ` [PATCH v1 net-next 04/16] af_unix: Save listener for embryo socket Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 05/16] af_unix: Fix up unix_edge.successor " Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 06/16] af_unix: Bulk update unix_tot_inflight/unix_inflight when queuing skb Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 07/16] af_unix: Detect Strongly Connected Components Kuniyuki Iwashima
2024-02-03 19:59   ` kernel test robot
2024-02-03 21:36   ` kernel test robot
2024-02-03  3:00 ` [PATCH v1 net-next 08/16] af_unix: Save O(n) setup of Tarjan's algo Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 09/16] af_unix: Avoid Tarjan's algorithm if unnecessary Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 10/16] af_unix: Skip GC if no cycle exists Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 11/16] af_unix: Assign a unique index to SCC Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 12/16] af_unix: Detect dead SCC Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 13/16] af_unix: Replace garbage collection algorithm Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 14/16] af_unix: Remove scm_fp_dup() in unix_attach_fds() Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 15/16] af_unix: Remove lock dance in unix_peek_fds() Kuniyuki Iwashima
2024-02-03  3:00 ` [PATCH v1 net-next 16/16] selftest: af_unix: Test GC for SCM_RIGHTS Kuniyuki Iwashima

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240203030058.60750-3-kuniyu@amazon.com \
    --to=kuniyu@amazon.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=kuni1840@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).