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
This commit is contained in:
parent
9c5ce94257
commit
1030a1a9cb
@ -34,7 +34,7 @@
|
|||||||
#include <sys/errno.h>
|
#include <sys/errno.h>
|
||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/rwlock.h>
|
#include <sys/rmlock.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/socketvar.h>
|
#include <sys/socketvar.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -66,11 +66,12 @@ int
|
|||||||
pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
|
pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
|
||||||
int dir, struct inpcb *inp)
|
int dir, struct inpcb *inp)
|
||||||
{
|
{
|
||||||
|
struct rm_priotracker rmpt;
|
||||||
struct packet_filter_hook *pfh;
|
struct packet_filter_hook *pfh;
|
||||||
struct mbuf *m = *mp;
|
struct mbuf *m = *mp;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
PFIL_RLOCK(ph);
|
PFIL_RLOCK(ph, &rmpt);
|
||||||
KASSERT(ph->ph_nhooks >= 0, ("Pfil hook count dropped < 0"));
|
KASSERT(ph->ph_nhooks >= 0, ("Pfil hook count dropped < 0"));
|
||||||
for (pfh = pfil_hook_get(dir, ph); pfh != NULL;
|
for (pfh = pfil_hook_get(dir, ph); pfh != NULL;
|
||||||
pfh = TAILQ_NEXT(pfh, pfil_link)) {
|
pfh = TAILQ_NEXT(pfh, pfil_link)) {
|
||||||
@ -80,7 +81,7 @@ pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PFIL_RUNLOCK(ph);
|
PFIL_RUNLOCK(ph, &rmpt);
|
||||||
|
|
||||||
*mp = m;
|
*mp = m;
|
||||||
return (rv);
|
return (rv);
|
||||||
@ -104,7 +105,7 @@ pfil_head_register(struct pfil_head *ph)
|
|||||||
}
|
}
|
||||||
PFIL_LIST_UNLOCK();
|
PFIL_LIST_UNLOCK();
|
||||||
|
|
||||||
rw_init(&ph->ph_mtx, "PFil hook read/write mutex");
|
PFIL_LOCK_INIT(ph);
|
||||||
PFIL_WLOCK(ph);
|
PFIL_WLOCK(ph);
|
||||||
ph->ph_nhooks = 0;
|
ph->ph_nhooks = 0;
|
||||||
|
|
||||||
@ -143,7 +144,7 @@ pfil_head_unregister(struct pfil_head *ph)
|
|||||||
free(pfh, M_IFADDR);
|
free(pfh, M_IFADDR);
|
||||||
TAILQ_FOREACH_SAFE(pfh, &ph->ph_out, pfil_link, pfnext)
|
TAILQ_FOREACH_SAFE(pfh, &ph->ph_out, pfil_link, pfnext)
|
||||||
free(pfh, M_IFADDR);
|
free(pfh, M_IFADDR);
|
||||||
rw_destroy(&ph->ph_mtx);
|
PFIL_LOCK_DESTROY(ph);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
#include <sys/_lock.h>
|
#include <sys/_lock.h>
|
||||||
#include <sys/_mutex.h>
|
#include <sys/_mutex.h>
|
||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
#include <sys/rwlock.h>
|
#include <sys/rmlock.h>
|
||||||
|
|
||||||
struct mbuf;
|
struct mbuf;
|
||||||
struct ifnet;
|
struct ifnet;
|
||||||
@ -69,7 +69,7 @@ struct pfil_head {
|
|||||||
pfil_list_t ph_out;
|
pfil_list_t ph_out;
|
||||||
int ph_type;
|
int ph_type;
|
||||||
int ph_nhooks;
|
int ph_nhooks;
|
||||||
struct rwlock ph_mtx;
|
struct rmlock ph_lock;
|
||||||
union {
|
union {
|
||||||
u_long phu_val;
|
u_long phu_val;
|
||||||
void *phu_ptr;
|
void *phu_ptr;
|
||||||
@ -93,10 +93,13 @@ int pfil_head_unregister(struct pfil_head *);
|
|||||||
struct pfil_head *pfil_head_get(int, u_long);
|
struct pfil_head *pfil_head_get(int, u_long);
|
||||||
|
|
||||||
#define PFIL_HOOKED(p) ((p)->ph_nhooks > 0)
|
#define PFIL_HOOKED(p) ((p)->ph_nhooks > 0)
|
||||||
#define PFIL_RLOCK(p) rw_rlock(&(p)->ph_mtx)
|
#define PFIL_LOCK_INIT(p) \
|
||||||
#define PFIL_WLOCK(p) rw_wlock(&(p)->ph_mtx)
|
rm_init(&(p)->ph_lock, "PFil hook read/write mutex", LO_RECURSABLE)
|
||||||
#define PFIL_RUNLOCK(p) rw_runlock(&(p)->ph_mtx)
|
#define PFIL_LOCK_DESTROY(p) rm_destroy(&(p)->ph_lock)
|
||||||
#define PFIL_WUNLOCK(p) rw_wunlock(&(p)->ph_mtx)
|
#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_LOCK() mtx_lock(&pfil_global_lock)
|
||||||
#define PFIL_LIST_UNLOCK() mtx_unlock(&pfil_global_lock)
|
#define PFIL_LIST_UNLOCK() mtx_unlock(&pfil_global_lock)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user