From owner-svn-src-all@FreeBSD.ORG Thu Oct 30 21:58:41 2008 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6EF971065677; Thu, 30 Oct 2008 21:58:41 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1EFE98FC2B; Thu, 30 Oct 2008 21:58:40 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id m9ULwdLM062712; Thu, 30 Oct 2008 21:58:39 GMT (envelope-from rwatson@svn.freebsd.org) Received: (from rwatson@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id m9ULwdlk062711; Thu, 30 Oct 2008 21:58:39 GMT (envelope-from rwatson@svn.freebsd.org) Message-Id: <200810302158.m9ULwdlk062711@svn.freebsd.org> From: Robert Watson Date: Thu, 30 Oct 2008 21:58:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r184488 - head/sys/security/audit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Oct 2008 21:58:41 -0000 Author: rwatson Date: Thu Oct 30 21:58:39 2008 New Revision: 184488 URL: http://svn.freebsd.org/changeset/base/184488 Log: Break out single audit_pipe_mtx into two types of locks: a global rwlock protecting the list of audit pipes, and a per-pipe mutex protecting the queue. Likewise, replace the single global condition variable used to signal delivery of a record to one or more pipes, and add a per-pipe condition variable to avoid spurious wakeups when event subscriptions differ across multiple pipes. This slightly increases the cost of delivering to audit pipes, but should reduce lock contention in the presence of multiple readers as only the per-pipe lock is required to read from a pipe, as well as avoid overheading when different pipes are used in different ways. MFC after: 2 months Sponsored by: Apple, Inc. Modified: head/sys/security/audit/audit_pipe.c Modified: head/sys/security/audit/audit_pipe.c ============================================================================== --- head/sys/security/audit/audit_pipe.c Thu Oct 30 21:48:28 2008 (r184487) +++ head/sys/security/audit/audit_pipe.c Thu Oct 30 21:58:39 2008 (r184488) @@ -1,5 +1,6 @@ /*- * Copyright (c) 2006 Robert N. M. Watson + * Copyright (c) 2008 Apple, Inc. * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. @@ -41,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -115,6 +117,17 @@ struct audit_pipe { struct selinfo ap_selinfo; struct sigio *ap_sigio; + /* + * Per-pipe mutex protecting most fields in this data structure. + */ + struct mtx ap_lock; + + /* + * Condition variable to signal when data has been delivered to a + * pipe. + */ + struct cv ap_cv; + u_int ap_qlen; u_int ap_qlimit; @@ -144,19 +157,31 @@ struct audit_pipe { TAILQ_ENTRY(audit_pipe) ap_list; }; +#define AUDIT_PIPE_LOCK(ap) mtx_lock(&(ap)->ap_lock) +#define AUDIT_PIPE_LOCK_ASSERT(ap) mtx_assert(&(ap)->ap_lock, MA_OWNED) +#define AUDIT_PIPE_LOCK_DESTROY(ap) mtx_destroy(&(ap)->ap_lock) +#define AUDIT_PIPE_LOCK_INIT(ap) mtx_init(&(ap)->ap_lock, \ + "audit_pipe_lock", NULL, MTX_DEF) +#define AUDIT_PIPE_UNLOCK(ap) mtx_unlock(&(ap)->ap_lock) +#define AUDIT_PIPE_MTX(ap) (&(ap)->ap_lock) + /* - * Global list of audit pipes, mutex to protect it and the pipes. Finer - * grained locking may be desirable at some point. + * Global list of audit pipes, rwlock to protect it. Individual record + * queues on pipes are protected by per-pipe locks; these locks synchronize + * between threads walking the list to deliver to individual pipes and add/ + * remove of pipes, and are mostly acquired for read. */ static TAILQ_HEAD(, audit_pipe) audit_pipe_list; -static struct mtx audit_pipe_mtx; +static struct rwlock audit_pipe_lock; -/* - * This CV is used to wakeup on an audit record write. Eventually, it might - * be per-pipe to avoid unnecessary wakeups when several pipes with different - * preselection masks are present. - */ -static struct cv audit_pipe_cv; +#define AUDIT_PIPE_LIST_LOCK_INIT() rw_init(&audit_pipe_lock, \ + "audit_pipe_list_lock") +#define AUDIT_PIPE_LIST_RLOCK() rw_rlock(&audit_pipe_lock) +#define AUDIT_PIPE_LIST_RUNLOCK() rw_runlock(&audit_pipe_lock) +#define AUDIT_PIPE_LIST_WLOCK() rw_wlock(&audit_pipe_lock) +#define AUDIT_PIPE_LIST_WLOCK_ASSERT() rw_assert(&audit_pipe_lock, \ + RA_WLOCKED) +#define AUDIT_PIPE_LIST_WUNLOCK() rw_wunlock(&audit_pipe_lock) /* * Cloning related variables and constants. @@ -224,7 +249,7 @@ audit_pipe_preselect_find(struct audit_p { struct audit_pipe_preselect *app; - mtx_assert(&audit_pipe_mtx, MA_OWNED); + AUDIT_PIPE_LOCK_ASSERT(ap); TAILQ_FOREACH(app, &ap->ap_preselect_list, app_list) { if (app->app_auid == auid) @@ -243,14 +268,14 @@ audit_pipe_preselect_get(struct audit_pi struct audit_pipe_preselect *app; int error; - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); app = audit_pipe_preselect_find(ap, auid); if (app != NULL) { *maskp = app->app_mask; error = 0; } else error = ENOENT; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); return (error); } @@ -268,7 +293,7 @@ audit_pipe_preselect_set(struct audit_pi * set, and allocate. We will free it if it is unneeded. */ app_new = malloc(sizeof(*app_new), M_AUDIT_PIPE_PRESELECT, M_WAITOK); - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); app = audit_pipe_preselect_find(ap, auid); if (app == NULL) { app = app_new; @@ -277,7 +302,7 @@ audit_pipe_preselect_set(struct audit_pi TAILQ_INSERT_TAIL(&ap->ap_preselect_list, app, app_list); } app->app_mask = mask; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); if (app_new != NULL) free(app_new, M_AUDIT_PIPE_PRESELECT); } @@ -291,14 +316,14 @@ audit_pipe_preselect_delete(struct audit struct audit_pipe_preselect *app; int error; - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); app = audit_pipe_preselect_find(ap, auid); if (app != NULL) { TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list); error = 0; } else error = ENOENT; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); if (app != NULL) free(app, M_AUDIT_PIPE_PRESELECT); return (error); @@ -312,7 +337,7 @@ audit_pipe_preselect_flush_locked(struct { struct audit_pipe_preselect *app; - mtx_assert(&audit_pipe_mtx, MA_OWNED); + AUDIT_PIPE_LOCK_ASSERT(ap); while ((app = TAILQ_FIRST(&ap->ap_preselect_list)) != NULL) { TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list); @@ -324,9 +349,9 @@ static void audit_pipe_preselect_flush(struct audit_pipe *ap) { - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); audit_pipe_preselect_flush_locked(ap); - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); } /*- @@ -345,7 +370,7 @@ audit_pipe_preselect_check(struct audit_ { struct audit_pipe_preselect *app; - mtx_assert(&audit_pipe_mtx, MA_OWNED); + AUDIT_PIPE_LOCK_ASSERT(ap); switch (ap->ap_preselect_mode) { case AUDITPIPE_PRESELECT_MODE_TRAIL: @@ -382,15 +407,18 @@ audit_pipe_preselect(au_id_t auid, au_ev { struct audit_pipe *ap; - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LIST_RLOCK(); TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) { + AUDIT_PIPE_LOCK(ap); if (audit_pipe_preselect_check(ap, auid, event, class, sorf, trail_preselect)) { - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); + AUDIT_PIPE_LIST_RUNLOCK(); return (1); } + AUDIT_PIPE_UNLOCK(ap); } - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_LIST_RUNLOCK(); return (0); } @@ -405,7 +433,7 @@ audit_pipe_append(struct audit_pipe *ap, { struct audit_pipe_entry *ape, *ape_remove; - mtx_assert(&audit_pipe_mtx, MA_OWNED); + AUDIT_PIPE_LOCK_ASSERT(ap); ape = malloc(sizeof(*ape), M_AUDIT_PIPE_ENTRY, M_NOWAIT | M_ZERO); if (ape == NULL) { @@ -441,6 +469,7 @@ audit_pipe_append(struct audit_pipe *ap, KNOTE_LOCKED(&ap->ap_selinfo.si_note, 0); if (ap->ap_flags & AUDIT_PIPE_ASYNC) pgsigio(&ap->ap_sigio, SIGIO, 0); + cv_broadcast(&ap->ap_cv); } /* @@ -454,20 +483,23 @@ audit_pipe_submit(au_id_t auid, au_event struct audit_pipe *ap; /* - * Lockless read to avoid mutex overhead if pipes are not in use. + * Lockless read to avoid lock overhead if pipes are not in use. */ if (TAILQ_FIRST(&audit_pipe_list) == NULL) return; - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LIST_RLOCK(); TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) { + AUDIT_PIPE_LOCK(ap); if (audit_pipe_preselect_check(ap, auid, event, class, sorf, trail_select)) audit_pipe_append(ap, record, record_len); + AUDIT_PIPE_UNLOCK(ap); } + AUDIT_PIPE_LIST_RUNLOCK(); + + /* Unlocked increment. */ audit_pipe_records++; - mtx_unlock(&audit_pipe_mtx); - cv_broadcastpri(&audit_pipe_cv, PSOCK); } /* @@ -484,17 +516,21 @@ audit_pipe_submit_user(void *record, u_i struct audit_pipe *ap; /* - * Lockless read to avoid mutex overhead if pipes are not in use. + * Lockless read to avoid lock overhead if pipes are not in use. */ if (TAILQ_FIRST(&audit_pipe_list) == NULL) return; - mtx_lock(&audit_pipe_mtx); - TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) + AUDIT_PIPE_LIST_RLOCK(); + TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) { + AUDIT_PIPE_LOCK(ap); audit_pipe_append(ap, record, record_len); + AUDIT_PIPE_UNLOCK(ap); + } + AUDIT_PIPE_LIST_RUNLOCK(); + + /* Unlocked increment. */ audit_pipe_records++; - mtx_unlock(&audit_pipe_mtx); - cv_broadcastpri(&audit_pipe_cv, PSOCK); } /* @@ -505,7 +541,7 @@ audit_pipe_pop(struct audit_pipe *ap) { struct audit_pipe_entry *ape; - mtx_assert(&audit_pipe_mtx, MA_OWNED); + AUDIT_PIPE_LOCK_ASSERT(ap); ape = TAILQ_FIRST(&ap->ap_queue); KASSERT((ape == NULL && ap->ap_qlen == 0) || @@ -526,15 +562,17 @@ audit_pipe_alloc(void) { struct audit_pipe *ap; - mtx_assert(&audit_pipe_mtx, MA_OWNED); + AUDIT_PIPE_LIST_WLOCK_ASSERT(); ap = malloc(sizeof(*ap), M_AUDIT_PIPE, M_NOWAIT | M_ZERO); if (ap == NULL) return (NULL); ap->ap_qlimit = AUDIT_PIPE_QLIMIT_DEFAULT; TAILQ_INIT(&ap->ap_queue); - knlist_init(&ap->ap_selinfo.si_note, &audit_pipe_mtx, NULL, NULL, + knlist_init(&ap->ap_selinfo.si_note, AUDIT_PIPE_MTX(ap), NULL, NULL, NULL); + AUDIT_PIPE_LOCK_INIT(ap); + cv_init(&ap->ap_cv, "audit_pipe"); /* * Default flags, naflags, and auid-specific preselection settings to @@ -566,7 +604,7 @@ audit_pipe_flush(struct audit_pipe *ap) { struct audit_pipe_entry *ape; - mtx_assert(&audit_pipe_mtx, MA_OWNED); + AUDIT_PIPE_LOCK_ASSERT(ap); while ((ape = TAILQ_FIRST(&ap->ap_queue)) != NULL) { TAILQ_REMOVE(&ap->ap_queue, ape, ape_queue); @@ -578,18 +616,21 @@ audit_pipe_flush(struct audit_pipe *ap) /* * Free an audit pipe; this means freeing all preselection state and all - * records in the pipe. Assumes mutex is held to prevent any new records - * from being inserted during the free, and that the audit pipe is still on - * the global list. + * records in the pipe. Assumes global write lock and pipe mutex are held to + * prevent any new records from being inserted during the free, and that the + * audit pipe is still on the global list. */ static void audit_pipe_free(struct audit_pipe *ap) { - mtx_assert(&audit_pipe_mtx, MA_OWNED); + AUDIT_PIPE_LIST_WLOCK_ASSERT(); + AUDIT_PIPE_LOCK_ASSERT(ap); audit_pipe_preselect_flush_locked(ap); audit_pipe_flush(ap); + cv_destroy(&ap->ap_cv); + AUDIT_PIPE_LOCK_DESTROY(ap); knlist_destroy(&ap->ap_selinfo.si_note); TAILQ_REMOVE(&audit_pipe_list, ap, ap_list); free(ap, M_AUDIT_PIPE); @@ -635,22 +676,22 @@ audit_pipe_open(struct cdev *dev, int of { struct audit_pipe *ap; - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LIST_WLOCK(); ap = dev->si_drv1; if (ap == NULL) { ap = audit_pipe_alloc(); if (ap == NULL) { - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_LIST_WUNLOCK(); return (ENOMEM); } dev->si_drv1 = ap; } else { KASSERT(ap->ap_open, ("audit_pipe_open: ap && !ap_open")); - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_LIST_WUNLOCK(); return (EBUSY); } - ap->ap_open = 1; - mtx_unlock(&audit_pipe_mtx); + ap->ap_open = 1; /* No lock required yet. */ + AUDIT_PIPE_LIST_WUNLOCK(); fsetown(td->td_proc->p_pid, &ap->ap_sigio); return (0); } @@ -666,12 +707,14 @@ audit_pipe_close(struct cdev *dev, int f ap = dev->si_drv1; KASSERT(ap != NULL, ("audit_pipe_close: ap == NULL")); KASSERT(ap->ap_open, ("audit_pipe_close: !ap_open")); + funsetown(&ap->ap_sigio); - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LIST_WLOCK(); + AUDIT_PIPE_LOCK(ap); ap->ap_open = 0; audit_pipe_free(ap); dev->si_drv1 = NULL; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_LIST_WUNLOCK(); return (0); } @@ -702,33 +745,33 @@ audit_pipe_ioctl(struct cdev *dev, u_lon */ switch (cmd) { case FIONBIO: - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); if (*(int *)data) ap->ap_flags |= AUDIT_PIPE_NBIO; else ap->ap_flags &= ~AUDIT_PIPE_NBIO; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); error = 0; break; case FIONREAD: - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); if (TAILQ_FIRST(&ap->ap_queue) != NULL) *(int *)data = TAILQ_FIRST(&ap->ap_queue)->ape_record_len; else *(int *)data = 0; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); error = 0; break; case FIOASYNC: - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); if (*(int *)data) ap->ap_flags |= AUDIT_PIPE_ASYNC; else ap->ap_flags &= ~AUDIT_PIPE_ASYNC; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); error = 0; break; @@ -772,34 +815,34 @@ audit_pipe_ioctl(struct cdev *dev, u_lon break; case AUDITPIPE_GET_PRESELECT_FLAGS: - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); maskp = (au_mask_t *)data; *maskp = ap->ap_preselect_flags; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); error = 0; break; case AUDITPIPE_SET_PRESELECT_FLAGS: - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); maskp = (au_mask_t *)data; ap->ap_preselect_flags = *maskp; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); error = 0; break; case AUDITPIPE_GET_PRESELECT_NAFLAGS: - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); maskp = (au_mask_t *)data; *maskp = ap->ap_preselect_naflags; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); error = 0; break; case AUDITPIPE_SET_PRESELECT_NAFLAGS: - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); maskp = (au_mask_t *)data; ap->ap_preselect_naflags = *maskp; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); error = 0; break; @@ -826,9 +869,9 @@ audit_pipe_ioctl(struct cdev *dev, u_lon break; case AUDITPIPE_GET_PRESELECT_MODE: - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); *(int *)data = ap->ap_preselect_mode; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); error = 0; break; @@ -837,9 +880,9 @@ audit_pipe_ioctl(struct cdev *dev, u_lon switch (mode) { case AUDITPIPE_PRESELECT_MODE_TRAIL: case AUDITPIPE_PRESELECT_MODE_LOCAL: - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); ap->ap_preselect_mode = mode; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); error = 0; break; @@ -849,9 +892,9 @@ audit_pipe_ioctl(struct cdev *dev, u_lon break; case AUDITPIPE_FLUSH: - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); audit_pipe_flush(ap); - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); error = 0; break; @@ -910,7 +953,8 @@ audit_pipe_read(struct cdev *dev, struct ap = dev->si_drv1; KASSERT(ap != NULL, ("audit_pipe_read: ap == NULL")); - mtx_lock(&audit_pipe_mtx); + + AUDIT_PIPE_LOCK(ap); do { /* * Wait for a record that fits into the read buffer, dropping @@ -920,12 +964,12 @@ audit_pipe_read(struct cdev *dev, struct */ while ((ape = audit_pipe_pop(ap)) == NULL) { if (ap->ap_flags & AUDIT_PIPE_NBIO) { - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); return (EAGAIN); } - error = cv_wait_sig(&audit_pipe_cv, &audit_pipe_mtx); + error = cv_wait_sig(&ap->ap_cv, AUDIT_PIPE_MTX(ap)); if (error) { - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); return (error); } } @@ -935,7 +979,7 @@ audit_pipe_read(struct cdev *dev, struct ap->ap_truncates++; } while (1); ap->ap_reads++; - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); /* * Now read record to user space memory. Even if the read is short, @@ -959,13 +1003,14 @@ audit_pipe_poll(struct cdev *dev, int ev revents = 0; ap = dev->si_drv1; KASSERT(ap != NULL, ("audit_pipe_poll: ap == NULL")); + if (events & (POLLIN | POLLRDNORM)) { - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); if (TAILQ_FIRST(&ap->ap_queue) != NULL) revents |= events & (POLLIN | POLLRDNORM); else selrecord(td, &ap->ap_selinfo); - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); } return (revents); } @@ -987,9 +1032,9 @@ audit_pipe_kqfilter(struct cdev *dev, st kn->kn_fop = &audit_pipe_read_filterops; kn->kn_hook = ap; - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); knlist_add(&ap->ap_selinfo.si_note, kn, 1); - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); return (0); } @@ -1002,11 +1047,11 @@ audit_pipe_kqread(struct knote *kn, long struct audit_pipe_entry *ape; struct audit_pipe *ap; - mtx_assert(&audit_pipe_mtx, MA_OWNED); - ap = (struct audit_pipe *)kn->kn_hook; KASSERT(ap != NULL, ("audit_pipe_kqread: ap == NULL")); + AUDIT_PIPE_LOCK_ASSERT(ap); + if (ap->ap_qlen != 0) { ape = TAILQ_FIRST(&ap->ap_queue); KASSERT(ape != NULL, ("audit_pipe_kqread: ape == NULL")); @@ -1030,9 +1075,9 @@ audit_pipe_kqdetach(struct knote *kn) ap = (struct audit_pipe *)kn->kn_hook; KASSERT(ap != NULL, ("audit_pipe_kqdetach: ap == NULL")); - mtx_lock(&audit_pipe_mtx); + AUDIT_PIPE_LOCK(ap); knlist_remove(&ap->ap_selinfo.si_note, kn, 1); - mtx_unlock(&audit_pipe_mtx); + AUDIT_PIPE_UNLOCK(ap); } /* @@ -1043,8 +1088,7 @@ audit_pipe_init(void *unused) { TAILQ_INIT(&audit_pipe_list); - mtx_init(&audit_pipe_mtx, "audit_pipe_mtx", NULL, MTX_DEF); - cv_init(&audit_pipe_cv, "audit_pipe_cv"); + AUDIT_PIPE_LIST_LOCK_INIT(); clone_setup(&audit_pipe_clones); audit_pipe_eh_tag = EVENTHANDLER_REGISTER(dev_clone,