aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/garbage.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/unix/garbage.c')
-rw-r--r--net/unix/garbage.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index 19c17e4a0c8b..f89f83bf828e 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -74,7 +74,6 @@
74#include <linux/un.h> 74#include <linux/un.h>
75#include <linux/net.h> 75#include <linux/net.h>
76#include <linux/fs.h> 76#include <linux/fs.h>
77#include <linux/slab.h>
78#include <linux/skbuff.h> 77#include <linux/skbuff.h>
79#include <linux/netdevice.h> 78#include <linux/netdevice.h>
80#include <linux/file.h> 79#include <linux/file.h>
@@ -97,7 +96,7 @@ static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait);
97unsigned int unix_tot_inflight; 96unsigned int unix_tot_inflight;
98 97
99 98
100static struct sock *unix_get_socket(struct file *filp) 99struct sock *unix_get_socket(struct file *filp)
101{ 100{
102 struct sock *u_sock = NULL; 101 struct sock *u_sock = NULL;
103 struct inode *inode = filp->f_path.dentry->d_inode; 102 struct inode *inode = filp->f_path.dentry->d_inode;
@@ -154,15 +153,6 @@ void unix_notinflight(struct file *fp)
154 } 153 }
155} 154}
156 155
157static inline struct sk_buff *sock_queue_head(struct sock *sk)
158{
159 return (struct sk_buff *)&sk->sk_receive_queue;
160}
161
162#define receive_queue_for_each_skb(sk, next, skb) \
163 for (skb = sock_queue_head(sk)->next, next = skb->next; \
164 skb != sock_queue_head(sk); skb = next, next = skb->next)
165
166static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), 156static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
167 struct sk_buff_head *hitlist) 157 struct sk_buff_head *hitlist)
168{ 158{
@@ -170,7 +160,7 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
170 struct sk_buff *next; 160 struct sk_buff *next;
171 161
172 spin_lock(&x->sk_receive_queue.lock); 162 spin_lock(&x->sk_receive_queue.lock);
173 receive_queue_for_each_skb(x, next, skb) { 163 skb_queue_walk_safe(&x->sk_receive_queue, skb, next) {
174 /* 164 /*
175 * Do we have file descriptors ? 165 * Do we have file descriptors ?
176 */ 166 */
@@ -226,7 +216,7 @@ static void scan_children(struct sock *x, void (*func)(struct unix_sock *),
226 * and perform a scan on them as well. 216 * and perform a scan on them as well.
227 */ 217 */
228 spin_lock(&x->sk_receive_queue.lock); 218 spin_lock(&x->sk_receive_queue.lock);
229 receive_queue_for_each_skb(x, next, skb) { 219 skb_queue_walk_safe(&x->sk_receive_queue, skb, next) {
230 u = unix_sk(skb->sk); 220 u = unix_sk(skb->sk);
231 221
232 /* 222 /*
@@ -269,9 +259,16 @@ static void inc_inflight_move_tail(struct unix_sock *u)
269} 259}
270 260
271static bool gc_in_progress = false; 261static bool gc_in_progress = false;
262#define UNIX_INFLIGHT_TRIGGER_GC 16000
272 263
273void wait_for_unix_gc(void) 264void wait_for_unix_gc(void)
274{ 265{
266 /*
267 * If number of inflight sockets is insane,
268 * force a garbage collect right now.
269 */
270 if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress)
271 unix_gc();
275 wait_event(unix_gc_wait, gc_in_progress == false); 272 wait_event(unix_gc_wait, gc_in_progress == false);
276} 273}
277 274