From: Ben Gras Date: Fri, 10 Feb 2006 16:53:51 +0000 (+0000) Subject: added reenter check to lock_dequeue() to avoid unlocking of interrupts X-Git-Tag: v3.1.2a~371 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/rndc.conf.html?a=commitdiff_plain;h=88ba4b526800411f7d7aadd7583d13c566f24e53;p=minix.git added reenter check to lock_dequeue() to avoid unlocking of interrupts via cause_sig() during an exception. moved lock check configuration to instead of kernel/config.h, because the 'relocking' field in kinfo depends on it. other prettification: common locking macro, whether lock timing is on or not. --- diff --git a/include/limits.h b/include/limits.h index ad261aecb..74cdff0ee 100755 --- a/include/limits.h +++ b/include/limits.h @@ -67,7 +67,7 @@ #define ARG_MAX 4096 /* args + environ on small machines */ #endif #define CHILD_MAX _NO_LIMIT /* MINIX does not limit children */ -#define OPEN_MAX 30 /* # open files a process may have */ +#define OPEN_MAX 32 /* # open files a process may have */ #if 0 /* V1 file system */ #define LINK_MAX CHAR_MAX /* # links a file may have */ #else /* V2 or better file system */ diff --git a/include/minix/sys_config.h b/include/minix/sys_config.h index 69ccaa47d..5df200d2e 100755 --- a/include/minix/sys_config.h +++ b/include/minix/sys_config.h @@ -68,4 +68,7 @@ error "In please define _MINIX_MACHINE to have a legal valu error "_MINIX_MACHINE has incorrect value (0)" #endif +/* Kernel debug checks */ +#define DEBUG_LOCK_CHECK 0 /* Interrupt Lock/unlock sanity checking. */ + #endif /* _MINIX_SYS_CONFIG_H */ diff --git a/include/minix/type.h b/include/minix/type.h index ab8801588..e4def1221 100755 --- a/include/minix/type.h +++ b/include/minix/type.h @@ -104,7 +104,9 @@ struct kinfo { int nr_tasks; /* number of kernel tasks */ char release[6]; /* kernel release number */ char version[6]; /* kernel version number */ - int relocking; /* relocking check (for debugging) */ +#if DEBUG_LOCK_CHECK + int relocking; /* interrupt locking depth (should be 0) */ +#endif }; /* Load data accounted every this no. of seconds. */ diff --git a/kernel/config.h b/kernel/config.h index 5ffe84c5f..9253fe94f 100644 --- a/kernel/config.h +++ b/kernel/config.h @@ -76,7 +76,6 @@ * For normal operation all options should be disabled. */ #define DEBUG_SCHED_CHECK 0 /* sanity check of scheduling queues */ -#define DEBUG_LOCK_CHECK 0 /* kernel lock() sanity check */ #define DEBUG_TIME_LOCKS 0 /* measure time spent in locks */ #endif /* CONFIG_H */ diff --git a/kernel/const.h b/kernel/const.h index 77385f36c..e1d040bef 100755 --- a/kernel/const.h +++ b/kernel/const.h @@ -58,11 +58,19 @@ #define IF_MASK 0x00000200 #define IOPL_MASK 0x003000 +#if DEBUG_LOCK_CHECK +#define reallock(c, v) { if (!(read_cpu_flags() & X86_FLAG_I)) { kinfo.relocking++; } else { intr_disable(); } } +#else +#define reallock(c, v) intr_disable() +#endif + +#define realunlock(c) intr_enable() + /* Disable/ enable hardware interrupts. The parameters of lock() and unlock() * are used when debugging is enabled. See debug.h for more information. */ -#define lock(c, v) intr_disable(); -#define unlock(c) intr_enable(); +#define lock(c, v) reallock(c, v) +#define unlock(c) realunlock(c) /* Sizes of memory tables. The boot monitor distinguishes three memory areas, * namely low mem below 1M, 1M-16M, and mem after 16M. More chunks are needed diff --git a/kernel/debug.h b/kernel/debug.h index 0e067feed..71e874317 100644 --- a/kernel/debug.h +++ b/kernel/debug.h @@ -51,15 +51,6 @@ _PROTOTYPE( void timer_end, (int cat) ); #define locktimeend(c) #endif /* DEBUG_TIME_LOCKS */ -/* The locking checks counts relocking situation, which are dangerous because - * the inner lock may unlock the outer one. - */ -#if DEBUG_LOCK_CHECK -#define lockcheck if (!(read_cpu_flags() & X86_FLAG_I)) kinfo.relocking++; -#else -#define lockcheck -#endif /* DEBUG_LOCK_CHECK */ - /* This check makes sure that the scheduling queues are in a consistent state. * The check is run when the queues are updated with ready() and unready(). */ @@ -73,14 +64,9 @@ _PROTOTYPE( void check_runqueues, (char *when) ); */ #if (DEBUG_TIME_LOCKS || DEBUG_LOCK_CHECK) # undef lock -# define lock(c, v) do { lockcheck; \ - intr_disable(); \ - locktimestart(c, v); \ - } while(0) +# define lock(c, v) do { reallock(c, v); locktimestart(c, v); } while(0) # undef unlock -# define unlock(c) do { locktimeend(c); \ - intr_enable();\ - } while(0) +# define unlock(c) do { locktimeend(c); realunlock(c); } while(0) #endif #endif /* DEBUG_H */ diff --git a/kernel/proc.c b/kernel/proc.c index f4d7eafaf..1fa720864 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -669,8 +669,15 @@ PUBLIC void lock_dequeue(rp) struct proc *rp; /* this process is no longer runnable */ { /* Safe gateway to dequeue() for tasks. */ - lock(4, "dequeue"); - dequeue(rp); - unlock(4); + if (k_reenter >= 0) { + /* We're in an exception or interrupt, so don't lock (and.. + * don't unlock). + */ + dequeue(rp); + } else { + lock(4, "dequeue"); + dequeue(rp); + unlock(4); + } }