FreeBSD/sys/dev/cxgb/ulp/tom/cxgb_l2t.c
/*
 * Module locking notes:  There is a RW lock protecting the L2 table as a
 * whole plus a mutex per L2T entry.  Entry lookups and allocations happen
 * under the protection of the table lock, individual entry changes happen
 * while holding that entry's mutex.  The table lock nests outside the
 * entry locks.  Allocations of new entries take the table lock as writers so
 * no other lookups can happen while allocating new entries.  Entry updates
 * take the table lock as readers so multiple entries can be updated in
 * parallel.  An L2T entry can be dropped by decrementing its reference count
 * and therefore can happen in parallel with entry allocation but no entry
 * can change state or increment its ref count during allocation as both of
 * these perform lookups.
 *
 * When acquiring multiple locks, the order is llentry -> L2 table -> L2 entry.
 */
Module locking notes:  There is a RW lock protecting the L2 table as a
whole plus a mutex per L2T entry.  Entry lookups and allocations happen
under the protection of the table lock, individual entry changes happen
while holding that entry's mutex.  The table lock nests outside the
entry locks.  Allocations of new entries take the table lock as writers so
no other lookups can happen while allocating new entries.  Entry updates
take the table lock as readers so multiple entries can be updated in
parallel.  An L2T entry can be dropped by decrementing its reference count
and therefore can happen in parallel with entry allocation but no entry
can change state or increment its ref count during allocation as both of
these perform lookups.

When acquiring multiple locks, the order is llentry -> L2 table -> L2 entry.
Module locking notes : There is a RW lock protecting the L2 table as a whole plus a mutex per L2T entry . Entry lookups and allocations happen under the protection of the table lock individual entry changes happen while holding that entry ' s mutex . The table lock nests outside the entry locks . Allocations of new entries take the table lock as writers so no other lookups can happen while allocating new entries . Entry updates take the table lock as readers so multiple entries can be updated in parallel . An L2T entry can be dropped by decrementing its reference count and therefore can happen in parallel with entry allocation but no entry can change state or increment its ref count during allocation as both of these perform lookups . When acquiring multiple locks the order is llentry - > L2 table - > L2 entry .
static inline unsigned int
arp_hash(u32 key, int ifindex, const struct l2t_data *d)
{
	return jhash_2words(key, ifindex, 0) & (d->nentries - 1);
}
static inline unsigned int arp_hash ( u32 key , int ifindex , const struct l2t_data * d ) { return jhash_2words ( key , ifindex , 0 ) & ( d -> nentries - 1 ) ; }
Module locking notes:  There is a RW lock protecting the L2 table as a
 whole plus a mutex per L2T entry.
Module locking notes : There is a RW lock protecting the L2 table as a whole plus a mutex per L2T entry .