71 #include <linux/kernel.h>
72 #include <linux/string.h>
73 #include <linux/socket.h>
75 #include <linux/net.h>
78 #include <linux/netdevice.h>
82 #include <linux/wait.h>
109 struct sock *
s = sock->
sk;
130 spin_lock(&unix_gc_lock);
131 if (atomic_long_inc_return(&u->
inflight) == 1) {
138 spin_unlock(&unix_gc_lock);
147 spin_lock(&unix_gc_lock);
149 if (atomic_long_dec_and_test(&u->
inflight))
150 list_del_init(&u->
link);
152 spin_unlock(&unix_gc_lock);
172 int nfd =
UNIXCB(skb).fp->count;
194 if (hit && hitlist !=
NULL) {
196 __skb_queue_tail(hitlist, skb);
207 scan_inflight(x,
func, hitlist);
231 while (!list_empty(&embryos)) {
233 scan_inflight(&u->
sk,
func, hitlist);
234 list_del_init(&u->
link);
239 static void dec_inflight(
struct unix_sock *usk)
244 static void inc_inflight(
struct unix_sock *usk)
249 static void inc_inflight_move_tail(
struct unix_sock *u)
258 list_move_tail(&u->
link, &gc_candidates);
261 static bool gc_in_progress =
false;
262 #define UNIX_INFLIGHT_TRIGGER_GC 16000
272 wait_event(unix_gc_wait, gc_in_progress ==
false);
284 spin_lock(&unix_gc_lock);
290 gc_in_progress =
true;
312 inflight_refs = atomic_long_read(&u->
inflight);
314 BUG_ON(inflight_refs < 1);
315 BUG_ON(total_refs < inflight_refs);
316 if (total_refs == inflight_refs) {
317 list_move_tail(&u->
link, &gc_candidates);
328 scan_children(&u->
sk, dec_inflight,
NULL);
338 list_add(&cursor, &gc_candidates);
339 while (cursor.
next != &gc_candidates) {
343 list_move(&cursor, &u->
link);
345 if (atomic_long_read(&u->
inflight) > 0) {
346 list_move_tail(&u->
link, ¬_cycle_list);
348 scan_children(&u->
sk, inc_inflight_move_tail,
NULL);
357 while (!list_empty(¬_cycle_list)) {
360 list_move_tail(&u->
link, &gc_inflight_list);
368 skb_queue_head_init(&hitlist);
370 scan_children(&u->
sk, inc_inflight, &hitlist);
372 spin_unlock(&unix_gc_lock);
375 __skb_queue_purge(&hitlist);
377 spin_lock(&unix_gc_lock);
380 BUG_ON(!list_empty(&gc_candidates));
381 gc_in_progress =
false;
385 spin_unlock(&unix_gc_lock);