Move UNIX domain sockets garbage collector out of `unp_lock.
Except `unp_ino' this leaves only per-socket data protected by
`unp_lock'. The `unp_ino' protection is not the big deal and will be
done with mutex(9) in the future diff.
The garbage collector flags moved from from `unp_flags' to unp_gcflags'.
The two new locks introduced to protect garbage collector data. The
`unp_gc_lock' rwlock(9) protects `unp_defer', `unp_gcing', `unp_gcflags'
and `unp_link' list. The `unp_df_lock' protects `ud_link' list.
We need to simultaneously lock `unp_gc_lock' and `unp_lock'. When we
perform unp_attach() or unp_detach() we link PCB to `unp_link' list with
`unp_lock' held. But when unp_gc() does `unp_link' list walkthrough with
the `unp_gc_lock' lock held it should lock socket while performs
`so_rcv' buffer scan and the lock order should be the opposite.
In the future diff `unp_lock' will be replaced by per-socket `so_lock'
so it's better to enforce `unp_gc_lock' -> `unp_lock' (solock()) lock
order and release `unp_lock' in the unp_attach() and unp_detach() paths.
The previously committed diffs made this safe.
The `unp_df_lock' introduced because the `unp_lock' and `unp_gc_lock'
state are unknown when unp_discard() called. Since it touches only
`ud_link' list the re-lock dances are unwanted in this path. Also this
keeps M_WAITOK allocation outside rwlock(9) when unp_discard() called
from unp_externalize() error path.
ok bluhm@