diff options
Diffstat (limited to 'net/unix/garbage.c')
| -rw-r--r-- | net/unix/garbage.c | 17 | 
1 files changed, 9 insertions, 8 deletions
| diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 6a0d48525fcf..c36757e72844 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -146,6 +146,7 @@ void unix_notinflight(struct user_struct *user, struct file *fp)  	if (s) {  		struct unix_sock *u = unix_sk(s); +		BUG_ON(!atomic_long_read(&u->inflight));  		BUG_ON(list_empty(&u->link));  		if (atomic_long_dec_and_test(&u->inflight)) @@ -341,6 +342,14 @@ void unix_gc(void)  	}  	list_del(&cursor); +	/* Now gc_candidates contains only garbage.  Restore original +	 * inflight counters for these as well, and remove the skbuffs +	 * which are creating the cycle(s). +	 */ +	skb_queue_head_init(&hitlist); +	list_for_each_entry(u, &gc_candidates, link) +		scan_children(&u->sk, inc_inflight, &hitlist); +  	/* not_cycle_list contains those sockets which do not make up a  	 * cycle.  Restore these to the inflight list.  	 */ @@ -350,14 +359,6 @@ void unix_gc(void)  		list_move_tail(&u->link, &gc_inflight_list);  	} -	/* Now gc_candidates contains only garbage.  Restore original -	 * inflight counters for these as well, and remove the skbuffs -	 * which are creating the cycle(s). -	 */ -	skb_queue_head_init(&hitlist); -	list_for_each_entry(u, &gc_candidates, link) -	scan_children(&u->sk, inc_inflight, &hitlist); -  	spin_unlock(&unix_gc_lock);  	/* Here we are. Hitlist is filled. Die. */ |