Commit 4090fa37 authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Jakub Kicinski

af_unix: Replace garbage collection algorithm.

If we find a dead SCC during iteration, we call unix_collect_skb()
to splice all skb in the SCC to the global sk_buff_head, hitlist.

After iterating all SCC, we unlock unix_gc_lock and purge the queue.
Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Acked-by: default avatarPaolo Abeni <pabeni@redhat.com>
Link: https://lore.kernel.org/r/20240325202425.60930-15-kuniyu@amazon.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a15702d8
...@@ -19,9 +19,6 @@ static inline struct unix_sock *unix_get_socket(struct file *filp) ...@@ -19,9 +19,6 @@ static inline struct unix_sock *unix_get_socket(struct file *filp)
extern spinlock_t unix_gc_lock; extern spinlock_t unix_gc_lock;
extern unsigned int unix_tot_inflight; 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_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver); void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver);
void unix_del_edges(struct scm_fp_list *fpl); void unix_del_edges(struct scm_fp_list *fpl);
void unix_update_edges(struct unix_sock *receiver); void unix_update_edges(struct unix_sock *receiver);
...@@ -85,12 +82,7 @@ struct unix_sock { ...@@ -85,12 +82,7 @@ struct unix_sock {
struct sock *peer; struct sock *peer;
struct sock *listener; struct sock *listener;
struct unix_vertex *vertex; struct unix_vertex *vertex;
struct list_head link;
unsigned long inflight;
spinlock_t lock; spinlock_t lock;
unsigned long gc_flags;
#define UNIX_GC_CANDIDATE 0
#define UNIX_GC_MAYBE_CYCLE 1
struct socket_wq peer_wq; struct socket_wq peer_wq;
wait_queue_entry_t peer_wake; wait_queue_entry_t peer_wake;
struct scm_stat scm_stat; struct scm_stat scm_stat;
......
...@@ -980,12 +980,10 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, ...@@ -980,12 +980,10 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern,
sk->sk_destruct = unix_sock_destructor; sk->sk_destruct = unix_sock_destructor;
u = unix_sk(sk); u = unix_sk(sk);
u->listener = NULL; u->listener = NULL;
u->inflight = 0;
u->vertex = NULL; u->vertex = NULL;
u->path.dentry = NULL; u->path.dentry = NULL;
u->path.mnt = NULL; u->path.mnt = NULL;
spin_lock_init(&u->lock); spin_lock_init(&u->lock);
INIT_LIST_HEAD(&u->link);
mutex_init(&u->iolock); /* single task reading lock */ mutex_init(&u->iolock); /* single task reading lock */
mutex_init(&u->bindlock); /* single task binding lock */ mutex_init(&u->bindlock); /* single task binding lock */
init_waitqueue_head(&u->peer_wait); init_waitqueue_head(&u->peer_wait);
...@@ -1793,8 +1791,6 @@ static inline bool too_many_unix_fds(struct task_struct *p) ...@@ -1793,8 +1791,6 @@ static inline bool too_many_unix_fds(struct task_struct *p)
static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
{ {
int i;
if (too_many_unix_fds(current)) if (too_many_unix_fds(current))
return -ETOOMANYREFS; return -ETOOMANYREFS;
...@@ -1806,9 +1802,6 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) ...@@ -1806,9 +1802,6 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
if (!UNIXCB(skb).fp) if (!UNIXCB(skb).fp)
return -ENOMEM; return -ENOMEM;
for (i = scm->fp->count - 1; i >= 0; i--)
unix_inflight(scm->fp->user, scm->fp->fp[i]);
if (unix_prepare_fpl(UNIXCB(skb).fp)) if (unix_prepare_fpl(UNIXCB(skb).fp))
return -ENOMEM; return -ENOMEM;
...@@ -1817,15 +1810,10 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) ...@@ -1817,15 +1810,10 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb) static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
{ {
int i;
scm->fp = UNIXCB(skb).fp; scm->fp = UNIXCB(skb).fp;
UNIXCB(skb).fp = NULL; UNIXCB(skb).fp = NULL;
unix_destroy_fpl(scm->fp); unix_destroy_fpl(scm->fp);
for (i = scm->fp->count - 1; i >= 0; i--)
unix_notinflight(scm->fp->user, scm->fp->fp[i]);
} }
static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb) static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb)
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment