From owner-p4-projects Wed Mar 5 12:40:58 2003 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 5AD3337B405; Wed, 5 Mar 2003 12:40:53 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 03C0137B401 for ; Wed, 5 Mar 2003 12:40:53 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id D661343FCB for ; Wed, 5 Mar 2003 12:40:51 -0800 (PST) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h25Kep0U091912 for ; Wed, 5 Mar 2003 12:40:51 -0800 (PST) (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h25Kepb6091906 for perforce@freebsd.org; Wed, 5 Mar 2003 12:40:51 -0800 (PST) Date: Wed, 5 Mar 2003 12:40:51 -0800 (PST) Message-Id: <200303052040.h25Kepb6091906@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin Subject: PERFORCE change 26389 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG http://perforce.freebsd.org/chv.cgi?CH=26389 Change 26389 by jhb@jhb_laptop on 2003/03/05 12:40:27 Split itismychild() out into two separate functions and axe the silly static recursed variable. Also, handle one place where we ignored itismychild() failure and more cleanly handle the failure in witness_lock(). This is mostly a WIP in support of better handling witness's going away. Affected files ... .. //depot/projects/smpng/sys/kern/subr_witness.c#76 edit Differences ... ==== //depot/projects/smpng/sys/kern/subr_witness.c#76 (text+ko) ==== @@ -154,10 +154,12 @@ static struct witness *enroll(const char *description, struct lock_class *lock_class); +static int insertchild(struct witness *parent, struct witness *child); static int itismychild(struct witness *parent, struct witness *child); static void removechild(struct witness *parent, struct witness *child); static int isitmychild(struct witness *parent, struct witness *child); static int isitmydescendant(struct witness *parent, struct witness *child); +static int rebalancetree(void); #ifdef BLESSING static int blessed(struct witness *, struct witness *); #endif @@ -376,7 +378,8 @@ if (w1 == NULL) continue; w1->w_file = "order list"; - itismychild(w, w1); + if (!itismychild(w, w1)) + panic("Not enough memory for static orders!"); w = w1; } } @@ -785,15 +788,15 @@ * Giant if it is the wrong direction. The real lock order is that * sleepable locks come before Giant. */ - if (lock1->li_lock == &Giant.mtx_object && - (lock->lo_flags & LO_SLEEPABLE) != 0) - mtx_unlock_spin(&w_mtx); - else { + if (!(lock1->li_lock == &Giant.mtx_object && + (lock->lo_flags & LO_SLEEPABLE) != 0)) { CTR3(KTR_WITNESS, "%s: adding %s as a child of %s", __func__, lock->lo_type, lock1->li_lock->lo_type); if (!itismychild(lock1->li_lock->lo_witness, w)) - mtx_unlock_spin(&w_mtx); + /* Witness is dead. */ + return; } + mtx_unlock_spin(&w_mtx); out: #ifdef DDB @@ -1116,20 +1119,48 @@ return (w); } +/* + * Prune the whole tree. We look for cases where a lock is now + * both a descendant and a direct child of a given lock. In that + * case, we want to remove the direct child link from the tree. + * + * Returns false if insertchild() fails. + */ static int -itismychild(struct witness *parent, struct witness *child) +rebalancetree(void) +{ + struct witness *child, *parent; + struct witness_list *list; + + if (parent->w_class->lc_flags & LC_SLEEPLOCK) + list = &w_sleep; + else + list = &w_spin; + STAILQ_FOREACH(child, list, w_typelist) { + STAILQ_FOREACH(parent, list, w_typelist) { + if (!isitmychild(parent, child)) + continue; + removechild(parent, child); + if (isitmydescendant(parent, child)) + continue; + if (!insertchild(parent, child)) + return (0); + } + } + witness_levelall(); + return (1); +} + +/* + * Add "child" as a direct child of "parent". Returns false if + * we fail due to out of memory. + */ +static int +insertchild(struct witness *parent, struct witness *child) { - static int recursed; struct witness_child_list_entry **wcl; - struct witness_list *list; MPASS(child != NULL && parent != NULL); - if ((parent->w_class->lc_flags & (LC_SLEEPLOCK | LC_SPINLOCK)) != - (child->w_class->lc_flags & (LC_SLEEPLOCK | LC_SPINLOCK))) - panic( - "%s: parent (%s) and child (%s) are not the same lock type", - __func__, parent->w_class->lc_name, - child->w_class->lc_name); /* * Insert "child" after "parent" @@ -1140,35 +1171,29 @@ if (*wcl == NULL) { *wcl = witness_child_get(); if (*wcl == NULL) - return (1); + return (0); } (*wcl)->wcl_children[(*wcl)->wcl_count++] = child; - /* - * Now prune whole tree. We look for cases where a lock is now - * both a descendant and a direct child of a given lock. In that - * case, we want to remove the direct child link from the tree. - */ - if (recursed) + return (1); +} + +static int +itismychild(struct witness *parent, struct witness *child) +{ + + MPASS(child != NULL && parent != NULL); + if ((parent->w_class->lc_flags & (LC_SLEEPLOCK | LC_SPINLOCK)) != + (child->w_class->lc_flags & (LC_SLEEPLOCK | LC_SPINLOCK))) + panic( + "%s: parent (%s) and child (%s) are not the same lock type", + __func__, parent->w_class->lc_name, + child->w_class->lc_name); + + if (!insertchild(parent, child)) return (0); - recursed = 1; - if (parent->w_class->lc_flags & LC_SLEEPLOCK) - list = &w_sleep; - else - list = &w_spin; - STAILQ_FOREACH(child, list, w_typelist) { - STAILQ_FOREACH(parent, list, w_typelist) { - if (!isitmychild(parent, child)) - continue; - removechild(parent, child); - if (isitmydescendant(parent, child)) - continue; - itismychild(parent, child); - } - } - recursed = 0; - witness_levelall(); - return (0); + + return (rebalancetree()); } static void To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message