The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_mutex.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1998 Berkeley Software Design, Inc. All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  * 3. Berkeley Software Design Inc's name may not be used to endorse or
   13  *    promote products derived from this software without specific prior
   14  *    written permission.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  *
   28  *      from BSDI $Id: mutex_witness.c,v 1.1.2.20 2000/04/27 03:10:27 cp Exp $
   29  *      and BSDI $Id: synch_machdep.c,v 2.3.2.39 2000/04/27 03:10:25 cp Exp $
   30  */
   31 
   32 /*
   33  * Machine independent bits of mutex implementation.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD: releng/6.0/sys/kern/kern_mutex.c 151148 2005-10-09 04:30:31Z delphij $");
   38 
   39 #include "opt_adaptive_mutexes.h"
   40 #include "opt_ddb.h"
   41 #include "opt_mprof.h"
   42 #include "opt_mutex_wake_all.h"
   43 #include "opt_sched.h"
   44 
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/bus.h>
   48 #include <sys/conf.h>
   49 #include <sys/kdb.h>
   50 #include <sys/kernel.h>
   51 #include <sys/ktr.h>
   52 #include <sys/lock.h>
   53 #include <sys/malloc.h>
   54 #include <sys/mutex.h>
   55 #include <sys/proc.h>
   56 #include <sys/resourcevar.h>
   57 #include <sys/sched.h>
   58 #include <sys/sbuf.h>
   59 #include <sys/sysctl.h>
   60 #include <sys/turnstile.h>
   61 #include <sys/vmmeter.h>
   62 
   63 #include <machine/atomic.h>
   64 #include <machine/bus.h>
   65 #include <machine/clock.h>
   66 #include <machine/cpu.h>
   67 
   68 #include <ddb/ddb.h>
   69 
   70 #include <vm/vm.h>
   71 #include <vm/vm_extern.h>
   72 
   73 /* 
   74  * Force MUTEX_WAKE_ALL for now.
   75  * single thread wakeup needs fixes to avoid race conditions with 
   76  * priority inheritance.
   77  */
   78 #ifndef MUTEX_WAKE_ALL
   79 #define MUTEX_WAKE_ALL
   80 #endif
   81 
   82 /*
   83  * Internal utility macros.
   84  */
   85 #define mtx_unowned(m)  ((m)->mtx_lock == MTX_UNOWNED)
   86 
   87 #define mtx_owner(m)    (mtx_unowned((m)) ? NULL \
   88         : (struct thread *)((m)->mtx_lock & MTX_FLAGMASK))
   89 
   90 /*
   91  * Lock classes for sleep and spin mutexes.
   92  */
   93 struct lock_class lock_class_mtx_sleep = {
   94         "sleep mutex",
   95         LC_SLEEPLOCK | LC_RECURSABLE
   96 };
   97 struct lock_class lock_class_mtx_spin = {
   98         "spin mutex",
   99         LC_SPINLOCK | LC_RECURSABLE
  100 };
  101 
  102 /*
  103  * System-wide mutexes
  104  */
  105 struct mtx sched_lock;
  106 struct mtx Giant;
  107 
  108 #ifdef MUTEX_PROFILING
  109 SYSCTL_NODE(_debug, OID_AUTO, mutex, CTLFLAG_RD, NULL, "mutex debugging");
  110 SYSCTL_NODE(_debug_mutex, OID_AUTO, prof, CTLFLAG_RD, NULL, "mutex profiling");
  111 static int mutex_prof_enable = 0;
  112 SYSCTL_INT(_debug_mutex_prof, OID_AUTO, enable, CTLFLAG_RW,
  113     &mutex_prof_enable, 0, "Enable tracing of mutex holdtime");
  114 
  115 struct mutex_prof {
  116         const char      *name;
  117         const char      *file;
  118         int             line;
  119         uintmax_t       cnt_max;
  120         uintmax_t       cnt_tot;
  121         uintmax_t       cnt_cur;
  122         uintmax_t       cnt_contest_holding;
  123         uintmax_t       cnt_contest_locking;
  124         struct mutex_prof *next;
  125 };
  126 
  127 /*
  128  * mprof_buf is a static pool of profiling records to avoid possible
  129  * reentrance of the memory allocation functions.
  130  *
  131  * Note: NUM_MPROF_BUFFERS must be smaller than MPROF_HASH_SIZE.
  132  */
  133 #ifdef MPROF_BUFFERS
  134 #define NUM_MPROF_BUFFERS       MPROF_BUFFERS
  135 #else
  136 #define NUM_MPROF_BUFFERS       1000
  137 #endif
  138 static struct mutex_prof mprof_buf[NUM_MPROF_BUFFERS];
  139 static int first_free_mprof_buf;
  140 #ifndef MPROF_HASH_SIZE
  141 #define MPROF_HASH_SIZE         1009
  142 #endif
  143 #if NUM_MPROF_BUFFERS >= MPROF_HASH_SIZE
  144 #error MPROF_BUFFERS must be larger than MPROF_HASH_SIZE
  145 #endif
  146 static struct mutex_prof *mprof_hash[MPROF_HASH_SIZE];
  147 /* SWAG: sbuf size = avg stat. line size * number of locks */
  148 #define MPROF_SBUF_SIZE         256 * 400
  149 
  150 static int mutex_prof_acquisitions;
  151 SYSCTL_INT(_debug_mutex_prof, OID_AUTO, acquisitions, CTLFLAG_RD,
  152     &mutex_prof_acquisitions, 0, "Number of mutex acquistions recorded");
  153 static int mutex_prof_records;
  154 SYSCTL_INT(_debug_mutex_prof, OID_AUTO, records, CTLFLAG_RD,
  155     &mutex_prof_records, 0, "Number of profiling records");
  156 static int mutex_prof_maxrecords = NUM_MPROF_BUFFERS;
  157 SYSCTL_INT(_debug_mutex_prof, OID_AUTO, maxrecords, CTLFLAG_RD,
  158     &mutex_prof_maxrecords, 0, "Maximum number of profiling records");
  159 static int mutex_prof_rejected;
  160 SYSCTL_INT(_debug_mutex_prof, OID_AUTO, rejected, CTLFLAG_RD,
  161     &mutex_prof_rejected, 0, "Number of rejected profiling records");
  162 static int mutex_prof_hashsize = MPROF_HASH_SIZE;
  163 SYSCTL_INT(_debug_mutex_prof, OID_AUTO, hashsize, CTLFLAG_RD,
  164     &mutex_prof_hashsize, 0, "Hash size");
  165 static int mutex_prof_collisions = 0;
  166 SYSCTL_INT(_debug_mutex_prof, OID_AUTO, collisions, CTLFLAG_RD,
  167     &mutex_prof_collisions, 0, "Number of hash collisions");
  168 
  169 /*
  170  * mprof_mtx protects the profiling buffers and the hash.
  171  */
  172 static struct mtx mprof_mtx;
  173 MTX_SYSINIT(mprof, &mprof_mtx, "mutex profiling lock", MTX_SPIN | MTX_QUIET);
  174 
  175 static u_int64_t
  176 nanoseconds(void)
  177 {
  178         struct timespec tv;
  179 
  180         nanotime(&tv);
  181         return (tv.tv_sec * (u_int64_t)1000000000 + tv.tv_nsec);
  182 }
  183 
  184 static int
  185 dump_mutex_prof_stats(SYSCTL_HANDLER_ARGS)
  186 {
  187         struct sbuf *sb;
  188         int error, i;
  189         static int multiplier = 1;
  190 
  191         if (first_free_mprof_buf == 0)
  192                 return (SYSCTL_OUT(req, "No locking recorded",
  193                     sizeof("No locking recorded")));
  194 
  195 retry_sbufops:
  196         sb = sbuf_new(NULL, NULL, MPROF_SBUF_SIZE * multiplier, SBUF_FIXEDLEN);
  197         sbuf_printf(sb, "\n%6s %12s %11s %5s %12s %12s %s\n",
  198             "max", "total", "count", "avg", "cnt_hold", "cnt_lock", "name");
  199         /*
  200          * XXX this spinlock seems to be by far the largest perpetrator
  201          * of spinlock latency (1.6 msec on an Athlon1600 was recorded
  202          * even before I pessimized it further by moving the average
  203          * computation here).
  204          */
  205         mtx_lock_spin(&mprof_mtx);
  206         for (i = 0; i < first_free_mprof_buf; ++i) {
  207                 sbuf_printf(sb, "%6ju %12ju %11ju %5ju %12ju %12ju %s:%d (%s)\n",
  208                     mprof_buf[i].cnt_max / 1000,
  209                     mprof_buf[i].cnt_tot / 1000,
  210                     mprof_buf[i].cnt_cur,
  211                     mprof_buf[i].cnt_cur == 0 ? (uintmax_t)0 :
  212                         mprof_buf[i].cnt_tot / (mprof_buf[i].cnt_cur * 1000),
  213                     mprof_buf[i].cnt_contest_holding,
  214                     mprof_buf[i].cnt_contest_locking,
  215                     mprof_buf[i].file, mprof_buf[i].line, mprof_buf[i].name);
  216                 if (sbuf_overflowed(sb)) {
  217                         mtx_unlock_spin(&mprof_mtx);
  218                         sbuf_delete(sb);
  219                         multiplier++;
  220                         goto retry_sbufops;
  221                 }
  222         }
  223         mtx_unlock_spin(&mprof_mtx);
  224         sbuf_finish(sb);
  225         error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
  226         sbuf_delete(sb);
  227         return (error);
  228 }
  229 SYSCTL_PROC(_debug_mutex_prof, OID_AUTO, stats, CTLTYPE_STRING | CTLFLAG_RD,
  230     NULL, 0, dump_mutex_prof_stats, "A", "Mutex profiling statistics");
  231 
  232 static int
  233 reset_mutex_prof_stats(SYSCTL_HANDLER_ARGS)
  234 {
  235         int error, v;
  236 
  237         if (first_free_mprof_buf == 0)
  238                 return (0);
  239 
  240         v = 0;
  241         error = sysctl_handle_int(oidp, &v, 0, req);
  242         if (error)
  243                 return (error);
  244         if (req->newptr == NULL)
  245                 return (error);
  246         if (v == 0)
  247                 return (0);
  248 
  249         mtx_lock_spin(&mprof_mtx);
  250         bzero(mprof_buf, sizeof(*mprof_buf) * first_free_mprof_buf);
  251         bzero(mprof_hash, sizeof(struct mtx *) * MPROF_HASH_SIZE);
  252         first_free_mprof_buf = 0;
  253         mtx_unlock_spin(&mprof_mtx);
  254         return (0);
  255 }
  256 SYSCTL_PROC(_debug_mutex_prof, OID_AUTO, reset, CTLTYPE_INT | CTLFLAG_RW,
  257     NULL, 0, reset_mutex_prof_stats, "I", "Reset mutex profiling statistics");
  258 #endif
  259 
  260 /*
  261  * Function versions of the inlined __mtx_* macros.  These are used by
  262  * modules and can also be called from assembly language if needed.
  263  */
  264 void
  265 _mtx_lock_flags(struct mtx *m, int opts, const char *file, int line)
  266 {
  267 
  268         MPASS(curthread != NULL);
  269         KASSERT(m->mtx_object.lo_class == &lock_class_mtx_sleep,
  270             ("mtx_lock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
  271             file, line));
  272         WITNESS_CHECKORDER(&m->mtx_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
  273             file, line);
  274         _get_sleep_lock(m, curthread, opts, file, line);
  275         LOCK_LOG_LOCK("LOCK", &m->mtx_object, opts, m->mtx_recurse, file,
  276             line);
  277         WITNESS_LOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
  278 #ifdef MUTEX_PROFILING
  279         /* don't reset the timer when/if recursing */
  280         if (m->mtx_acqtime == 0) {
  281                 m->mtx_filename = file;
  282                 m->mtx_lineno = line;
  283                 m->mtx_acqtime = mutex_prof_enable ? nanoseconds() : 0;
  284                 ++mutex_prof_acquisitions;
  285         }
  286 #endif
  287 }
  288 
  289 void
  290 _mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line)
  291 {
  292 
  293         MPASS(curthread != NULL);
  294         KASSERT(m->mtx_object.lo_class == &lock_class_mtx_sleep,
  295             ("mtx_unlock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
  296             file, line));
  297         WITNESS_UNLOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
  298         LOCK_LOG_LOCK("UNLOCK", &m->mtx_object, opts, m->mtx_recurse, file,
  299             line);
  300         mtx_assert(m, MA_OWNED);
  301 #ifdef MUTEX_PROFILING
  302         if (m->mtx_acqtime != 0) {
  303                 static const char *unknown = "(unknown)";
  304                 struct mutex_prof *mpp;
  305                 u_int64_t acqtime, now;
  306                 const char *p, *q;
  307                 volatile u_int hash;
  308 
  309                 now = nanoseconds();
  310                 acqtime = m->mtx_acqtime;
  311                 m->mtx_acqtime = 0;
  312                 if (now <= acqtime)
  313                         goto out;
  314                 for (p = m->mtx_filename;
  315                     p != NULL && strncmp(p, "../", 3) == 0; p += 3)
  316                         /* nothing */ ;
  317                 if (p == NULL || *p == '\0')
  318                         p = unknown;
  319                 for (hash = m->mtx_lineno, q = p; *q != '\0'; ++q)
  320                         hash = (hash * 2 + *q) % MPROF_HASH_SIZE;
  321                 mtx_lock_spin(&mprof_mtx);
  322                 for (mpp = mprof_hash[hash]; mpp != NULL; mpp = mpp->next)
  323                         if (mpp->line == m->mtx_lineno &&
  324                             strcmp(mpp->file, p) == 0)
  325                                 break;
  326                 if (mpp == NULL) {
  327                         /* Just exit if we cannot get a trace buffer */
  328                         if (first_free_mprof_buf >= NUM_MPROF_BUFFERS) {
  329                                 ++mutex_prof_rejected;
  330                                 goto unlock;
  331                         }
  332                         mpp = &mprof_buf[first_free_mprof_buf++];
  333                         mpp->name = mtx_name(m);
  334                         mpp->file = p;
  335                         mpp->line = m->mtx_lineno;
  336                         mpp->next = mprof_hash[hash];
  337                         if (mprof_hash[hash] != NULL)
  338                                 ++mutex_prof_collisions;
  339                         mprof_hash[hash] = mpp;
  340                         ++mutex_prof_records;
  341                 }
  342                 /*
  343                  * Record if the mutex has been held longer now than ever
  344                  * before.
  345                  */
  346                 if (now - acqtime > mpp->cnt_max)
  347                         mpp->cnt_max = now - acqtime;
  348                 mpp->cnt_tot += now - acqtime;
  349                 mpp->cnt_cur++;
  350                 /*
  351                  * There's a small race, really we should cmpxchg
  352                  * 0 with the current value, but that would bill
  353                  * the contention to the wrong lock instance if
  354                  * it followed this also.
  355                  */
  356                 mpp->cnt_contest_holding += m->mtx_contest_holding;
  357                 m->mtx_contest_holding = 0;
  358                 mpp->cnt_contest_locking += m->mtx_contest_locking;
  359                 m->mtx_contest_locking = 0;
  360 unlock:
  361                 mtx_unlock_spin(&mprof_mtx);
  362         }
  363 out:
  364 #endif
  365         _rel_sleep_lock(m, curthread, opts, file, line);
  366 }
  367 
  368 void
  369 _mtx_lock_spin_flags(struct mtx *m, int opts, const char *file, int line)
  370 {
  371 
  372         MPASS(curthread != NULL);
  373         KASSERT(m->mtx_object.lo_class == &lock_class_mtx_spin,
  374             ("mtx_lock_spin() of sleep mutex %s @ %s:%d",
  375             m->mtx_object.lo_name, file, line));
  376         WITNESS_CHECKORDER(&m->mtx_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
  377             file, line);
  378         _get_spin_lock(m, curthread, opts, file, line);
  379         LOCK_LOG_LOCK("LOCK", &m->mtx_object, opts, m->mtx_recurse, file,
  380             line);
  381         WITNESS_LOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
  382 }
  383 
  384 void
  385 _mtx_unlock_spin_flags(struct mtx *m, int opts, const char *file, int line)
  386 {
  387 
  388         MPASS(curthread != NULL);
  389         KASSERT(m->mtx_object.lo_class == &lock_class_mtx_spin,
  390             ("mtx_unlock_spin() of sleep mutex %s @ %s:%d",
  391             m->mtx_object.lo_name, file, line));
  392         WITNESS_UNLOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line);
  393         LOCK_LOG_LOCK("UNLOCK", &m->mtx_object, opts, m->mtx_recurse, file,
  394             line);
  395         mtx_assert(m, MA_OWNED);
  396         _rel_spin_lock(m);
  397 }
  398 
  399 /*
  400  * The important part of mtx_trylock{,_flags}()
  401  * Tries to acquire lock `m.'  If this function is called on a mutex that
  402  * is already owned, it will recursively acquire the lock.
  403  */
  404 int
  405 _mtx_trylock(struct mtx *m, int opts, const char *file, int line)
  406 {
  407         int rval;
  408 
  409         MPASS(curthread != NULL);
  410         KASSERT(m->mtx_object.lo_class == &lock_class_mtx_sleep,
  411             ("mtx_trylock() of spin mutex %s @ %s:%d", m->mtx_object.lo_name,
  412             file, line));
  413 
  414         if (mtx_owned(m) && (m->mtx_object.lo_flags & LO_RECURSABLE) != 0) {
  415                 m->mtx_recurse++;
  416                 atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
  417                 rval = 1;
  418         } else
  419                 rval = _obtain_lock(m, (uintptr_t)curthread);
  420 
  421         LOCK_LOG_TRY("LOCK", &m->mtx_object, opts, rval, file, line);
  422         if (rval)
  423                 WITNESS_LOCK(&m->mtx_object, opts | LOP_EXCLUSIVE | LOP_TRYLOCK,
  424                     file, line);
  425 
  426         return (rval);
  427 }
  428 
  429 /*
  430  * _mtx_lock_sleep: the tougher part of acquiring an MTX_DEF lock.
  431  *
  432  * We call this if the lock is either contested (i.e. we need to go to
  433  * sleep waiting for it), or if we need to recurse on it.
  434  */
  435 void
  436 _mtx_lock_sleep(struct mtx *m, uintptr_t tid, int opts, const char *file,
  437     int line)
  438 {
  439 #if defined(SMP) && !defined(NO_ADAPTIVE_MUTEXES)
  440         struct thread *owner;
  441 #endif
  442         uintptr_t v;
  443 #ifdef KTR
  444         int cont_logged = 0;
  445 #endif
  446 #ifdef MUTEX_PROFILING
  447         int contested;
  448 #endif
  449 
  450         if (mtx_owned(m)) {
  451                 KASSERT((m->mtx_object.lo_flags & LO_RECURSABLE) != 0,
  452             ("_mtx_lock_sleep: recursed on non-recursive mutex %s @ %s:%d\n",
  453                     m->mtx_object.lo_name, file, line));
  454                 m->mtx_recurse++;
  455                 atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
  456                 if (LOCK_LOG_TEST(&m->mtx_object, opts))
  457                         CTR1(KTR_LOCK, "_mtx_lock_sleep: %p recursing", m);
  458                 return;
  459         }
  460 
  461         if (LOCK_LOG_TEST(&m->mtx_object, opts))
  462                 CTR4(KTR_LOCK,
  463                     "_mtx_lock_sleep: %s contested (lock=%p) at %s:%d",
  464                     m->mtx_object.lo_name, (void *)m->mtx_lock, file, line);
  465 
  466 #ifdef MUTEX_PROFILING
  467         contested = 0;
  468 #endif
  469         while (!_obtain_lock(m, tid)) {
  470 #ifdef MUTEX_PROFILING
  471                 contested = 1;
  472                 atomic_add_int(&m->mtx_contest_holding, 1);
  473 #endif
  474                 turnstile_lock(&m->mtx_object);
  475                 v = m->mtx_lock;
  476 
  477                 /*
  478                  * Check if the lock has been released while spinning for
  479                  * the turnstile chain lock.
  480                  */
  481                 if (v == MTX_UNOWNED) {
  482                         turnstile_release(&m->mtx_object);
  483                         cpu_spinwait();
  484                         continue;
  485                 }
  486 
  487 #ifdef MUTEX_WAKE_ALL
  488                 MPASS(v != MTX_CONTESTED);
  489 #else
  490                 /*
  491                  * The mutex was marked contested on release. This means that
  492                  * there are other threads blocked on it.  Grab ownership of
  493                  * it and propagate its priority to the current thread if
  494                  * necessary.
  495                  */
  496                 if (v == MTX_CONTESTED) {
  497                         m->mtx_lock = tid | MTX_CONTESTED;
  498                         turnstile_claim(&m->mtx_object);
  499                         break;
  500                 }
  501 #endif
  502 
  503                 /*
  504                  * If the mutex isn't already contested and a failure occurs
  505                  * setting the contested bit, the mutex was either released
  506                  * or the state of the MTX_RECURSED bit changed.
  507                  */
  508                 if ((v & MTX_CONTESTED) == 0 &&
  509                     !atomic_cmpset_ptr(&m->mtx_lock, v, v | MTX_CONTESTED)) {
  510                         turnstile_release(&m->mtx_object);
  511                         cpu_spinwait();
  512                         continue;
  513                 }
  514 
  515 #if defined(SMP) && !defined(NO_ADAPTIVE_MUTEXES)
  516                 /*
  517                  * If the current owner of the lock is executing on another
  518                  * CPU, spin instead of blocking.
  519                  */
  520                 owner = (struct thread *)(v & MTX_FLAGMASK);
  521 #ifdef ADAPTIVE_GIANT
  522                 if (TD_IS_RUNNING(owner)) {
  523 #else
  524                 if (m != &Giant && TD_IS_RUNNING(owner)) {
  525 #endif
  526                         turnstile_release(&m->mtx_object);
  527                         while (mtx_owner(m) == owner && TD_IS_RUNNING(owner)) {
  528                                 cpu_spinwait();
  529                         }
  530                         continue;
  531                 }
  532 #endif  /* SMP && !NO_ADAPTIVE_MUTEXES */
  533 
  534                 /*
  535                  * We definitely must sleep for this lock.
  536                  */
  537                 mtx_assert(m, MA_NOTOWNED);
  538 
  539 #ifdef KTR
  540                 if (!cont_logged) {
  541                         CTR6(KTR_CONTENTION,
  542                             "contention: %p at %s:%d wants %s, taken by %s:%d",
  543                             (void *)tid, file, line, m->mtx_object.lo_name,
  544                             WITNESS_FILE(&m->mtx_object),
  545                             WITNESS_LINE(&m->mtx_object));
  546                         cont_logged = 1;
  547                 }
  548 #endif
  549 
  550                 /*
  551                  * Block on the turnstile.
  552                  */
  553                 turnstile_wait(&m->mtx_object, mtx_owner(m));
  554         }
  555 
  556 #ifdef KTR
  557         if (cont_logged) {
  558                 CTR4(KTR_CONTENTION,
  559                     "contention end: %s acquired by %p at %s:%d",
  560                     m->mtx_object.lo_name, (void *)tid, file, line);
  561         }
  562 #endif
  563 #ifdef MUTEX_PROFILING
  564         if (contested)
  565                 m->mtx_contest_locking++;
  566         m->mtx_contest_holding = 0;
  567 #endif
  568         return;
  569 }
  570 
  571 #ifdef SMP
  572 /*
  573  * _mtx_lock_spin: the tougher part of acquiring an MTX_SPIN lock.
  574  *
  575  * This is only called if we need to actually spin for the lock. Recursion
  576  * is handled inline.
  577  */
  578 void
  579 _mtx_lock_spin(struct mtx *m, uintptr_t tid, int opts, const char *file,
  580     int line)
  581 {
  582         int i = 0;
  583 
  584         if (LOCK_LOG_TEST(&m->mtx_object, opts))
  585                 CTR1(KTR_LOCK, "_mtx_lock_spin: %p spinning", m);
  586 
  587         for (;;) {
  588                 if (_obtain_lock(m, tid))
  589                         break;
  590 
  591                 /* Give interrupts a chance while we spin. */
  592                 spinlock_exit();
  593                 while (m->mtx_lock != MTX_UNOWNED) {
  594                         if (i++ < 10000000) {
  595                                 cpu_spinwait();
  596                                 continue;
  597                         }
  598                         if (i < 60000000)
  599                                 DELAY(1);
  600                         else if (!kdb_active && !panicstr) {
  601                                 printf("spin lock %s held by %p for > 5 seconds\n",
  602                                     m->mtx_object.lo_name, (void *)m->mtx_lock);
  603 #ifdef WITNESS
  604                                 witness_display_spinlock(&m->mtx_object,
  605                                     mtx_owner(m));
  606 #endif
  607                                 panic("spin lock held too long");
  608                         }
  609                         cpu_spinwait();
  610                 }
  611                 spinlock_enter();
  612         }
  613 
  614         if (LOCK_LOG_TEST(&m->mtx_object, opts))
  615                 CTR1(KTR_LOCK, "_mtx_lock_spin: %p spin done", m);
  616 
  617         return;
  618 }
  619 #endif /* SMP */
  620 
  621 /*
  622  * _mtx_unlock_sleep: the tougher part of releasing an MTX_DEF lock.
  623  *
  624  * We are only called here if the lock is recursed or contested (i.e. we
  625  * need to wake up a blocked thread).
  626  */
  627 void
  628 _mtx_unlock_sleep(struct mtx *m, int opts, const char *file, int line)
  629 {
  630         struct turnstile *ts;
  631 #ifndef PREEMPTION
  632         struct thread *td, *td1;
  633 #endif
  634 
  635         if (mtx_recursed(m)) {
  636                 if (--(m->mtx_recurse) == 0)
  637                         atomic_clear_ptr(&m->mtx_lock, MTX_RECURSED);
  638                 if (LOCK_LOG_TEST(&m->mtx_object, opts))
  639                         CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p unrecurse", m);
  640                 return;
  641         }
  642 
  643         turnstile_lock(&m->mtx_object);
  644         ts = turnstile_lookup(&m->mtx_object);
  645         if (LOCK_LOG_TEST(&m->mtx_object, opts))
  646                 CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p contested", m);
  647 
  648 #if defined(SMP) && !defined(NO_ADAPTIVE_MUTEXES)
  649         if (ts == NULL) {
  650                 _release_lock_quick(m);
  651                 if (LOCK_LOG_TEST(&m->mtx_object, opts))
  652                         CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p no sleepers", m);
  653                 turnstile_release(&m->mtx_object);
  654                 return;
  655         }
  656 #else
  657         MPASS(ts != NULL);
  658 #endif
  659 #ifndef PREEMPTION
  660         /* XXX */
  661         td1 = turnstile_head(ts);
  662 #endif
  663 #ifdef MUTEX_WAKE_ALL
  664         turnstile_broadcast(ts);
  665         _release_lock_quick(m);
  666 #else
  667         if (turnstile_signal(ts)) {
  668                 _release_lock_quick(m);
  669                 if (LOCK_LOG_TEST(&m->mtx_object, opts))
  670                         CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p not held", m);
  671         } else {
  672                 m->mtx_lock = MTX_CONTESTED;
  673                 if (LOCK_LOG_TEST(&m->mtx_object, opts))
  674                         CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p still contested",
  675                             m);
  676         }
  677 #endif
  678         turnstile_unpend(ts);
  679 
  680 #ifndef PREEMPTION
  681         /*
  682          * XXX: This is just a hack until preemption is done.  However,
  683          * once preemption is done we need to either wrap the
  684          * turnstile_signal() and release of the actual lock in an
  685          * extra critical section or change the preemption code to
  686          * always just set a flag and never do instant-preempts.
  687          */
  688         td = curthread;
  689         if (td->td_critnest > 0 || td1->td_priority >= td->td_priority)
  690                 return;
  691         mtx_lock_spin(&sched_lock);
  692         if (!TD_IS_RUNNING(td1)) {
  693 #ifdef notyet
  694                 if (td->td_ithd != NULL) {
  695                         struct ithd *it = td->td_ithd;
  696 
  697                         if (it->it_interrupted) {
  698                                 if (LOCK_LOG_TEST(&m->mtx_object, opts))
  699                                         CTR2(KTR_LOCK,
  700                                     "_mtx_unlock_sleep: %p interrupted %p",
  701                                             it, it->it_interrupted);
  702                                 intr_thd_fixup(it);
  703                         }
  704                 }
  705 #endif
  706                 if (LOCK_LOG_TEST(&m->mtx_object, opts))
  707                         CTR2(KTR_LOCK,
  708                             "_mtx_unlock_sleep: %p switching out lock=%p", m,
  709                             (void *)m->mtx_lock);
  710 
  711                 mi_switch(SW_INVOL, NULL);
  712                 if (LOCK_LOG_TEST(&m->mtx_object, opts))
  713                         CTR2(KTR_LOCK, "_mtx_unlock_sleep: %p resuming lock=%p",
  714                             m, (void *)m->mtx_lock);
  715         }
  716         mtx_unlock_spin(&sched_lock);
  717 #endif
  718 
  719         return;
  720 }
  721 
  722 /*
  723  * All the unlocking of MTX_SPIN locks is done inline.
  724  * See the _rel_spin_lock() macro for the details.
  725  */
  726 
  727 /*
  728  * The backing function for the INVARIANTS-enabled mtx_assert()
  729  */
  730 #ifdef INVARIANT_SUPPORT
  731 void
  732 _mtx_assert(struct mtx *m, int what, const char *file, int line)
  733 {
  734 
  735         if (panicstr != NULL || dumping)
  736                 return;
  737         switch (what) {
  738         case MA_OWNED:
  739         case MA_OWNED | MA_RECURSED:
  740         case MA_OWNED | MA_NOTRECURSED:
  741                 if (!mtx_owned(m))
  742                         panic("mutex %s not owned at %s:%d",
  743                             m->mtx_object.lo_name, file, line);
  744                 if (mtx_recursed(m)) {
  745                         if ((what & MA_NOTRECURSED) != 0)
  746                                 panic("mutex %s recursed at %s:%d",
  747                                     m->mtx_object.lo_name, file, line);
  748                 } else if ((what & MA_RECURSED) != 0) {
  749                         panic("mutex %s unrecursed at %s:%d",
  750                             m->mtx_object.lo_name, file, line);
  751                 }
  752                 break;
  753         case MA_NOTOWNED:
  754                 if (mtx_owned(m))
  755                         panic("mutex %s owned at %s:%d",
  756                             m->mtx_object.lo_name, file, line);
  757                 break;
  758         default:
  759                 panic("unknown mtx_assert at %s:%d", file, line);
  760         }
  761 }
  762 #endif
  763 
  764 /*
  765  * The MUTEX_DEBUG-enabled mtx_validate()
  766  *
  767  * Most of these checks have been moved off into the LO_INITIALIZED flag
  768  * maintained by the witness code.
  769  */
  770 #ifdef MUTEX_DEBUG
  771 
  772 void    mtx_validate(struct mtx *);
  773 
  774 void
  775 mtx_validate(struct mtx *m)
  776 {
  777 
  778 /*
  779  * XXX: When kernacc() does not require Giant we can reenable this check
  780  */
  781 #ifdef notyet
  782 /*
  783  * XXX - When kernacc() is fixed on the alpha to handle K0_SEG memory properly
  784  * we can re-enable the kernacc() checks.
  785  */
  786 #ifndef __alpha__
  787         /*
  788          * Can't call kernacc() from early init386(), especially when
  789          * initializing Giant mutex, because some stuff in kernacc()
  790          * requires Giant itself.
  791          */
  792         if (!cold)
  793                 if (!kernacc((caddr_t)m, sizeof(m),
  794                     VM_PROT_READ | VM_PROT_WRITE))
  795                         panic("Can't read and write to mutex %p", m);
  796 #endif
  797 #endif
  798 }
  799 #endif
  800 
  801 /*
  802  * General init routine used by the MTX_SYSINIT() macro.
  803  */
  804 void
  805 mtx_sysinit(void *arg)
  806 {
  807         struct mtx_args *margs = arg;
  808 
  809         mtx_init(margs->ma_mtx, margs->ma_desc, NULL, margs->ma_opts);
  810 }
  811 
  812 /*
  813  * Mutex initialization routine; initialize lock `m' of type contained in
  814  * `opts' with options contained in `opts' and name `name.'  The optional
  815  * lock type `type' is used as a general lock category name for use with
  816  * witness.
  817  */
  818 void
  819 mtx_init(struct mtx *m, const char *name, const char *type, int opts)
  820 {
  821         struct lock_object *lock;
  822 
  823         MPASS((opts & ~(MTX_SPIN | MTX_QUIET | MTX_RECURSE |
  824             MTX_NOWITNESS | MTX_DUPOK)) == 0);
  825 
  826 #ifdef MUTEX_DEBUG
  827         /* Diagnostic and error correction */
  828         mtx_validate(m);
  829 #endif
  830 
  831         lock = &m->mtx_object;
  832         KASSERT((lock->lo_flags & LO_INITIALIZED) == 0,
  833             ("mutex \"%s\" %p already initialized", name, m));
  834         bzero(m, sizeof(*m));
  835         if (opts & MTX_SPIN)
  836                 lock->lo_class = &lock_class_mtx_spin;
  837         else
  838                 lock->lo_class = &lock_class_mtx_sleep;
  839         lock->lo_name = name;
  840         lock->lo_type = type != NULL ? type : name;
  841         if (opts & MTX_QUIET)
  842                 lock->lo_flags = LO_QUIET;
  843         if (opts & MTX_RECURSE)
  844                 lock->lo_flags |= LO_RECURSABLE;
  845         if ((opts & MTX_NOWITNESS) == 0)
  846                 lock->lo_flags |= LO_WITNESS;
  847         if (opts & MTX_DUPOK)
  848                 lock->lo_flags |= LO_DUPOK;
  849 
  850         m->mtx_lock = MTX_UNOWNED;
  851 
  852         LOCK_LOG_INIT(lock, opts);
  853 
  854         WITNESS_INIT(lock);
  855 }
  856 
  857 /*
  858  * Remove lock `m' from all_mtx queue.  We don't allow MTX_QUIET to be
  859  * passed in as a flag here because if the corresponding mtx_init() was
  860  * called with MTX_QUIET set, then it will already be set in the mutex's
  861  * flags.
  862  */
  863 void
  864 mtx_destroy(struct mtx *m)
  865 {
  866 
  867         LOCK_LOG_DESTROY(&m->mtx_object, 0);
  868 
  869         if (!mtx_owned(m))
  870                 MPASS(mtx_unowned(m));
  871         else {
  872                 MPASS((m->mtx_lock & (MTX_RECURSED|MTX_CONTESTED)) == 0);
  873 
  874                 /* Tell witness this isn't locked to make it happy. */
  875                 WITNESS_UNLOCK(&m->mtx_object, LOP_EXCLUSIVE, __FILE__,
  876                     __LINE__);
  877         }
  878 
  879         WITNESS_DESTROY(&m->mtx_object);
  880 }
  881 
  882 /*
  883  * Intialize the mutex code and system mutexes.  This is called from the MD
  884  * startup code prior to mi_startup().  The per-CPU data space needs to be
  885  * setup before this is called.
  886  */
  887 void
  888 mutex_init(void)
  889 {
  890 
  891         /* Setup thread0 so that mutexes work. */
  892         LIST_INIT(&thread0.td_contested);
  893 
  894         /* Setup turnstiles so that sleep mutexes work. */
  895         init_turnstiles();
  896 
  897         /*
  898          * Initialize mutexes.
  899          */
  900         mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
  901         mtx_init(&sched_lock, "sched lock", NULL, MTX_SPIN | MTX_RECURSE);
  902         mtx_init(&proc0.p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK);
  903         mtx_lock(&Giant);
  904 }

Cache object: a6ed8cb966a0b6e2d44a5a8cc3435f3d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.