[BACK]Return to subr_lockdebug.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/kern/subr_lockdebug.c between version 1.34 and 1.34.2.1

version 1.34, 2008/05/06 18:40:57 version 1.34.2.1, 2008/06/23 04:31:51
Line 48  __KERNEL_RCSID(0, "$NetBSD$");
Line 48  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/cpu.h>  #include <sys/cpu.h>
 #include <sys/atomic.h>  #include <sys/atomic.h>
 #include <sys/lock.h>  #include <sys/lock.h>
   #include <sys/rb.h>
 #include <lib/libkern/rb.h>  
   
 #include <machine/lock.h>  #include <machine/lock.h>
   
Line 291  lockdebug_alloc(volatile void *lock, loc
Line 290  lockdebug_alloc(volatile void *lock, loc
         ld->ld_unlocked = 0;          ld->ld_unlocked = 0;
         ld->ld_lwp = NULL;          ld->ld_lwp = NULL;
         ld->ld_initaddr = initaddr;          ld->ld_initaddr = initaddr;
         ld->ld_flags = lo->lo_sleeplock ? LD_SLEEPER : 0;          ld->ld_flags = (lo->lo_type == LOCKOPS_SLEEP ? LD_SLEEPER : 0);
         lockdebug_lock_cpus();          lockdebug_lock_cpus();
         rb_tree_insert_node(&ld_rb_tree, __UNVOLATILE(&ld->ld_rb_node));          rb_tree_insert_node(&ld_rb_tree, __UNVOLATILE(&ld->ld_rb_node));
         lockdebug_unlock_cpus();          lockdebug_unlock_cpus();
Line 320  lockdebug_free(volatile void *lock)
Line 319  lockdebug_free(volatile void *lock)
         ld = lockdebug_lookup(lock);          ld = lockdebug_lookup(lock);
         if (ld == NULL) {          if (ld == NULL) {
                 __cpu_simple_unlock(&ld_mod_lk);                  __cpu_simple_unlock(&ld_mod_lk);
                 panic("lockdebug_free: destroying uninitialized lock %p"                  panic("lockdebug_free: destroying uninitialized object %p"
                     "(ld_lock=%p)", lock, ld->ld_lock);                      "(ld_lock=%p)", lock, ld->ld_lock);
                 lockdebug_abort1(ld, s, __func__, "lock record follows", true);                  lockdebug_abort1(ld, s, __func__, "record follows", true);
                 return;                  return;
         }          }
         if ((ld->ld_flags & LD_LOCKED) != 0 || ld->ld_shares != 0) {          if ((ld->ld_flags & LD_LOCKED) != 0 || ld->ld_shares != 0) {
                 __cpu_simple_unlock(&ld_mod_lk);                  __cpu_simple_unlock(&ld_mod_lk);
                 lockdebug_abort1(ld, s, __func__, "is locked", true);                  lockdebug_abort1(ld, s, __func__, "is locked or in use", true);
                 return;                  return;
         }          }
         lockdebug_lock_cpus();          lockdebug_lock_cpus();
Line 354  lockdebug_more(int s)
Line 353  lockdebug_more(int s)
         void *block;          void *block;
         int i, base, m;          int i, base, m;
   
           /*
            * Can't call kmem_alloc() if in interrupt context.  XXX We could
            * deadlock, because we don't know which locks the caller holds.
            */
           if (cpu_intr_p() || (curlwp->l_pflag & LP_INTR) != 0) {
                   return s;
           }
   
         while (ld_nfree < LD_SLOP) {          while (ld_nfree < LD_SLOP) {
                 __cpu_simple_unlock(&ld_mod_lk);                  __cpu_simple_unlock(&ld_mod_lk);
                 splx(s);                  splx(s);
Line 454  lockdebug_wantlock(volatile void *lock, 
Line 461  lockdebug_wantlock(volatile void *lock, 
  *      Process a lock acquire operation.   *      Process a lock acquire operation.
  */   */
 void  void
 lockdebug_locked(volatile void *lock, uintptr_t where, int shared)  lockdebug_locked(volatile void *lock, void *cvlock, uintptr_t where,
                    int shared)
 {  {
         struct lwp *l = curlwp;          struct lwp *l = curlwp;
         lockdebug_t *ld;          lockdebug_t *ld;
Line 468  lockdebug_locked(volatile void *lock, ui
Line 476  lockdebug_locked(volatile void *lock, ui
                 splx(s);                  splx(s);
                 return;                  return;
         }          }
         if (shared) {          if (cvlock) {
                   KASSERT(ld->ld_lockops->lo_type == LOCKOPS_CV);
                   if (lock == (void *)&lbolt) {
                           /* nothing */
                   } else if (ld->ld_shares++ == 0) {
                           ld->ld_locked = (uintptr_t)cvlock;
                   } else if (cvlock != (void *)ld->ld_locked) {
                           lockdebug_abort1(ld, s, __func__, "multiple locks used"
                               " with condition variable", true);
                           return;
                   }
           } else if (shared) {
                 l->l_shlocks++;                  l->l_shlocks++;
                 ld->ld_shares++;                  ld->ld_shares++;
                 ld->ld_shwant--;                  ld->ld_shwant--;
Line 514  lockdebug_unlocked(volatile void *lock, 
Line 533  lockdebug_unlocked(volatile void *lock, 
                 splx(s);                  splx(s);
                 return;                  return;
         }          }
         if (shared) {          if (ld->ld_lockops->lo_type == LOCKOPS_CV) {
                   if (lock == (void *)&lbolt) {
                           /* nothing */
                   } else {
                           ld->ld_shares--;
                   }
           } else if (shared) {
                 if (l->l_shlocks == 0) {                  if (l->l_shlocks == 0) {
                         lockdebug_abort1(ld, s, __func__,                          lockdebug_abort1(ld, s, __func__,
                             "no shared locks held by LWP", true);                              "no shared locks held by LWP", true);
Line 565  lockdebug_unlocked(volatile void *lock, 
Line 590  lockdebug_unlocked(volatile void *lock, 
 }  }
   
 /*  /*
    * lockdebug_wakeup:
    *
    *      Process a wakeup on a condition variable.
    */
   void
   lockdebug_wakeup(volatile void *lock, uintptr_t where)
   {
           lockdebug_t *ld;
           int s;
   
           if (panicstr != NULL || ld_panic || lock == (void *)&lbolt)
                   return;
   
           s = splhigh();
           /* Find the CV... */
           if ((ld = lockdebug_lookup(lock)) == NULL) {
                   splx(s);
                   return;
           }
           /*
            * If it has any waiters, ensure that they are using the
            * same interlock.
            */
           if (ld->ld_shares != 0 && !mutex_owned((kmutex_t *)ld->ld_locked)) {
                   lockdebug_abort1(ld, s, __func__, "interlocking mutex not "
                       "held during wakeup", true);
                   return;
           }
           __cpu_simple_unlock(&ld->ld_spinlock);
           splx(s);
   }
   
   /*
  * lockdebug_barrier:   * lockdebug_barrier:
  *   *
  *      Panic if we hold more than one specified spin lock, and optionally,   *      Panic if we hold more than one specified spin lock, and optionally,
Line 659  lockdebug_dump(lockdebug_t *ld, void (*p
Line 717  lockdebug_dump(lockdebug_t *ld, void (*p
   
         (*pr)(          (*pr)(
             "lock address : %#018lx type     : %18s\n"              "lock address : %#018lx type     : %18s\n"
             "shared holds : %18u exclusive: %18u\n"              "initialized  : %#018lx",
             "shares wanted: %18u exclusive: %18u\n"  
             "current cpu  : %18u last held: %18u\n"  
             "current lwp  : %#018lx last held: %#018lx\n"  
             "last locked  : %#018lx unlocked : %#018lx\n"  
             "initialized  : %#018lx\n",  
             (long)ld->ld_lock, (sleeper ? "sleep/adaptive" : "spin"),              (long)ld->ld_lock, (sleeper ? "sleep/adaptive" : "spin"),
             (unsigned)ld->ld_shares, ((ld->ld_flags & LD_LOCKED) != 0),  
             (unsigned)ld->ld_shwant, (unsigned)ld->ld_exwant,  
             (unsigned)cpu_number(), (unsigned)ld->ld_cpu,  
             (long)curlwp, (long)ld->ld_lwp,  
             (long)ld->ld_locked, (long)ld->ld_unlocked,  
             (long)ld->ld_initaddr);              (long)ld->ld_initaddr);
   
           if (ld->ld_lockops->lo_type == LOCKOPS_CV) {
                   (*pr)(" interlock: %#018lx\n", ld->ld_locked);
           } else {
                   (*pr)("\n"
                       "shared holds : %18u exclusive: %18u\n"
                       "shares wanted: %18u exclusive: %18u\n"
                       "current cpu  : %18u last held: %18u\n"
                       "current lwp  : %#018lx last held: %#018lx\n"
                       "last locked  : %#018lx unlocked : %#018lx\n",
                       (unsigned)ld->ld_shares, ((ld->ld_flags & LD_LOCKED) != 0),
                       (unsigned)ld->ld_shwant, (unsigned)ld->ld_exwant,
                       (unsigned)cpu_number(), (unsigned)ld->ld_cpu,
                       (long)curlwp, (long)ld->ld_lwp,
                       (long)ld->ld_locked, (long)ld->ld_unlocked);
           }
   
         if (ld->ld_lockops->lo_dump != NULL)          if (ld->ld_lockops->lo_dump != NULL)
                 (*ld->ld_lockops->lo_dump)(ld->ld_lock);                  (*ld->ld_lockops->lo_dump)(ld->ld_lock);
   

Legend:
Removed from v.1.34  
changed lines
  Added in v.1.34.2.1

CVSweb <webmaster@jp.NetBSD.org>