Author: kevans
Date: Sat Nov  7 05:10:46 2020
New Revision: 367444
URL: https://svnweb.freebsd.org/changeset/base/367444

Log:
  imgact_binmisc: abstract away the list lock (NFC)
  
  This module handles relatively few execs (initial qemu-user-static, then
  qemu-user-static handles exec'ing itself for binaries it's already running),
  but all execs pay the price of at least taking the relatively expensive
  sx/slock to check for a match when this module is loaded. Future work will
  almost certainly swap this out for another lock, perhaps an rmslock.
  
  The RLOCK/WLOCK phrasing was chosen based on what the callers are really
  wanting, rather than using the verbiage typically appropriate for an sx.
  
  MFC after:    1 week

Modified:
  head/sys/kern/imgact_binmisc.c

Modified: head/sys/kern/imgact_binmisc.c
==============================================================================
--- head/sys/kern/imgact_binmisc.c      Sat Nov  7 04:15:24 2020        
(r367443)
+++ head/sys/kern/imgact_binmisc.c      Sat Nov  7 05:10:46 2020        
(r367444)
@@ -98,6 +98,16 @@ static int interp_list_entry_count;
 
 static struct sx interp_list_sx;
 
+#define        INTERP_LIST_WLOCK()             sx_xlock(&interp_list_sx)
+#define        INTERP_LIST_RLOCK()             sx_slock(&interp_list_sx)
+#define        INTERP_LIST_WUNLOCK()           sx_xunlock(&interp_list_sx)
+#define        INTERP_LIST_RUNLOCK()           sx_sunlock(&interp_list_sx)
+
+#define        INTERP_LIST_LOCK_INIT()         sx_init(&interp_list_sx, 
KMOD_NAME)
+#define        INTERP_LIST_LOCK_DESTROY()      sx_destroy(&interp_list_sx)
+
+#define        INTERP_LIST_ASSERT_LOCKED()     sx_assert(&interp_list_sx, 
SA_LOCKED)
+
 /*
  * Populate the entry with the information about the interpreter.
  */
@@ -198,7 +208,7 @@ imgact_binmisc_find_entry(char *name)
 {
        imgact_binmisc_entry_t *ibe;
 
-       sx_assert(&interp_list_sx, SA_LOCKED);
+       INTERP_LIST_ASSERT_LOCKED();
 
        SLIST_FOREACH(ibe, &interpreter_list, link) {
                if (strncmp(name, ibe->ibe_name, IBE_NAME_MAX) == 0)
@@ -256,9 +266,9 @@ imgact_binmisc_add_entry(ximgact_binmisc_entry_t *xbe)
                }
        }
 
-       sx_xlock(&interp_list_sx);
+       INTERP_LIST_WLOCK();
        if (imgact_binmisc_find_entry(xbe->xbe_name) != NULL) {
-               sx_xunlock(&interp_list_sx);
+               INTERP_LIST_WUNLOCK();
                return (EEXIST);
        }
 
@@ -267,7 +277,7 @@ imgact_binmisc_add_entry(ximgact_binmisc_entry_t *xbe)
 
        SLIST_INSERT_HEAD(&interpreter_list, ibe, link);
        interp_list_entry_count++;
-       sx_xunlock(&interp_list_sx);
+       INTERP_LIST_WUNLOCK();
 
        return (0);
 }
@@ -281,14 +291,14 @@ imgact_binmisc_remove_entry(char *name)
 {
        imgact_binmisc_entry_t *ibe;
 
-       sx_xlock(&interp_list_sx);
+       INTERP_LIST_WLOCK();
        if ((ibe = imgact_binmisc_find_entry(name)) == NULL) {
-               sx_xunlock(&interp_list_sx);
+               INTERP_LIST_WUNLOCK();
                return (ENOENT);
        }
        SLIST_REMOVE(&interpreter_list, ibe, imgact_binmisc_entry, link);
        interp_list_entry_count--;
-       sx_xunlock(&interp_list_sx);
+       INTERP_LIST_WUNLOCK();
 
        imgact_binmisc_destroy_entry(ibe);
 
@@ -304,14 +314,14 @@ imgact_binmisc_disable_entry(char *name)
 {
        imgact_binmisc_entry_t *ibe;
 
-       sx_xlock(&interp_list_sx);
+       INTERP_LIST_WLOCK();
        if ((ibe = imgact_binmisc_find_entry(name)) == NULL) {
-               sx_xunlock(&interp_list_sx);
+               INTERP_LIST_WUNLOCK();
                return (ENOENT);
        }
 
        ibe->ibe_flags &= ~IBF_ENABLED;
-       sx_xunlock(&interp_list_sx);
+       INTERP_LIST_WUNLOCK();
 
        return (0);
 }
@@ -325,14 +335,14 @@ imgact_binmisc_enable_entry(char *name)
 {
        imgact_binmisc_entry_t *ibe;
 
-       sx_xlock(&interp_list_sx);
+       INTERP_LIST_WLOCK();
        if ((ibe = imgact_binmisc_find_entry(name)) == NULL) {
-               sx_xunlock(&interp_list_sx);
+               INTERP_LIST_WUNLOCK();
                return (ENOENT);
        }
 
        ibe->ibe_flags |= IBF_ENABLED;
-       sx_xunlock(&interp_list_sx);
+       INTERP_LIST_WUNLOCK();
 
        return (0);
 }
@@ -343,8 +353,7 @@ imgact_binmisc_populate_xbe(ximgact_binmisc_entry_t *x
 {
        uint32_t i;
 
-       sx_assert(&interp_list_sx, SA_LOCKED);
-
+       INTERP_LIST_ASSERT_LOCKED();
        memset(xbe, 0, sizeof(*xbe));
        strlcpy(xbe->xbe_name, ibe->ibe_name, IBE_NAME_MAX);
 
@@ -375,14 +384,14 @@ imgact_binmisc_lookup_entry(char *name, ximgact_binmis
        imgact_binmisc_entry_t *ibe;
        int error = 0;
 
-       sx_slock(&interp_list_sx);
+       INTERP_LIST_RLOCK();
        if ((ibe = imgact_binmisc_find_entry(name)) == NULL) {
-               sx_sunlock(&interp_list_sx);
+               INTERP_LIST_RUNLOCK();
                return (ENOENT);
        }
 
        error = imgact_binmisc_populate_xbe(xbe, ibe);
-       sx_sunlock(&interp_list_sx);
+       INTERP_LIST_RUNLOCK();
 
        return (error);
 }
@@ -397,7 +406,7 @@ imgact_binmisc_get_all_entries(struct sysctl_req *req)
        imgact_binmisc_entry_t *ibe;
        int error = 0, count;
 
-       sx_slock(&interp_list_sx);
+       INTERP_LIST_RLOCK();
        count = interp_list_entry_count;
        xbe = malloc(sizeof(*xbe) * count, M_BINMISC, M_WAITOK|M_ZERO);
 
@@ -407,7 +416,7 @@ imgact_binmisc_get_all_entries(struct sysctl_req *req)
                if (error)
                        break;
        }
-       sx_sunlock(&interp_list_sx);
+       INTERP_LIST_RUNLOCK();
 
        if (!error)
                error = SYSCTL_OUT(req, xbe, sizeof(*xbe) * count);
@@ -546,7 +555,7 @@ imgact_binmisc_find_interpreter(const char *image_head
        int i;
        size_t sz;
 
-       sx_assert(&interp_list_sx, SA_LOCKED);
+       INTERP_LIST_ASSERT_LOCKED();
 
        SLIST_FOREACH(ibe, &interpreter_list, link) {
                if (!(IBF_ENABLED & ibe->ibe_flags))
@@ -584,7 +593,7 @@ imgact_binmisc_exec(struct image_params *imgp)
 
        sname = NULL;
        /* Do we have an interpreter for the given image header? */
-       sx_slock(&interp_list_sx);
+       INTERP_LIST_RLOCK();
        if ((ibe = imgact_binmisc_find_interpreter(image_header)) == NULL) {
                error = -1;
                goto done;
@@ -702,7 +711,7 @@ imgact_binmisc_exec(struct image_params *imgp)
        imgp->interpreter_name = imgp->args->begin_argv;
 
 done:
-       sx_sunlock(&interp_list_sx);
+       INTERP_LIST_RUNLOCK();
        if (sname)
                sbuf_delete(sname);
        return (error);
@@ -712,7 +721,7 @@ static void
 imgact_binmisc_init(void *arg)
 {
 
-       sx_init(&interp_list_sx, KMOD_NAME);
+       INTERP_LIST_LOCK_INIT();
 }
 
 static void
@@ -721,15 +730,15 @@ imgact_binmisc_fini(void *arg)
        imgact_binmisc_entry_t *ibe, *ibe_tmp;
 
        /* Free all the interpreters. */
-       sx_xlock(&interp_list_sx);
+       INTERP_LIST_WLOCK();
        SLIST_FOREACH_SAFE(ibe, &interpreter_list, link, ibe_tmp) {
                SLIST_REMOVE(&interpreter_list, ibe, imgact_binmisc_entry,
                    link);
                imgact_binmisc_destroy_entry(ibe);
        }
-       sx_xunlock(&interp_list_sx);
+       INTERP_LIST_WUNLOCK();
 
-       sx_destroy(&interp_list_sx);
+       INTERP_LIST_LOCK_DESTROY();
 }
 
 SYSINIT(imgact_binmisc, SI_SUB_EXEC, SI_ORDER_MIDDLE, imgact_binmisc_init,
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to