subr_witness.c (67548) | subr_witness.c (67676) |
---|---|
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 $ | 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 67548 2000-10-25 04:37:54Z jhb $ | 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 | 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 |
|
53#include <sys/param.h> 54#include <sys/bus.h> 55#include <sys/kernel.h> 56#include <sys/malloc.h> 57#include <sys/proc.h> | 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> |
|
58#include <sys/systm.h> 59#include <sys/vmmeter.h> 60#include <sys/ktr.h> 61 62#include <machine/atomic.h> 63#include <machine/bus.h> 64#include <machine/clock.h> 65#include <machine/cpu.h> --- 609 unchanged lines hidden (view full) --- 675 struct witness *w_children[WITNESS_NCHILDREN]; 676}; 677 678struct witness_blessed { 679 char *b_lock1; 680 char *b_lock2; 681}; 682 | 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 |
683#ifdef KDEBUG | 686#ifdef DDB |
684/* | 687/* |
685 * When WITNESS_KDEBUG is set to 1, it will cause the system to | 688 * When DDB is enabled and witness_ddb is set to 1, it will cause the system to |
686 * drop into kdebug() when: 687 * - a lock heirarchy violation occurs 688 * - locks are held when going to sleep. 689 */ | 689 * drop into kdebug() when: 690 * - a lock heirarchy violation occurs 691 * - locks are held when going to sleep. 692 */ |
690#ifndef WITNESS_KDEBUG 691#define WITNESS_KDEBUG 0 | 693#ifdef WITNESS_DDB 694int witness_ddb = 1; 695#else 696int witness_ddb = 0; |
692#endif | 697#endif |
693int witness_kdebug = WITNESS_KDEBUG; 694#endif /* KDEBUG */ | 698SYSCTL_INT(_debug, OID_AUTO, witness_ddb, CTLFLAG_RW, &witness_ddb, 0, ""); 699#endif /* DDB */ |
695 | 700 |
696#ifndef WITNESS_SKIPSPIN 697#define WITNESS_SKIPSPIN 0 | 701#ifdef WITNESS_SKIPSPIN 702int witness_skipspin = 1; 703#else 704int witness_skipspin = 0; |
698#endif | 705#endif |
699int witness_skipspin = WITNESS_SKIPSPIN; | 706SYSCTL_INT(_debug, OID_AUTO, witness_skipspin, CTLFLAG_RD, &witness_skipspin, 0, 707 ""); |
700 | 708 |
701 702static struct mtx w_mtx; | 709MUTEX_DECLARE(static,w_mtx); |
703static struct witness *w_free; 704static struct witness *w_all; 705static int w_inited; 706static int witness_dead; /* fatal error, probably no memory */ 707 708static struct witness w_data[WITNESS_COUNT]; 709 710static struct witness *enroll __P((const char *description, int flag)); --- 8 unchanged lines hidden (view full) --- 719static void witness_leveldescendents __P((struct witness *parent, int level)); 720static void witness_levelall __P((void)); 721static struct witness * witness_get __P((void)); 722static void witness_free __P((struct witness *m)); 723 724 725static char *ignore_list[] = { 726 "witness lock", | 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", |
727 "Kdebug", /* breaks rules and may or may not work */ 728 "Page Alias", /* sparc only, witness lock won't block intr */ | |
729 NULL 730}; 731 732static char *spin_order_list[] = { 733 "sched lock", | 734 NULL 735}; 736 737static char *spin_order_list[] = { 738 "sched lock", |
734 "log mtx", 735 "zslock", /* sparc only above log, this one is a real hack */ 736 "time lock", /* above callout */ 737 "callout mtx", /* above wayout */ | 739 "clk", 740 "sio", |
738 /* 739 * leaf locks 740 */ | 741 /* 742 * leaf locks 743 */ |
741 "wayout mtx", 742 "kernel_pmap", /* sparc only, logically equal "pmap" below */ 743 "pmap", /* sparc only */ | |
744 NULL 745}; 746 747static char *order_list[] = { | 744 NULL 745}; 746 747static char *order_list[] = { |
748 "tcb", "inp", "so_snd", "so_rcv", "Giant lock", NULL, 749 "udb", "inp", NULL, 750 "unp head", "unp", "so_snd", NULL, 751 "de0", "Giant lock", NULL, 752 "ifnet", "Giant lock", NULL, 753 "fifo", "so_snd", NULL, 754 "hme0", "Giant lock", NULL, 755 "esp0", "Giant lock", NULL, 756 "hfa0", "Giant lock", NULL, 757 "so_rcv", "atm_global", NULL, 758 "so_snd", "atm_global", NULL, 759 "NFS", "Giant lock", NULL, | |
760 NULL 761}; 762 763static char *dup_list[] = { | 748 NULL 749}; 750 751static char *dup_list[] = { |
764 "inp", 765 "process group", 766 "session", 767 "unp", 768 "rtentry", 769 "rawcb", | |
770 NULL 771}; 772 773static char *sleep_list[] = { 774 "Giant lock", 775 NULL 776}; 777 --- 30 unchanged lines hidden (view full) --- 808 809void 810witness_enter(struct mtx *m, int flags, const char *file, int line) 811{ 812 struct witness *w, *w1; 813 struct mtx *m1; 814 struct proc *p; 815 int i; | 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; |
816#ifdef KDEBUG 817 int go_into_kdebug = 0; 818#endif /* KDEBUG */ | 798#ifdef DDB 799 int go_into_ddb = 0; 800#endif /* DDB */ |
819 820 w = m->mtx_witness; 821 p = CURPROC; 822 823 if (flags & MTX_SPIN) { 824 if (!w->w_spin) 825 panic("mutex_enter: MTX_SPIN on MTX_DEF mutex %s @" 826 " %s:%d", m->mtx_description, file, line); --- 35 unchanged lines hidden (view full) --- 862 if ((w1 = m1->mtx_witness) == w) { 863 if (w->w_same_squawked || dup_ok(w)) 864 goto out; 865 w->w_same_squawked = 1; 866 printf("acquring duplicate lock of same type: \"%s\"\n", 867 m->mtx_description); 868 printf(" 1st @ %s:%d\n", w->w_file, w->w_line); 869 printf(" 2nd @ %s:%d\n", file, line); | 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); |
870#ifdef KDEBUG 871 go_into_kdebug = 1; 872#endif /* KDEBUG */ | 852#ifdef DDB 853 go_into_ddb = 1; 854#endif /* DDB */ |
873 goto out; 874 } 875 MPASS(!mtx_owned(&w_mtx)); 876 mtx_enter(&w_mtx, MTX_SPIN); 877 /* 878 * If we have a known higher number just say ok 879 */ 880 if (witness_watch > 1 && w->w_level > w1->w_level) { --- 25 unchanged lines hidden (view full) --- 906 } 907 printf("lock order reversal\n"); 908 printf(" 1st %s last acquired @ %s:%d\n", 909 w->w_description, w->w_file, w->w_line); 910 printf(" 2nd %p %s @ %s:%d\n", 911 m1, w1->w_description, w1->w_file, w1->w_line); 912 printf(" 3rd %p %s @ %s:%d\n", 913 m, w->w_description, file, line); | 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); |
914#ifdef KDEBUG 915 go_into_kdebug = 1; 916#endif /* KDEBUG */ | 896#ifdef DDB 897 go_into_ddb = 1; 898#endif /* DDB */ |
917 goto out; 918 } 919 } 920 m1 = LIST_FIRST(&p->p_heldmtx); 921 if (!itismychild(m1->mtx_witness, w)) 922 mtx_exit(&w_mtx, MTX_SPIN); 923 924out: | 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: |
925#ifdef KDEBUG 926 if (witness_kdebug && go_into_kdebug) 927 kdebug(); 928#endif /* KDEBUG */ | 907#ifdef DDB 908 if (witness_ddb && go_into_ddb) 909 Debugger("witness_enter"); 910#endif /* DDB */ |
929 w->w_file = file; 930 w->w_line = line; 931 m->mtx_line = line; 932 m->mtx_file = file; 933 934 /* 935 * If this pays off it likely means that a mutex being witnessed 936 * is acquired in hardclock. Put it in the ignore list. It is --- 117 unchanged lines hidden (view full) --- 1054 goto next; 1055 printf("%s:%d: %s with \"%s\" locked from %s:%d\n", 1056 file, line, check_only ? "could sleep" : "sleeping", 1057 m->mtx_description, 1058 m->mtx_witness->w_file, m->mtx_witness->w_line); 1059 n++; 1060 next: 1061 } | 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 } |
1062#ifdef KDEBUG 1063 if (witness_kdebug && n) 1064 kdebug(); 1065#endif /* KDEBUG */ | 1044#ifdef DDB 1045 if (witness_ddb && n) 1046 Debugger("witness_sleep"); 1047#endif /* DDB */ |
1066 return (n); 1067} 1068 1069static struct witness * 1070enroll(const char *description, int flag) 1071{ 1072 int i; 1073 struct witness *w, *w1; 1074 char **ignore; 1075 char **order; 1076 1077 if (!witness_watch) 1078 return (NULL); 1079 for (ignore = ignore_list; *ignore != NULL; ignore++) 1080 if (strcmp(description, *ignore) == 0) 1081 return (NULL); 1082 1083 if (w_inited == 0) { | 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) { |
1084 mtx_init(&w_mtx, "witness lock", MTX_DEF); | 1066 mtx_init(&w_mtx, "witness lock", MTX_COLD | MTX_DEF); |
1085 for (i = 0; i < WITNESS_COUNT; i++) { 1086 w = &w_data[i]; 1087 witness_free(w); 1088 } 1089 w_inited = 1; 1090 for (order = order_list; *order != NULL; order++) { 1091 w = enroll(*order, MTX_DEF); 1092 w->w_file = "order list"; --- 287 unchanged lines hidden --- | 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 --- |