From owner-svn-src-all@FreeBSD.ORG Tue May 11 18:24:22 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8F5F2106566B; Tue, 11 May 2010 18:24:22 +0000 (UTC) (envelope-from attilio@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7DC178FC08; Tue, 11 May 2010 18:24:22 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o4BIOM8c060022; Tue, 11 May 2010 18:24:22 GMT (envelope-from attilio@svn.freebsd.org) Received: (from attilio@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o4BIOMdP060017; Tue, 11 May 2010 18:24:22 GMT (envelope-from attilio@svn.freebsd.org) Message-Id: <201005111824.o4BIOMdP060017@svn.freebsd.org> From: Attilio Rao Date: Tue, 11 May 2010 18:24:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r207929 - in head/sys: kern sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 May 2010 18:24:22 -0000 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 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 *);