Deleted Added
sdiff udiff text old ( 67548 ) new ( 67676 )
full compact
1/*-
2 * Copyright (c) 1998 Berkeley Software Design, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 13 unchanged lines hidden (view full) ---

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * from BSDI $Id: mutex_witness.c,v 1.1.2.20 2000/04/27 03:10:27 cp Exp $
29 * and BSDI $Id: synch_machdep.c,v 2.3.2.39 2000/04/27 03:10:25 cp Exp $
30 * $FreeBSD: head/sys/kern/subr_witness.c 67676 2000-10-27 02:59:30Z jhb $
31 */
32
33/*
34 * Main Entry: witness
35 * Pronunciation: 'wit-n&s
36 * Function: noun
37 * Etymology: Middle English witnesse, from Old English witnes knowledge,
38 * testimony, witness, from 2wit

--- 6 unchanged lines hidden (view full) ---

45 * 4 : one who has personal knowledge of something
46 * 5 a : something serving as evidence or proof : SIGN
47 * b : public affirmation by word or example of usually
48 * religious faith or conviction <the heroic witness to divine
49 * life -- Pilot>
50 * 6 capitalized : a member of the Jehovah's Witnesses
51 */
52
53#include "opt_witness.h"
54
55#include <sys/param.h>
56#include <sys/bus.h>
57#include <sys/kernel.h>
58#include <sys/malloc.h>
59#include <sys/proc.h>
60#include <sys/sysctl.h>
61#include <sys/systm.h>
62#include <sys/vmmeter.h>
63#include <sys/ktr.h>
64
65#include <machine/atomic.h>
66#include <machine/bus.h>
67#include <machine/clock.h>
68#include <machine/cpu.h>

--- 609 unchanged lines hidden (view full) ---

678 struct witness *w_children[WITNESS_NCHILDREN];
679};
680
681struct witness_blessed {
682 char *b_lock1;
683 char *b_lock2;
684};
685
686#ifdef DDB
687/*
688 * When DDB is enabled and witness_ddb is set to 1, it will cause the system to
689 * drop into kdebug() when:
690 * - a lock heirarchy violation occurs
691 * - locks are held when going to sleep.
692 */
693#ifdef WITNESS_DDB
694int witness_ddb = 1;
695#else
696int witness_ddb = 0;
697#endif
698SYSCTL_INT(_debug, OID_AUTO, witness_ddb, CTLFLAG_RW, &witness_ddb, 0, "");
699#endif /* DDB */
700
701#ifdef WITNESS_SKIPSPIN
702int witness_skipspin = 1;
703#else
704int witness_skipspin = 0;
705#endif
706SYSCTL_INT(_debug, OID_AUTO, witness_skipspin, CTLFLAG_RD, &witness_skipspin, 0,
707 "");
708
709MUTEX_DECLARE(static,w_mtx);
710static struct witness *w_free;
711static struct witness *w_all;
712static int w_inited;
713static int witness_dead; /* fatal error, probably no memory */
714
715static struct witness w_data[WITNESS_COUNT];
716
717static struct witness *enroll __P((const char *description, int flag));

--- 8 unchanged lines hidden (view full) ---

726static void witness_leveldescendents __P((struct witness *parent, int level));
727static void witness_levelall __P((void));
728static struct witness * witness_get __P((void));
729static void witness_free __P((struct witness *m));
730
731
732static char *ignore_list[] = {
733 "witness lock",
734 NULL
735};
736
737static char *spin_order_list[] = {
738 "sched lock",
739 "clk",
740 "sio",
741 /*
742 * leaf locks
743 */
744 NULL
745};
746
747static char *order_list[] = {
748 NULL
749};
750
751static char *dup_list[] = {
752 NULL
753};
754
755static char *sleep_list[] = {
756 "Giant lock",
757 NULL
758};
759

--- 30 unchanged lines hidden (view full) ---

790
791void
792witness_enter(struct mtx *m, int flags, const char *file, int line)
793{
794 struct witness *w, *w1;
795 struct mtx *m1;
796 struct proc *p;
797 int i;
798#ifdef DDB
799 int go_into_ddb = 0;
800#endif /* DDB */
801
802 w = m->mtx_witness;
803 p = CURPROC;
804
805 if (flags & MTX_SPIN) {
806 if (!w->w_spin)
807 panic("mutex_enter: MTX_SPIN on MTX_DEF mutex %s @"
808 " %s:%d", m->mtx_description, file, line);

--- 35 unchanged lines hidden (view full) ---

844 if ((w1 = m1->mtx_witness) == w) {
845 if (w->w_same_squawked || dup_ok(w))
846 goto out;
847 w->w_same_squawked = 1;
848 printf("acquring duplicate lock of same type: \"%s\"\n",
849 m->mtx_description);
850 printf(" 1st @ %s:%d\n", w->w_file, w->w_line);
851 printf(" 2nd @ %s:%d\n", file, line);
852#ifdef DDB
853 go_into_ddb = 1;
854#endif /* DDB */
855 goto out;
856 }
857 MPASS(!mtx_owned(&w_mtx));
858 mtx_enter(&w_mtx, MTX_SPIN);
859 /*
860 * If we have a known higher number just say ok
861 */
862 if (witness_watch > 1 && w->w_level > w1->w_level) {

--- 25 unchanged lines hidden (view full) ---

888 }
889 printf("lock order reversal\n");
890 printf(" 1st %s last acquired @ %s:%d\n",
891 w->w_description, w->w_file, w->w_line);
892 printf(" 2nd %p %s @ %s:%d\n",
893 m1, w1->w_description, w1->w_file, w1->w_line);
894 printf(" 3rd %p %s @ %s:%d\n",
895 m, w->w_description, file, line);
896#ifdef DDB
897 go_into_ddb = 1;
898#endif /* DDB */
899 goto out;
900 }
901 }
902 m1 = LIST_FIRST(&p->p_heldmtx);
903 if (!itismychild(m1->mtx_witness, w))
904 mtx_exit(&w_mtx, MTX_SPIN);
905
906out:
907#ifdef DDB
908 if (witness_ddb && go_into_ddb)
909 Debugger("witness_enter");
910#endif /* DDB */
911 w->w_file = file;
912 w->w_line = line;
913 m->mtx_line = line;
914 m->mtx_file = file;
915
916 /*
917 * If this pays off it likely means that a mutex being witnessed
918 * is acquired in hardclock. Put it in the ignore list. It is

--- 117 unchanged lines hidden (view full) ---

1036 goto next;
1037 printf("%s:%d: %s with \"%s\" locked from %s:%d\n",
1038 file, line, check_only ? "could sleep" : "sleeping",
1039 m->mtx_description,
1040 m->mtx_witness->w_file, m->mtx_witness->w_line);
1041 n++;
1042 next:
1043 }
1044#ifdef DDB
1045 if (witness_ddb && n)
1046 Debugger("witness_sleep");
1047#endif /* DDB */
1048 return (n);
1049}
1050
1051static struct witness *
1052enroll(const char *description, int flag)
1053{
1054 int i;
1055 struct witness *w, *w1;
1056 char **ignore;
1057 char **order;
1058
1059 if (!witness_watch)
1060 return (NULL);
1061 for (ignore = ignore_list; *ignore != NULL; ignore++)
1062 if (strcmp(description, *ignore) == 0)
1063 return (NULL);
1064
1065 if (w_inited == 0) {
1066 mtx_init(&w_mtx, "witness lock", MTX_COLD | MTX_DEF);
1067 for (i = 0; i < WITNESS_COUNT; i++) {
1068 w = &w_data[i];
1069 witness_free(w);
1070 }
1071 w_inited = 1;
1072 for (order = order_list; *order != NULL; order++) {
1073 w = enroll(*order, MTX_DEF);
1074 w->w_file = "order list";

--- 287 unchanged lines hidden ---