The branch main has been updated by gallatin:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=23b46b2bbf0a8f3a740b6e5baf0767816afc339e

commit 23b46b2bbf0a8f3a740b6e5baf0767816afc339e
Author:     Andrew Gallatin <[email protected]>
AuthorDate: 2025-10-27 14:05:49 +0000
Commit:     Andrew Gallatin <[email protected]>
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.

Reply via email to