From 1030a1a9cb2f9c6bf2c8cd3cdc77c06794abc86f Mon Sep 17 00:00:00 2001 From: Max Laier Date: Sun, 25 Nov 2007 12:41:47 +0000 Subject: [PATCH] pfil(9) locking take 3: Switch to rmlock(9) This has the benefit that rmlocks have proper support for reader recursion (in contrast to rwlock(9) which could potential lead to writer stravation). It also means a significant performance gain, eventhough only visible in microbenchmarks at the moment. Discussed on: -arch, -net --- sys/net/pfil.c | 11 ++++++----- sys/net/pfil.h | 15 +++++++++------ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/sys/net/pfil.c b/sys/net/pfil.c index 78b87f3179c..bb82bb313ac 100644 --- a/sys/net/pfil.c +++ b/sys/net/pfil.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -66,11 +66,12 @@ int pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp, int dir, struct inpcb *inp) { + struct rm_priotracker rmpt; struct packet_filter_hook *pfh; struct mbuf *m = *mp; int rv = 0; - PFIL_RLOCK(ph); + PFIL_RLOCK(ph, &rmpt); KASSERT(ph->ph_nhooks >= 0, ("Pfil hook count dropped < 0")); for (pfh = pfil_hook_get(dir, ph); pfh != NULL; pfh = TAILQ_NEXT(pfh, pfil_link)) { @@ -80,7 +81,7 @@ pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp, break; } } - PFIL_RUNLOCK(ph); + PFIL_RUNLOCK(ph, &rmpt); *mp = m; return (rv); @@ -104,7 +105,7 @@ pfil_head_register(struct pfil_head *ph) } PFIL_LIST_UNLOCK(); - rw_init(&ph->ph_mtx, "PFil hook read/write mutex"); + PFIL_LOCK_INIT(ph); PFIL_WLOCK(ph); ph->ph_nhooks = 0; @@ -143,7 +144,7 @@ pfil_head_unregister(struct pfil_head *ph) free(pfh, M_IFADDR); TAILQ_FOREACH_SAFE(pfh, &ph->ph_out, pfil_link, pfnext) free(pfh, M_IFADDR); - rw_destroy(&ph->ph_mtx); + PFIL_LOCK_DESTROY(ph); return (0); } diff --git a/sys/net/pfil.h b/sys/net/pfil.h index d2308fdbee5..22d3d16010a 100644 --- a/sys/net/pfil.h +++ b/sys/net/pfil.h @@ -37,7 +37,7 @@ #include #include #include -#include +#include struct mbuf; struct ifnet; @@ -69,7 +69,7 @@ struct pfil_head { pfil_list_t ph_out; int ph_type; int ph_nhooks; - struct rwlock ph_mtx; + struct rmlock ph_lock; union { u_long phu_val; void *phu_ptr; @@ -93,10 +93,13 @@ int pfil_head_unregister(struct pfil_head *); struct pfil_head *pfil_head_get(int, u_long); #define PFIL_HOOKED(p) ((p)->ph_nhooks > 0) -#define PFIL_RLOCK(p) rw_rlock(&(p)->ph_mtx) -#define PFIL_WLOCK(p) rw_wlock(&(p)->ph_mtx) -#define PFIL_RUNLOCK(p) rw_runlock(&(p)->ph_mtx) -#define PFIL_WUNLOCK(p) rw_wunlock(&(p)->ph_mtx) +#define PFIL_LOCK_INIT(p) \ + rm_init(&(p)->ph_lock, "PFil hook read/write mutex", LO_RECURSABLE) +#define PFIL_LOCK_DESTROY(p) rm_destroy(&(p)->ph_lock) +#define PFIL_RLOCK(p, t) rm_rlock(&(p)->ph_lock, (t)) +#define PFIL_WLOCK(p) rm_wlock(&(p)->ph_lock) +#define PFIL_RUNLOCK(p, t) rm_runlock(&(p)->ph_lock, (t)) +#define PFIL_WUNLOCK(p) rm_wunlock(&(p)->ph_lock) #define PFIL_LIST_LOCK() mtx_lock(&pfil_global_lock) #define PFIL_LIST_UNLOCK() mtx_unlock(&pfil_global_lock)