Date: Mon, 27 Oct 2025 14:15:09 GMT From: Andrew Gallatin <gallatin@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 23b46b2bbf0a - main - audit: convert audit event class lookup to lockless Message-ID: <202510271415.59REF9kg024897@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by gallatin: URL: https://cgit.FreeBSD.org/src/commit/?id=23b46b2bbf0a8f3a740b6e5baf0767816afc339e commit 23b46b2bbf0a8f3a740b6e5baf0767816afc339e Author: Andrew Gallatin <gallatin@FreeBSD.org> AuthorDate: 2025-10-27 14:05:49 +0000 Commit: Andrew Gallatin <gallatin@FreeBSD.org> CommitDate: 2025-10-27 14:15:01 +0000 audit: convert audit event class lookup to lockless When system call auditing is enabled, every audited call does a lookup in the evclass hash table. This table appears to be insert only (eg, nothing can be removed) and protecting it with an rwlock is overkill. Using an rwlock causes just the atomic operations to maintain uncontended rwlock state to be responsible for measurable overhead on high core count servers making lots of system calls. Given that the evclass hash table can never have items removed, only added, using a mutex to serialize additions and converting to ck_list allows sufficient protection for lockless lookups. In a contrived example of 64 cores, all reading 1 byte from their own file, this change increases performance from 5M reads/sec to 70M reads/sec on an AMD 7502P. Reviewed by: markj, mjg, glebius (privately) Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D53176 --- sys/security/audit/audit_bsm_db.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/sys/security/audit/audit_bsm_db.c b/sys/security/audit/audit_bsm_db.c index c9f3d5c8a549..358162544287 100644 --- a/sys/security/audit/audit_bsm_db.c +++ b/sys/security/audit/audit_bsm_db.c @@ -56,6 +56,8 @@ #include <security/audit/audit.h> #include <security/audit/audit_private.h> +#include <contrib/ck/include/ck_queue.h> + /* * Hash table functions for the audit event number to event class mask * mapping. @@ -64,21 +66,21 @@ struct evclass_elem { au_event_t event; au_class_t class; - LIST_ENTRY(evclass_elem) entry; + CK_LIST_ENTRY(evclass_elem) entry; }; struct evclass_list { - LIST_HEAD(, evclass_elem) head; + CK_LIST_HEAD(, evclass_elem) head; }; static MALLOC_DEFINE(M_AUDITEVCLASS, "audit_evclass", "Audit event class"); -static struct rwlock evclass_lock; static struct evclass_list evclass_hash[EVCLASSMAP_HASH_TABLE_SIZE]; - -#define EVCLASS_LOCK_INIT() rw_init(&evclass_lock, "evclass_lock") -#define EVCLASS_RLOCK() rw_rlock(&evclass_lock) -#define EVCLASS_RUNLOCK() rw_runlock(&evclass_lock) -#define EVCLASS_WLOCK() rw_wlock(&evclass_lock) -#define EVCLASS_WUNLOCK() rw_wunlock(&evclass_lock) +static struct mtx evclass_mtx; +#define EVCLASS_LOCK_INIT() mtx_init(&evclass_mtx, "evclass_lock", NULL, MTX_DEF) +#define EVCLASS_WLOCK() mtx_lock(&evclass_mtx); +#define EVCLASS_WUNLOCK() mtx_unlock(&evclass_mtx); +/* make these do something if we ever remove entries from the hash */ +#define EVCLASS_RLOCK() {} +#define EVCLASS_RUNLOCK() {} /* * Hash table maintaining a mapping from audit event numbers to audit event @@ -118,7 +120,7 @@ au_event_class(au_event_t event) EVCLASS_RLOCK(); evcl = &evclass_hash[event % EVCLASSMAP_HASH_TABLE_SIZE]; class = 0; - LIST_FOREACH(evc, &evcl->head, entry) { + CK_LIST_FOREACH(evc, &evcl->head, entry) { if (evc->event == event) { class = evc->class; goto out; @@ -150,7 +152,7 @@ au_evclassmap_insert(au_event_t event, au_class_t class) EVCLASS_WLOCK(); evcl = &evclass_hash[event % EVCLASSMAP_HASH_TABLE_SIZE]; - LIST_FOREACH(evc, &evcl->head, entry) { + CK_LIST_FOREACH(evc, &evcl->head, entry) { if (evc->event == event) { evc->class = class; EVCLASS_WUNLOCK(); @@ -161,7 +163,7 @@ au_evclassmap_insert(au_event_t event, au_class_t class) evc = evc_new; evc->event = event; evc->class = class; - LIST_INSERT_HEAD(&evcl->head, evc, entry); + CK_LIST_INSERT_HEAD(&evcl->head, evc, entry); EVCLASS_WUNLOCK(); } @@ -172,7 +174,7 @@ au_evclassmap_init(void) EVCLASS_LOCK_INIT(); for (i = 0; i < EVCLASSMAP_HASH_TABLE_SIZE; i++) - LIST_INIT(&evclass_hash[i].head); + CK_LIST_INIT(&evclass_hash[i].head); /* * Set up the initial event to class mapping for system calls.home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202510271415.59REF9kg024897>
