Author: markj
Date: Sat Aug 24 21:07:04 2013
New Revision: 254810
URL: http://svnweb.freebsd.org/changeset/base/254810

Log:
  Remove the kld lock macros and just use the sx(9) API. Add locking in
  linker_init_kernel_modules() and linker_preload() in order to remove most
  of the checks for !cold before asserting that the kld lock is held. These
  routines are invoked by SYSINIT(9), so there's no harm in them taking the
  kld lock.

Modified:
  head/sys/kern/kern_linker.c

Modified: head/sys/kern/kern_linker.c
==============================================================================
--- head/sys/kern/kern_linker.c Sat Aug 24 21:04:54 2013        (r254809)
+++ head/sys/kern/kern_linker.c Sat Aug 24 21:07:04 2013        (r254810)
@@ -71,17 +71,6 @@ SYSCTL_INT(_debug, OID_AUTO, kld_debug, 
 TUNABLE_INT("debug.kld_debug", &kld_debug);
 #endif
 
-#define        KLD_LOCK()              sx_xlock(&kld_sx)
-#define        KLD_UNLOCK()            sx_xunlock(&kld_sx)
-#define        KLD_DOWNGRADE()         sx_downgrade(&kld_sx)
-#define        KLD_LOCK_READ()         sx_slock(&kld_sx)
-#define        KLD_UNLOCK_READ()       sx_sunlock(&kld_sx)
-#define        KLD_LOCKED()            sx_xlocked(&kld_sx)
-#define        KLD_LOCK_ASSERT() do {                                          
\
-       if (!cold)                                                      \
-               sx_assert(&kld_sx, SX_XLOCKED);                         \
-} while (0)
-
 /*
  * static char *linker_search_path(const char *name, struct mod_depend
  * *verinfo);
@@ -121,7 +110,8 @@ static int linker_no_more_classes = 0;
 #define        LINKER_GET_NEXT_FILE_ID(a) do {                                 
\
        linker_file_t lftmp;                                            \
                                                                        \
-       KLD_LOCK_ASSERT();                                              \
+       if (!cold)                                                      \
+               sx_assert(&kld_sx, SA_XLOCKED);                         \
 retry:                                                                 \
        TAILQ_FOREACH(lftmp, &linker_files, link) {                     \
                if (next_file_id == lftmp->id) {                        \
@@ -360,7 +350,9 @@ static void
 linker_init_kernel_modules(void)
 {
 
+       sx_xlock(&kld_sx);
        linker_file_register_modules(linker_kernel_file);
+       sx_xunlock(&kld_sx);
 }
 
 SYSINIT(linker_kernel, SI_SUB_KLD, SI_ORDER_ANY, linker_init_kernel_modules,
@@ -377,7 +369,7 @@ linker_load_file(const char *filename, l
        if (prison0.pr_securelevel > 0)
                return (EPERM);
 
-       KLD_LOCK_ASSERT();
+       sx_assert(&kld_sx, SA_XLOCKED);
        lf = linker_find_file_by_name(filename);
        if (lf) {
                KLD_DPF(FILE, ("linker_load_file: file %s is already loaded,"
@@ -411,10 +403,10 @@ linker_load_file(const char *filename, l
                                return (error);
                        }
                        modules = !TAILQ_EMPTY(&lf->modules);
-                       KLD_UNLOCK();
+                       sx_xunlock(&kld_sx);
                        linker_file_register_sysctls(lf);
                        linker_file_sysinit(lf);
-                       KLD_LOCK();
+                       sx_xlock(&kld_sx);
                        lf->flags |= LINKER_FILE_LINKED;
 
                        /*
@@ -465,16 +457,16 @@ linker_reference_module(const char *modn
        modlist_t mod;
        int error;
 
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        if ((mod = modlist_lookup2(modname, verinfo)) != NULL) {
                *result = mod->container;
                (*result)->refs++;
-               KLD_UNLOCK();
+               sx_xunlock(&kld_sx);
                return (0);
        }
 
        error = linker_load_module(NULL, modname, NULL, verinfo, result);
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
        return (error);
 }
 
@@ -485,13 +477,13 @@ linker_release_module(const char *modnam
        modlist_t mod;
        int error;
 
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        if (lf == NULL) {
                KASSERT(modname != NULL,
                    ("linker_release_module: no file or name"));
                mod = modlist_lookup2(modname, verinfo);
                if (mod == NULL) {
-                       KLD_UNLOCK();
+                       sx_xunlock(&kld_sx);
                        return (ESRCH);
                }
                lf = mod->container;
@@ -499,7 +491,7 @@ linker_release_module(const char *modnam
                KASSERT(modname == NULL && verinfo == NULL,
                    ("linker_release_module: both file and name"));
        error = linker_file_unload(lf, LINKER_UNLOAD_NORMAL);
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
        return (error);
 }
 
@@ -512,7 +504,7 @@ linker_find_file_by_name(const char *fil
        koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK);
        sprintf(koname, "%s.ko", filename);
 
-       KLD_LOCK_ASSERT();
+       sx_assert(&kld_sx, SA_XLOCKED);
        TAILQ_FOREACH(lf, &linker_files, link) {
                if (strcmp(lf->filename, koname) == 0)
                        break;
@@ -528,7 +520,7 @@ linker_find_file_by_id(int fileid)
 {
        linker_file_t lf;
 
-       KLD_LOCK_ASSERT();
+       sx_assert(&kld_sx, SA_XLOCKED);
        TAILQ_FOREACH(lf, &linker_files, link)
                if (lf->id == fileid && lf->flags & LINKER_FILE_LINKED)
                        break;
@@ -541,13 +533,13 @@ linker_file_foreach(linker_predicate_t *
        linker_file_t lf;
        int retval = 0;
 
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        TAILQ_FOREACH(lf, &linker_files, link) {
                retval = predicate(lf, context);
                if (retval != 0)
                        break;
        }
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
        return (retval);
 }
 
@@ -557,7 +549,8 @@ linker_make_file(const char *pathname, l
        linker_file_t lf;
        const char *filename;
 
-       KLD_LOCK_ASSERT();
+       if (!cold)
+               sx_assert(&kld_sx, SA_XLOCKED);
        filename = linker_basename(pathname);
 
        KLD_DPF(FILE, ("linker_make_file: new file, filename='%s' for 
pathname='%s'\n", filename, pathname));
@@ -591,7 +584,7 @@ linker_file_unload(linker_file_t file, i
        if (prison0.pr_securelevel > 0)
                return (EPERM);
 
-       KLD_LOCK_ASSERT();
+       sx_assert(&kld_sx, SA_XLOCKED);
        KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs));
 
        /* Easy case of just dropping a reference. */
@@ -664,10 +657,10 @@ linker_file_unload(linker_file_t file, i
         */
        if (file->flags & LINKER_FILE_LINKED) {
                file->flags &= ~LINKER_FILE_LINKED;
-               KLD_UNLOCK();
+               sx_xunlock(&kld_sx);
                linker_file_sysuninit(file);
                linker_file_unregister_sysctls(file);
-               KLD_LOCK();
+               sx_xlock(&kld_sx);
        }
        TAILQ_REMOVE(&linker_files, file, link);
 
@@ -706,7 +699,7 @@ linker_file_add_dependency(linker_file_t
 {
        linker_file_t *newdeps;
 
-       KLD_LOCK_ASSERT();
+       sx_assert(&kld_sx, SA_XLOCKED);
        newdeps = malloc((file->ndeps + 1) * sizeof(linker_file_t *),
            M_LINKER, M_WAITOK | M_ZERO);
        if (newdeps == NULL)
@@ -738,12 +731,12 @@ linker_file_lookup_set(linker_file_t fil
 {
        int error, locked;
 
-       locked = KLD_LOCKED();
+       locked = sx_xlocked(&kld_sx);
        if (!locked)
-               KLD_LOCK();
+               sx_xlock(&kld_sx);
        error = LINKER_LOOKUP_SET(file, name, firstp, lastp, countp);
        if (!locked)
-               KLD_UNLOCK();
+               sx_xunlock(&kld_sx);
        return (error);
 }
 
@@ -763,12 +756,12 @@ linker_file_lookup_symbol(linker_file_t 
        caddr_t sym;
        int locked;
 
-       locked = KLD_LOCKED();
+       locked = sx_xlocked(&kld_sx);
        if (!locked)
-               KLD_LOCK();
+               sx_xlock(&kld_sx);
        sym = linker_file_lookup_symbol_internal(file, name, deps);
        if (!locked)
-               KLD_UNLOCK();
+               sx_xunlock(&kld_sx);
        return (sym);
 }
 
@@ -782,7 +775,7 @@ linker_file_lookup_symbol_internal(linke
        size_t common_size = 0;
        int i;
 
-       KLD_LOCK_ASSERT();
+       sx_assert(&kld_sx, SA_XLOCKED);
        KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%p, name=%s, deps=%d\n",
            file, name, deps));
 
@@ -982,9 +975,9 @@ linker_search_symbol_name(caddr_t value,
 {
        int error;
 
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        error = linker_debug_search_symbol_name(value, buf, buflen, offset);
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
        return (error);
 }
 
@@ -1026,10 +1019,10 @@ kern_kldload(struct thread *td, const ch
                modname = file;
        }
 
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        error = linker_load_module(kldname, modname, NULL, NULL, &lf);
        if (error) {
-               KLD_UNLOCK();
+               sx_xunlock(&kld_sx);
                goto done;
        }
        lf->userrefs++;
@@ -1039,13 +1032,13 @@ kern_kldload(struct thread *td, const ch
        EVENTHANDLER_INVOKE(kld_load, lf);
 
 #ifdef HWPMC_HOOKS
-       KLD_DOWNGRADE();
+       sx_downgrade(&kld_sx);
        pkm.pm_file = lf->filename;
        pkm.pm_address = (uintptr_t) lf->address;
        PMC_CALL_HOOK(td, PMC_FN_KLD_LOAD, (void *) &pkm);
-       KLD_UNLOCK_READ();
+       sx_sunlock(&kld_sx);
 #else
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
 #endif
 
 done:
@@ -1088,7 +1081,7 @@ kern_kldunload(struct thread *td, int fi
                return (error);
 
        CURVNET_SET(TD_TO_VNET(td));
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        lf = linker_find_file_by_id(fileid);
        if (lf) {
                KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs));
@@ -1119,13 +1112,13 @@ kern_kldunload(struct thread *td, int fi
 
 #ifdef HWPMC_HOOKS
        if (error == 0) {
-               KLD_DOWNGRADE();
+               sx_downgrade(&kld_sx);
                PMC_CALL_HOOK(td, PMC_FN_KLD_UNLOAD, (void *) &pkm);
-               KLD_UNLOCK_READ();
+               sx_sunlock(&kld_sx);
        } else
-               KLD_UNLOCK();
+               sx_xunlock(&kld_sx);
 #else
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
 #endif
        CURVNET_RESTORE();
        return (error);
@@ -1169,13 +1162,13 @@ sys_kldfind(struct thread *td, struct kl
                goto out;
 
        filename = linker_basename(pathname);
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        lf = linker_find_file_by_name(filename);
        if (lf)
                td->td_retval[0] = lf->id;
        else
                error = ENOENT;
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
 out:
        free(pathname, M_TEMP);
        return (error);
@@ -1193,7 +1186,7 @@ sys_kldnext(struct thread *td, struct kl
                return (error);
 #endif
 
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        if (uap->fileid == 0)
                lf = TAILQ_FIRST(&linker_files);
        else {
@@ -1214,7 +1207,7 @@ sys_kldnext(struct thread *td, struct kl
        else
                td->td_retval[0] = 0;
 out:
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
        return (error);
 }
 
@@ -1253,10 +1246,10 @@ kern_kldstat(struct thread *td, int file
                return (error);
 #endif
 
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        lf = linker_find_file_by_id(fileid);
        if (lf == NULL) {
-               KLD_UNLOCK();
+               sx_xunlock(&kld_sx);
                return (ENOENT);
        }
 
@@ -1274,7 +1267,7 @@ kern_kldstat(struct thread *td, int file
        if (namelen > MAXPATHLEN)
                namelen = MAXPATHLEN;
        bcopy(lf->pathname, &stat->pathname[0], namelen);
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
 
        td->td_retval[0] = 0;
        return (0);
@@ -1293,7 +1286,7 @@ sys_kldfirstmod(struct thread *td, struc
                return (error);
 #endif
 
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        lf = linker_find_file_by_id(uap->fileid);
        if (lf) {
                MOD_SLOCK;
@@ -1305,7 +1298,7 @@ sys_kldfirstmod(struct thread *td, struc
                MOD_SUNLOCK;
        } else
                error = ENOENT;
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
        return (error);
 }
 
@@ -1333,7 +1326,7 @@ sys_kldsym(struct thread *td, struct kld
        symstr = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
        if ((error = copyinstr(lookup.symname, symstr, MAXPATHLEN, NULL)) != 0)
                goto out;
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        if (uap->fileid != 0) {
                lf = linker_find_file_by_id(uap->fileid);
                if (lf == NULL)
@@ -1359,7 +1352,7 @@ sys_kldsym(struct thread *td, struct kld
                if (lf == NULL)
                        error = ENOENT;
        }
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
 out:
        free(symstr, M_TEMP);
        return (error);
@@ -1468,6 +1461,7 @@ linker_preload(void *arg)
        error = 0;
 
        modptr = NULL;
+       sx_xlock(&kld_sx);
        while ((modptr = preload_search_next_name(modptr)) != NULL) {
                modname = (char *)preload_search_info(modptr, MODINFO_NAME);
                modtype = (char *)preload_search_info(modptr, MODINFO_TYPE);
@@ -1649,6 +1643,7 @@ fail:
                TAILQ_REMOVE(&depended_files, lf, loaded);
                linker_file_unload(lf, LINKER_UNLOAD_FORCE);
        }
+       sx_xunlock(&kld_sx);
        /* woohoo! we made it! */
 }
 
@@ -1948,7 +1943,7 @@ linker_hwpmc_list_objects(void)
        int i, nmappings;
 
        nmappings = 0;
-       KLD_LOCK_READ();
+       sx_slock(&kld_sx);
        TAILQ_FOREACH(lf, &linker_files, link)
                nmappings++;
 
@@ -1963,7 +1958,7 @@ linker_hwpmc_list_objects(void)
                kobase[i].pm_address = (uintptr_t)lf->address;
                i++;
        }
-       KLD_UNLOCK_READ();
+       sx_sunlock(&kld_sx);
 
        KASSERT(i > 0, ("linker_hpwmc_list_objects: no kernel objects?"));
 
@@ -1989,7 +1984,7 @@ linker_load_module(const char *kldname, 
        char *pathname;
        int error;
 
-       KLD_LOCK_ASSERT();
+       sx_assert(&kld_sx, SA_XLOCKED);
        if (modname == NULL) {
                /*
                 * We have to load KLD
@@ -2063,7 +2058,7 @@ linker_load_dependencies(linker_file_t l
        /*
         * All files are dependant on /kernel.
         */
-       KLD_LOCK_ASSERT();
+       sx_assert(&kld_sx, SA_XLOCKED);
        if (linker_kernel_file) {
                linker_kernel_file->refs++;
                error = linker_file_add_dependency(lf, linker_kernel_file);
@@ -2155,16 +2150,16 @@ sysctl_kern_function_list(SYSCTL_HANDLER
        error = sysctl_wire_old_buffer(req, 0);
        if (error != 0)
                return (error);
-       KLD_LOCK();
+       sx_xlock(&kld_sx);
        TAILQ_FOREACH(lf, &linker_files, link) {
                error = LINKER_EACH_FUNCTION_NAME(lf,
                    sysctl_kern_function_list_iterate, req);
                if (error) {
-                       KLD_UNLOCK();
+                       sx_xunlock(&kld_sx);
                        return (error);
                }
        }
-       KLD_UNLOCK();
+       sx_xunlock(&kld_sx);
        return (SYSCTL_OUT(req, "", 1));
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to