1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * Big Theory Statement for mutual exclusion locking primitives. 31 * 32 * A mutex serializes multiple threads so that only one thread 33 * (the "owner" of the mutex) is active at a time. See mutex(9F) 34 * for a full description of the interfaces and programming model. 35 * The rest of this comment describes the implementation. 36 * 37 * Mutexes come in two flavors: adaptive and spin. mutex_init(9F) 38 * determines the type based solely on the iblock cookie (PIL) argument. 39 * PIL > LOCK_LEVEL implies a spin lock; everything else is adaptive. 40 * 41 * Spin mutexes block interrupts and spin until the lock becomes available. 42 * A thread may not sleep, or call any function that might sleep, while 43 * holding a spin mutex. With few exceptions, spin mutexes should only 44 * be used to synchronize with interrupt handlers. 45 * 46 * Adaptive mutexes (the default type) spin if the owner is running on 47 * another CPU and block otherwise. This policy is based on the assumption 48 * that mutex hold times are typically short enough that the time spent 49 * spinning is less than the time it takes to block. If you need mutual 50 * exclusion semantics with long hold times, consider an rwlock(9F) as 51 * RW_WRITER. Better still, reconsider the algorithm: if it requires 52 * mutual exclusion for long periods of time, it's probably not scalable. 53 * 54 * Adaptive mutexes are overwhelmingly more common than spin mutexes, 55 * so mutex_enter() assumes that the lock is adaptive. We get away 56 * with this by structuring mutexes so that an attempt to acquire a 57 * spin mutex as adaptive always fails. When mutex_enter() fails 58 * it punts to mutex_vector_enter(), which does all the hard stuff. 59 * 60 * mutex_vector_enter() first checks the type. If it's spin mutex, 61 * we just call lock_set_spl() and return. If it's an adaptive mutex, 62 * we check to see what the owner is doing. If the owner is running, 63 * we spin until the lock becomes available; if not, we mark the lock 64 * as having waiters and block. 65 * 66 * Blocking on a mutex is surprisingly delicate dance because, for speed, 67 * mutex_exit() doesn't use an atomic instruction. Thus we have to work 68 * a little harder in the (rarely-executed) blocking path to make sure 69 * we don't block on a mutex that's just been released -- otherwise we 70 * might never be woken up. 71 * 72 * The logic for synchronizing mutex_vector_enter() with mutex_exit() 73 * in the face of preemption and relaxed memory ordering is as follows: 74 * 75 * (1) Preemption in the middle of mutex_exit() must cause mutex_exit() 76 * to restart. Each platform must enforce this by checking the 77 * interrupted PC in the interrupt handler (or on return from trap -- 78 * whichever is more convenient for the platform). If the PC 79 * lies within the critical region of mutex_exit(), the interrupt 80 * handler must reset the PC back to the beginning of mutex_exit(). 81 * The critical region consists of all instructions up to, but not 82 * including, the store that clears the lock (which, of course, 83 * must never be executed twice.) 84 * 85 * This ensures that the owner will always check for waiters after 86 * resuming from a previous preemption. 87 * 88 * (2) A thread resuming in mutex_exit() does (at least) the following: 89 * 90 * when resuming: set CPU_THREAD = owner 91 * membar #StoreLoad 92 * 93 * in mutex_exit: check waiters bit; do wakeup if set 94 * membar #LoadStore|#StoreStore 95 * clear owner 96 * (at this point, other threads may or may not grab 97 * the lock, and we may or may not reacquire it) 98 * 99 * when blocking: membar #StoreStore (due to disp_lock_enter()) 100 * set CPU_THREAD = (possibly) someone else 101 * 102 * (3) A thread blocking in mutex_vector_enter() does the following: 103 * 104 * set waiters bit 105 * membar #StoreLoad (via membar_enter()) 106 * check CPU_THREAD for each CPU; abort if owner running 107 * membar #LoadLoad (via membar_consumer()) 108 * check owner and waiters bit; abort if either changed 109 * block 110 * 111 * Thus the global memory orderings for (2) and (3) are as follows: 112 * 113 * (2M) mutex_exit() memory order: 114 * 115 * STORE CPU_THREAD = owner 116 * LOAD waiters bit 117 * STORE owner = NULL 118 * STORE CPU_THREAD = (possibly) someone else 119 * 120 * (3M) mutex_vector_enter() memory order: 121 * 122 * STORE waiters bit = 1 123 * LOAD CPU_THREAD for each CPU 124 * LOAD owner and waiters bit 125 * 126 * It has been verified by exhaustive simulation that all possible global 127 * memory orderings of (2M) interleaved with (3M) result in correct 128 * behavior. Moreover, these ordering constraints are minimal: changing 129 * the ordering of anything in (2M) or (3M) breaks the algorithm, creating 130 * windows for missed wakeups. Note: the possibility that other threads 131 * may grab the lock after the owner drops it can be factored out of the 132 * memory ordering analysis because mutex_vector_enter() won't block 133 * if the lock isn't still owned by the same thread. 134 * 135 * The only requirements of code outside the mutex implementation are 136 * (1) mutex_exit() preemption fixup in interrupt handlers or trap return, 137 * and (2) a membar #StoreLoad after setting CPU_THREAD in resume(). 138 * Note: idle threads cannot grab adaptive locks (since they cannot block), 139 * so the membar may be safely omitted when resuming an idle thread. 140 * 141 * When a mutex has waiters, mutex_vector_exit() has several options: 142 * 143 * (1) Choose a waiter and make that thread the owner before waking it; 144 * this is known as "direct handoff" of ownership. 145 * 146 * (2) Drop the lock and wake one waiter. 147 * 148 * (3) Drop the lock, clear the waiters bit, and wake all waiters. 149 * 150 * In many ways (1) is the cleanest solution, but if a lock is moderately 151 * contended it defeats the adaptive spin logic. If we make some other 152 * thread the owner, but he's not ONPROC yet, then all other threads on 153 * other cpus that try to get the lock will conclude that the owner is 154 * blocked, so they'll block too. And so on -- it escalates quickly, 155 * with every thread taking the blocking path rather than the spin path. 156 * Thus, direct handoff is *not* a good idea for adaptive mutexes. 157 * 158 * Option (2) is the next most natural-seeming option, but it has several 159 * annoying properties. If there's more than one waiter, we must preserve 160 * the waiters bit on an unheld lock. On cas-capable platforms, where 161 * the waiters bit is part of the lock word, this means that both 0x0 162 * and 0x1 represent unheld locks, so we have to cas against *both*. 163 * Priority inheritance also gets more complicated, because a lock can 164 * have waiters but no owner to whom priority can be willed. So while 165 * it is possible to make option (2) work, it's surprisingly vile. 166 * 167 * Option (3), the least-intuitive at first glance, is what we actually do. 168 * It has the advantage that because you always wake all waiters, you 169 * never have to preserve the waiters bit. Waking all waiters seems like 170 * begging for a thundering herd problem, but consider: under option (2), 171 * every thread that grabs and drops the lock will wake one waiter -- so 172 * if the lock is fairly active, all waiters will be awakened very quickly 173 * anyway. Moreover, this is how adaptive locks are *supposed* to work. 174 * The blocking case is rare; the more common case (by 3-4 orders of 175 * magnitude) is that one or more threads spin waiting to get the lock. 176 * Only direct handoff can prevent the thundering herd problem, but as 177 * mentioned earlier, that would tend to defeat the adaptive spin logic. 178 * In practice, option (3) works well because the blocking case is rare. 179 */ 180 181 /* 182 * delayed lock retry with exponential delay for spin locks 183 * 184 * It is noted above that for both the spin locks and the adaptive locks, 185 * spinning is the dominate mode of operation. So long as there is only 186 * one thread waiting on a lock, the naive spin loop works very well in 187 * cache based architectures. The lock data structure is pulled into the 188 * cache of the processor with the waiting/spinning thread and no further 189 * memory traffic is generated until the lock is released. Unfortunately, 190 * once two or more threads are waiting on a lock, the naive spin has 191 * the property of generating maximum memory traffic from each spinning 192 * thread as the spinning threads contend for the lock data structure. 193 * 194 * By executing a delay loop before retrying a lock, a waiting thread 195 * can reduce its memory traffic by a large factor, depending on the 196 * size of the delay loop. A large delay loop greatly reduced the memory 197 * traffic, but has the drawback of having a period of time when 198 * no thread is attempting to gain the lock even though several threads 199 * might be waiting. A small delay loop has the drawback of not 200 * much reduction in memory traffic, but reduces the potential idle time. 201 * The theory of the exponential delay code is to start with a short 202 * delay loop and double the waiting time on each iteration, up to 203 * a preselected maximum. The BACKOFF_BASE provides the equivalent 204 * of 2 to 3 memory references delay for US-III+ and US-IV architectures. 205 * The BACKOFF_CAP is the equivalent of 50 to 100 memory references of 206 * time (less than 12 microseconds for a 1000 MHz system). 207 * 208 * To determine appropriate BACKOFF_BASE and BACKOFF_CAP values, 209 * studies on US-III+ and US-IV systems using 1 to 66 threads were 210 * done. A range of possible values were studied. 211 * Performance differences below 10 threads were not large. For 212 * systems with more threads, substantial increases in total lock 213 * throughput was observed with the given values. For cases where 214 * more than 20 threads were waiting on the same lock, lock throughput 215 * increased by a factor of 5 or more using the backoff algorithm. 216 */ 217 218 #include <sys/param.h> 219 #include <sys/time.h> 220 #include <sys/cpuvar.h> 221 #include <sys/thread.h> 222 #include <sys/debug.h> 223 #include <sys/cmn_err.h> 224 #include <sys/sobject.h> 225 #include <sys/turnstile.h> 226 #include <sys/systm.h> 227 #include <sys/mutex_impl.h> 228 #include <sys/spl.h> 229 #include <sys/lockstat.h> 230 #include <sys/atomic.h> 231 #include <sys/cpu.h> 232 #include <sys/stack.h> 233 234 #define BACKOFF_BASE 50 235 #define BACKOFF_CAP 1600 236 237 /* 238 * The sobj_ops vector exports a set of functions needed when a thread 239 * is asleep on a synchronization object of this type. 240 */ 241 static sobj_ops_t mutex_sobj_ops = { 242 SOBJ_MUTEX, mutex_owner, turnstile_stay_asleep, turnstile_change_pri 243 }; 244 245 /* 246 * If the system panics on a mutex, save the address of the offending 247 * mutex in panic_mutex_addr, and save the contents in panic_mutex. 248 */ 249 static mutex_impl_t panic_mutex; 250 static mutex_impl_t *panic_mutex_addr; 251 252 static void 253 mutex_panic(char *msg, mutex_impl_t *lp) 254 { 255 if (panicstr) 256 return; 257 258 if (casptr(&panic_mutex_addr, NULL, lp) == NULL) 259 panic_mutex = *lp; 260 261 panic("%s, lp=%p owner=%p thread=%p", 262 msg, lp, MUTEX_OWNER(&panic_mutex), curthread); 263 } 264 265 /* 266 * mutex_vector_enter() is called from the assembly mutex_enter() routine 267 * if the lock is held or is not of type MUTEX_ADAPTIVE. 268 */ 269 void 270 mutex_vector_enter(mutex_impl_t *lp) 271 { 272 kthread_id_t owner; 273 hrtime_t sleep_time = 0; /* how long we slept */ 274 uint_t spin_count = 0; /* how many times we spun */ 275 cpu_t *cpup, *last_cpu; 276 extern cpu_t *cpu_list; 277 turnstile_t *ts; 278 volatile mutex_impl_t *vlp = (volatile mutex_impl_t *)lp; 279 int backoff; /* current backoff */ 280 int backctr; /* ctr for backoff */ 281 282 ASSERT_STACK_ALIGNED(); 283 284 if (MUTEX_TYPE_SPIN(lp)) { 285 lock_set_spl(&lp->m_spin.m_spinlock, lp->m_spin.m_minspl, 286 &lp->m_spin.m_oldspl); 287 return; 288 } 289 290 if (!MUTEX_TYPE_ADAPTIVE(lp)) { 291 mutex_panic("mutex_enter: bad mutex", lp); 292 return; 293 } 294 295 /* 296 * Adaptive mutexes must not be acquired from above LOCK_LEVEL. 297 * We can migrate after loading CPU but before checking CPU_ON_INTR, 298 * so we must verify by disabling preemption and loading CPU again. 299 */ 300 cpup = CPU; 301 if (CPU_ON_INTR(cpup) && !panicstr) { 302 kpreempt_disable(); 303 if (CPU_ON_INTR(CPU)) 304 mutex_panic("mutex_enter: adaptive at high PIL", lp); 305 kpreempt_enable(); 306 } 307 308 CPU_STATS_ADDQ(cpup, sys, mutex_adenters, 1); 309 310 backoff = BACKOFF_BASE; 311 312 for (;;) { 313 spin: 314 spin_count++; 315 /* 316 * Add an exponential backoff delay before trying again 317 * to touch the mutex data structure. 318 * the spin_count test and call to nulldev are to prevent 319 * the compiler optimizer from eliminating the delay loop. 320 */ 321 for (backctr = backoff; backctr; backctr--) { 322 if (!spin_count) (void) nulldev(); 323 }; /* delay */ 324 backoff = backoff << 1; /* double it */ 325 if (backoff > BACKOFF_CAP) { 326 backoff = BACKOFF_CAP; 327 } 328 329 SMT_PAUSE(); 330 331 if (panicstr) 332 return; 333 334 if ((owner = MUTEX_OWNER(vlp)) == NULL) { 335 if (mutex_adaptive_tryenter(lp)) 336 break; 337 continue; 338 } 339 340 if (owner == curthread) 341 mutex_panic("recursive mutex_enter", lp); 342 343 /* 344 * If lock is held but owner is not yet set, spin. 345 * (Only relevant for platforms that don't have cas.) 346 */ 347 if (owner == MUTEX_NO_OWNER) 348 continue; 349 350 /* 351 * When searching the other CPUs, start with the one where 352 * we last saw the owner thread. If owner is running, spin. 353 * 354 * We must disable preemption at this point to guarantee 355 * that the list doesn't change while we traverse it 356 * without the cpu_lock mutex. While preemption is 357 * disabled, we must revalidate our cached cpu pointer. 358 */ 359 kpreempt_disable(); 360 if (cpup->cpu_next == NULL) 361 cpup = cpu_list; 362 last_cpu = cpup; /* mark end of search */ 363 do { 364 if (cpup->cpu_thread == owner) { 365 kpreempt_enable(); 366 goto spin; 367 } 368 } while ((cpup = cpup->cpu_next) != last_cpu); 369 kpreempt_enable(); 370 371 /* 372 * The owner appears not to be running, so block. 373 * See the Big Theory Statement for memory ordering issues. 374 */ 375 ts = turnstile_lookup(lp); 376 MUTEX_SET_WAITERS(lp); 377 membar_enter(); 378 379 /* 380 * Recheck whether owner is running after waiters bit hits 381 * global visibility (above). If owner is running, spin. 382 * 383 * Since we are at ipl DISP_LEVEL, kernel preemption is 384 * disabled, however we still need to revalidate our cached 385 * cpu pointer to make sure the cpu hasn't been deleted. 386 */ 387 if (cpup->cpu_next == NULL) 388 last_cpu = cpup = cpu_list; 389 do { 390 if (cpup->cpu_thread == owner) { 391 turnstile_exit(lp); 392 goto spin; 393 } 394 } while ((cpup = cpup->cpu_next) != last_cpu); 395 membar_consumer(); 396 397 /* 398 * If owner and waiters bit are unchanged, block. 399 */ 400 if (MUTEX_OWNER(vlp) == owner && MUTEX_HAS_WAITERS(vlp)) { 401 sleep_time -= gethrtime(); 402 (void) turnstile_block(ts, TS_WRITER_Q, lp, 403 &mutex_sobj_ops, NULL, NULL); 404 sleep_time += gethrtime(); 405 } else { 406 turnstile_exit(lp); 407 } 408 } 409 410 ASSERT(MUTEX_OWNER(lp) == curthread); 411 412 if (sleep_time == 0) { 413 LOCKSTAT_RECORD(LS_MUTEX_ENTER_SPIN, lp, spin_count); 414 } else { 415 LOCKSTAT_RECORD(LS_MUTEX_ENTER_BLOCK, lp, sleep_time); 416 } 417 418 LOCKSTAT_RECORD0(LS_MUTEX_ENTER_ACQUIRE, lp); 419 } 420 421 /* 422 * mutex_vector_tryenter() is called from the assembly mutex_tryenter() 423 * routine if the lock is held or is not of type MUTEX_ADAPTIVE. 424 */ 425 int 426 mutex_vector_tryenter(mutex_impl_t *lp) 427 { 428 int s; 429 430 if (MUTEX_TYPE_ADAPTIVE(lp)) 431 return (0); /* we already tried in assembly */ 432 433 if (!MUTEX_TYPE_SPIN(lp)) { 434 mutex_panic("mutex_tryenter: bad mutex", lp); 435 return (0); 436 } 437 438 s = splr(lp->m_spin.m_minspl); 439 if (lock_try(&lp->m_spin.m_spinlock)) { 440 lp->m_spin.m_oldspl = (ushort_t)s; 441 return (1); 442 } 443 splx(s); 444 return (0); 445 } 446 447 /* 448 * mutex_vector_exit() is called from mutex_exit() if the lock is not 449 * adaptive, has waiters, or is not owned by the current thread (panic). 450 */ 451 void 452 mutex_vector_exit(mutex_impl_t *lp) 453 { 454 turnstile_t *ts; 455 456 if (MUTEX_TYPE_SPIN(lp)) { 457 lock_clear_splx(&lp->m_spin.m_spinlock, lp->m_spin.m_oldspl); 458 return; 459 } 460 461 if (MUTEX_OWNER(lp) != curthread) { 462 mutex_panic("mutex_exit: not owner", lp); 463 return; 464 } 465 466 ts = turnstile_lookup(lp); 467 MUTEX_CLEAR_LOCK_AND_WAITERS(lp); 468 if (ts == NULL) 469 turnstile_exit(lp); 470 else 471 turnstile_wakeup(ts, TS_WRITER_Q, ts->ts_waiters, NULL); 472 LOCKSTAT_RECORD0(LS_MUTEX_EXIT_RELEASE, lp); 473 } 474 475 int 476 mutex_owned(kmutex_t *mp) 477 { 478 mutex_impl_t *lp = (mutex_impl_t *)mp; 479 480 if (panicstr) 481 return (1); 482 483 if (MUTEX_TYPE_ADAPTIVE(lp)) 484 return (MUTEX_OWNER(lp) == curthread); 485 return (LOCK_HELD(&lp->m_spin.m_spinlock)); 486 } 487 488 kthread_t * 489 mutex_owner(kmutex_t *mp) 490 { 491 mutex_impl_t *lp = (mutex_impl_t *)mp; 492 kthread_id_t t; 493 494 if (MUTEX_TYPE_ADAPTIVE(lp) && (t = MUTEX_OWNER(lp)) != MUTEX_NO_OWNER) 495 return (t); 496 return (NULL); 497 } 498 499 /* 500 * The iblock cookie 'ibc' is the spl level associated with the lock; 501 * this alone determines whether the lock will be ADAPTIVE or SPIN. 502 * 503 * Adaptive mutexes created in zeroed memory do not need to call 504 * mutex_init() as their allocation in this fashion guarantees 505 * their initialization. 506 * eg adaptive mutexes created as static within the BSS or allocated 507 * by kmem_zalloc(). 508 */ 509 /* ARGSUSED */ 510 void 511 mutex_init(kmutex_t *mp, char *name, kmutex_type_t type, void *ibc) 512 { 513 mutex_impl_t *lp = (mutex_impl_t *)mp; 514 515 ASSERT(ibc < (void *)KERNELBASE); /* see 1215173 */ 516 517 if ((intptr_t)ibc > ipltospl(LOCK_LEVEL) && ibc < (void *)KERNELBASE) { 518 ASSERT(type != MUTEX_ADAPTIVE && type != MUTEX_DEFAULT); 519 MUTEX_SET_TYPE(lp, MUTEX_SPIN); 520 LOCK_INIT_CLEAR(&lp->m_spin.m_spinlock); 521 LOCK_INIT_HELD(&lp->m_spin.m_dummylock); 522 lp->m_spin.m_minspl = (int)(intptr_t)ibc; 523 } else { 524 ASSERT(type != MUTEX_SPIN); 525 MUTEX_SET_TYPE(lp, MUTEX_ADAPTIVE); 526 MUTEX_CLEAR_LOCK_AND_WAITERS(lp); 527 } 528 } 529 530 void 531 mutex_destroy(kmutex_t *mp) 532 { 533 mutex_impl_t *lp = (mutex_impl_t *)mp; 534 535 if (lp->m_owner == 0 && !MUTEX_HAS_WAITERS(lp)) { 536 MUTEX_DESTROY(lp); 537 } else if (MUTEX_TYPE_SPIN(lp)) { 538 LOCKSTAT_RECORD0(LS_MUTEX_DESTROY_RELEASE, lp); 539 MUTEX_DESTROY(lp); 540 } else if (MUTEX_TYPE_ADAPTIVE(lp)) { 541 LOCKSTAT_RECORD0(LS_MUTEX_DESTROY_RELEASE, lp); 542 if (MUTEX_OWNER(lp) != curthread) 543 mutex_panic("mutex_destroy: not owner", lp); 544 if (MUTEX_HAS_WAITERS(lp)) { 545 turnstile_t *ts = turnstile_lookup(lp); 546 turnstile_exit(lp); 547 if (ts != NULL) 548 mutex_panic("mutex_destroy: has waiters", lp); 549 } 550 MUTEX_DESTROY(lp); 551 } else { 552 mutex_panic("mutex_destroy: bad mutex", lp); 553 } 554 } 555 556 /* 557 * Simple C support for the cases where spin locks miss on the first try. 558 */ 559 void 560 lock_set_spin(lock_t *lp) 561 { 562 int spin_count = 1; 563 int backoff; /* current backoff */ 564 int backctr; /* ctr for backoff */ 565 566 if (panicstr) 567 return; 568 569 if (ncpus == 1) 570 panic("lock_set: %p lock held and only one CPU", lp); 571 572 backoff = BACKOFF_BASE; 573 while (LOCK_HELD(lp) || !lock_spin_try(lp)) { 574 if (panicstr) 575 return; 576 spin_count++; 577 /* 578 * Add an exponential backoff delay before trying again 579 * to touch the mutex data structure. 580 * the spin_count test and call to nulldev are to prevent 581 * the compiler optimizer from eliminating the delay loop. 582 */ 583 for (backctr = backoff; backctr; backctr--) { /* delay */ 584 if (!spin_count) (void) nulldev(); 585 } 586 587 backoff = backoff << 1; /* double it */ 588 if (backoff > BACKOFF_CAP) { 589 backoff = BACKOFF_CAP; 590 } 591 SMT_PAUSE(); 592 } 593 594 if (spin_count) { 595 LOCKSTAT_RECORD(LS_LOCK_SET_SPIN, lp, spin_count); 596 } 597 598 LOCKSTAT_RECORD0(LS_LOCK_SET_ACQUIRE, lp); 599 } 600 601 void 602 lock_set_spl_spin(lock_t *lp, int new_pil, ushort_t *old_pil_addr, int old_pil) 603 { 604 int spin_count = 1; 605 int backoff; /* current backoff */ 606 int backctr; /* ctr for backoff */ 607 608 if (panicstr) 609 return; 610 611 if (ncpus == 1) 612 panic("lock_set_spl: %p lock held and only one CPU", lp); 613 614 ASSERT(new_pil > LOCK_LEVEL); 615 616 backoff = BACKOFF_BASE; 617 do { 618 splx(old_pil); 619 while (LOCK_HELD(lp)) { 620 if (panicstr) { 621 *old_pil_addr = (ushort_t)splr(new_pil); 622 return; 623 } 624 spin_count++; 625 /* 626 * Add an exponential backoff delay before trying again 627 * to touch the mutex data structure. 628 * spin_count test and call to nulldev are to prevent 629 * compiler optimizer from eliminating the delay loop. 630 */ 631 for (backctr = backoff; backctr; backctr--) { 632 if (!spin_count) (void) nulldev(); 633 } 634 backoff = backoff << 1; /* double it */ 635 if (backoff > BACKOFF_CAP) { 636 backoff = BACKOFF_CAP; 637 } 638 639 SMT_PAUSE(); 640 } 641 old_pil = splr(new_pil); 642 } while (!lock_spin_try(lp)); 643 644 *old_pil_addr = (ushort_t)old_pil; 645 646 if (spin_count) { 647 LOCKSTAT_RECORD(LS_LOCK_SET_SPL_SPIN, lp, spin_count); 648 } 649 650 LOCKSTAT_RECORD(LS_LOCK_SET_SPL_ACQUIRE, lp, spin_count); 651 } 652