From e27dfcea48372a4105d9fdf2e8450926737f6215 Mon Sep 17 00:00:00 2001 From: Jianjun Kong Date: Sat, 1 Nov 2008 21:38:31 -0700 Subject: af_unix: clean up net/unix/af_unix.c garbage.c sysctl_net_unix.c clean up net/unix/af_unix.c garbage.c sysctl_net_unix.c Signed-off-by: Jianjun Kong Signed-off-by: David S. Miller --- net/unix/garbage.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'net/unix/garbage.c') diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 2a27b84f740b..00734e22ec15 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -104,8 +104,8 @@ static struct sock *unix_get_socket(struct file *filp) * Socket ? */ if (S_ISSOCK(inode->i_mode)) { - struct socket * sock = SOCKET_I(inode); - struct sock * s = sock->sk; + struct socket *sock = SOCKET_I(inode); + struct sock *s = sock->sk; /* * PF_UNIX ? @@ -124,7 +124,7 @@ static struct sock *unix_get_socket(struct file *filp) void unix_inflight(struct file *fp) { struct sock *s = unix_get_socket(fp); - if(s) { + if (s) { struct unix_sock *u = unix_sk(s); spin_lock(&unix_gc_lock); if (atomic_long_inc_return(&u->inflight) == 1) { @@ -141,7 +141,7 @@ void unix_inflight(struct file *fp) void unix_notinflight(struct file *fp) { struct sock *s = unix_get_socket(fp); - if(s) { + if (s) { struct unix_sock *u = unix_sk(s); spin_lock(&unix_gc_lock); BUG_ON(list_empty(&u->link)); @@ -154,7 +154,7 @@ void unix_notinflight(struct file *fp) static inline struct sk_buff *sock_queue_head(struct sock *sk) { - return (struct sk_buff *) &sk->sk_receive_queue; + return (struct sk_buff *)&sk->sk_receive_queue; } #define receive_queue_for_each_skb(sk, next, skb) \ @@ -339,7 +339,7 @@ void unix_gc(void) */ skb_queue_head_init(&hitlist); list_for_each_entry(u, &gc_candidates, link) - scan_children(&u->sk, inc_inflight, &hitlist); + scan_children(&u->sk, inc_inflight, &hitlist); spin_unlock(&unix_gc_lock); -- cgit v1.2.2 From 5f23b734963ec7eaa3ebcd9050da0c9b7d143dd3 Mon Sep 17 00:00:00 2001 From: dann frazier Date: Wed, 26 Nov 2008 15:32:27 -0800 Subject: net: Fix soft lockups/OOM issues w/ unix garbage collector This is an implementation of David Miller's suggested fix in: https://bugzilla.redhat.com/show_bug.cgi?id=470201 It has been updated to use wait_event() instead of wait_event_interruptible(). Paraphrasing the description from the above report, it makes sendmsg() block while UNIX garbage collection is in progress. This avoids a situation where child processes continue to queue new FDs over a AF_UNIX socket to a parent which is in the exit path and running garbage collection on these FDs. This contention can result in soft lockups and oom-killing of unrelated processes. Signed-off-by: dann frazier Signed-off-by: David S. Miller --- net/unix/garbage.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'net/unix/garbage.c') diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 6d4a9a8de5ef..abb3ab34cb1e 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -80,6 +80,7 @@ #include #include #include +#include #include #include @@ -91,6 +92,7 @@ static LIST_HEAD(gc_inflight_list); static LIST_HEAD(gc_candidates); static DEFINE_SPINLOCK(unix_gc_lock); +static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait); unsigned int unix_tot_inflight; @@ -266,12 +268,16 @@ static void inc_inflight_move_tail(struct unix_sock *u) list_move_tail(&u->link, &gc_candidates); } -/* The external entry point: unix_gc() */ +static bool gc_in_progress = false; -void unix_gc(void) +void wait_for_unix_gc(void) { - static bool gc_in_progress = false; + wait_event(unix_gc_wait, gc_in_progress == false); +} +/* The external entry point: unix_gc() */ +void unix_gc(void) +{ struct unix_sock *u; struct unix_sock *next; struct sk_buff_head hitlist; @@ -376,6 +382,7 @@ void unix_gc(void) /* All candidates should have been detached by now. */ BUG_ON(!list_empty(&gc_candidates)); gc_in_progress = false; + wake_up(&unix_gc_wait); out: spin_unlock(&unix_gc_lock); -- cgit v1.2.2