Author: attilio
Date: Tue May 11 18:24:22 2010
New Revision: 207929
URL: http://svn.freebsd.org/changeset/base/207929

Log:
  Right now, WITNESS just blindly pipes all the output to the
  (TOCONS | TOLOG) mask even when called from DDB points.
  That breaks several output, where the most notable is textdump output.
  Fix this by having configurable callbacks passed to witness_list_locks()
  and witness_display_spinlock() for printing out datas.
  
  Reported by:  several broken textdump outputs
  Tested by:    Giovanni Trematerra
                <giovanni dot trematerra at gmail dot com>
  MFC after:    7 days
  X-MFC:                r207922

Modified:
  head/sys/kern/kern_mutex.c
  head/sys/kern/subr_pcpu.c
  head/sys/kern/subr_witness.c
  head/sys/sys/lock.h

Modified: head/sys/kern/kern_mutex.c
==============================================================================
--- head/sys/kern/kern_mutex.c  Tue May 11 18:09:24 2010        (r207928)
+++ head/sys/kern/kern_mutex.c  Tue May 11 18:24:22 2010        (r207929)
@@ -485,7 +485,7 @@ _mtx_lock_spin_failed(struct mtx *m)
        printf( "spin lock %p (%s) held by %p (tid %d) too long\n",
            m, m->lock_object.lo_name, td, td->td_tid);
 #ifdef WITNESS
-       witness_display_spinlock(&m->lock_object, td);
+       witness_display_spinlock(&m->lock_object, td, printf);
 #endif
        panic("spin lock held too long");
 }

Modified: head/sys/kern/subr_pcpu.c
==============================================================================
--- head/sys/kern/subr_pcpu.c   Tue May 11 18:09:24 2010        (r207928)
+++ head/sys/kern/subr_pcpu.c   Tue May 11 18:24:22 2010        (r207929)
@@ -363,7 +363,7 @@ show_pcpu(struct pcpu *pc)
 
 #ifdef WITNESS
        db_printf("spin locks held:\n");
-       witness_list_locks(&pc->pc_spinlocks);
+       witness_list_locks(&pc->pc_spinlocks, db_printf);
 #endif
 }
 

Modified: head/sys/kern/subr_witness.c
==============================================================================
--- head/sys/kern/subr_witness.c        Tue May 11 18:09:24 2010        
(r207928)
+++ head/sys/kern/subr_witness.c        Tue May 11 18:24:22 2010        
(r207929)
@@ -367,7 +367,8 @@ static int  witness_lock_order_check(stru
 static struct witness_lock_order_data  *witness_lock_order_get(
                                            struct witness *parent,
                                            struct witness *child);
-static void    witness_list_lock(struct lock_instance *instance);
+static void    witness_list_lock(struct lock_instance *instance,
+                   int (*prnt)(const char *fmt, ...));
 static void    witness_setflag(struct lock_object *lock, int flag, int set);
 
 #ifdef KDB
@@ -1597,7 +1598,7 @@ witness_thread_exit(struct thread *td)
                printf("Thread %p exiting with the following locks held:\n",
                                            td);
                                n++;
-                               witness_list_lock(&lle->ll_children[i]);
+                               witness_list_lock(&lle->ll_children[i], printf);
                                
                        }
                panic("Thread %p cannot exit while holding sleeplocks\n", td);
@@ -1646,7 +1647,7 @@ witness_warn(int flags, struct lock_obje
                                printf(" locks held:\n");
                        }
                        n++;
-                       witness_list_lock(lock1);
+                       witness_list_lock(lock1, printf);
                }
 
        /*
@@ -1677,7 +1678,7 @@ witness_warn(int flags, struct lock_obje
                if (flags & WARN_SLEEPOK)
                        printf(" non-sleepable");
                printf(" locks held:\n");
-               n += witness_list_locks(&lock_list);
+               n += witness_list_locks(&lock_list, printf);
        } else
                sched_unpin();
        if (flags & WARN_PANIC && n)
@@ -2063,16 +2064,17 @@ find_instance(struct lock_list_entry *li
 }
 
 static void
-witness_list_lock(struct lock_instance *instance)
+witness_list_lock(struct lock_instance *instance,
+    int (*prnt)(const char *fmt, ...))
 {
        struct lock_object *lock;
 
        lock = instance->li_lock;
-       printf("%s %s %s", (instance->li_flags & LI_EXCLUSIVE) != 0 ?
+       prnt("%s %s %s", (instance->li_flags & LI_EXCLUSIVE) != 0 ?
            "exclusive" : "shared", LOCK_CLASS(lock)->lc_name, lock->lo_name);
        if (lock->lo_witness->w_name != lock->lo_name)
-               printf(" (%s)", lock->lo_witness->w_name);
-       printf(" r = %d (%p) locked @ %s:%d\n",
+               prnt(" (%s)", lock->lo_witness->w_name);
+       prnt(" r = %d (%p) locked @ %s:%d\n",
            instance->li_flags & LI_RECURSEMASK, lock, instance->li_file,
            instance->li_line);
 }
@@ -2101,7 +2103,8 @@ witness_proc_has_locks(struct proc *p)
 #endif
 
 int
-witness_list_locks(struct lock_list_entry **lock_list)
+witness_list_locks(struct lock_list_entry **lock_list,
+    int (*prnt)(const char *fmt, ...))
 {
        struct lock_list_entry *lle;
        int i, nheld;
@@ -2109,7 +2112,7 @@ witness_list_locks(struct lock_list_entr
        nheld = 0;
        for (lle = *lock_list; lle != NULL; lle = lle->ll_next)
                for (i = lle->ll_count - 1; i >= 0; i--) {
-                       witness_list_lock(&lle->ll_children[i]);
+                       witness_list_lock(&lle->ll_children[i], prnt);
                        nheld++;
                }
        return (nheld);
@@ -2123,7 +2126,8 @@ witness_list_locks(struct lock_list_entr
  * see when it was last acquired.
  */
 void
-witness_display_spinlock(struct lock_object *lock, struct thread *owner)
+witness_display_spinlock(struct lock_object *lock, struct thread *owner,
+    int (*prnt)(const char *fmt, ...))
 {
        struct lock_instance *instance;
        struct pcpu *pc;
@@ -2133,7 +2137,7 @@ witness_display_spinlock(struct lock_obj
        pc = pcpu_find(owner->td_oncpu);
        instance = find_instance(pc->pc_spinlocks, lock);
        if (instance != NULL)
-               witness_list_lock(instance);
+               witness_list_lock(instance, prnt);
 }
 
 void
@@ -2306,7 +2310,7 @@ witness_ddb_list(struct thread *td)
        if (witness_watch < 1)
                return;
 
-       witness_list_locks(&td->td_sleeplocks);
+       witness_list_locks(&td->td_sleeplocks, db_printf);
 
        /*
         * We only handle spinlocks if td == curthread.  This is somewhat broken
@@ -2322,7 +2326,7 @@ witness_ddb_list(struct thread *td)
         * handle threads on other CPU's for now.
         */
        if (td == curthread && PCPU_GET(spinlocks) != NULL)
-               witness_list_locks(PCPU_PTR(spinlocks));
+               witness_list_locks(PCPU_PTR(spinlocks), db_printf);
 }
 
 DB_SHOW_COMMAND(locks, db_witness_list)

Modified: head/sys/sys/lock.h
==============================================================================
--- head/sys/sys/lock.h Tue May 11 18:09:24 2010        (r207928)
+++ head/sys/sys/lock.h Tue May 11 18:24:22 2010        (r207929)
@@ -212,10 +212,12 @@ void      witness_downgrade(struct lock_objec
 void   witness_unlock(struct lock_object *, int, const char *, int);
 void   witness_save(struct lock_object *, const char **, int *);
 void   witness_restore(struct lock_object *, const char *, int);
-int    witness_list_locks(struct lock_list_entry **);
+int    witness_list_locks(struct lock_list_entry **,
+           int (*)(const char *, ...));
 int    witness_warn(int, struct lock_object *, const char *, ...);
 void   witness_assert(struct lock_object *, int, const char *, int);
-void   witness_display_spinlock(struct lock_object *, struct thread *);
+void   witness_display_spinlock(struct lock_object *, struct thread *,
+           int (*)(const char *, ...));
 int    witness_line(struct lock_object *);
 void   witness_norelease(struct lock_object *);
 void   witness_releaseok(struct lock_object *);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to