Serious mapping problem with 2.9
ps at uok.UUCP
ps at uok.UUCP
Wed Oct 24 09:41:00 AEST 1984
Subject: panic: trap type 11
Index: /usr/include/sys/seg.h 2.9bsd
Description:
The system crashes with a 'panic: trap type 11'. This is
quite possible on a system compiled with NOKA5 undefined
and data extending up into the fifth segment. (> 40K data+bss)
The machine may also just stop without saying very much (anything?)
if you get two segmentation violations in a short period of time.
In this last case, the machine will not even reboot itself because
it is spinning in trap().
Repeat-By:
Hard to repeat on demand. This problem seems to be timing
dependant. A possible scenario is:
buffer gets mapped in:
*KDSD5 = (BSIZE << 2) | RW
*KDSA5 = click address in buffer pool
... (copying buffer)
clock interrupts:
map[0].se_addr = *KDSA5;
map[0].se_desc = *KDSD5;
*KDSD5 = seg5.se_desc;
*KDSA5 = seg5.se_addr;
... (handle 1 second clock processing)
... ((++lbolt >= hz) && BASEPRI(ps)) is true
... drop the priority to spl1().
... finish processing, start the restormap stuff
*KDSD5 = map[0].se_desc;
disk interrupts:
calls wakeup to notify process of completion of I/O
no Savemap() done because *KDSA5 == seg5.se_addr
and KDSD5 is not checked.
(notice, KDSD5 wrong, KDSA5 correct)
wakeup tries to reference something beyond the size
of a buffer in the fifth segment,
segmentation violation!
Fix:
The solution appears to be to change the savemap() macro
in /usr/include/sys/seg.h. Both the address and descriptor
registers need to be checked when deciding whether to call
Savemap().
It was:
#define savemap(map) {if (*KDSA5 != seg5.se_addr) Savemap(map); \
else map[0].se_desc = NOMAP; }
It should be changed to:
#define savemap(map) \
{\
if (*KDSA5 != seg5.se_addr || *KDSD5 != seg5.se_desc)\
Savemap(map);\
else\
map[0].se_desc = NOMAP;\
}
There is also a small problem in sys/machdep.c in the Restormap()
routine. The code to restore the values of KDS?5 is done in the
wrong order and should be reversed.
It was:
*KDSA5 = map[0].se_addr;
*KDSD5 = map[0].se_desc;
It should be:
*KDSD5 = map[0].se_desc;
*KDSA5 = map[0].se_addr;
We have been running on a kernel with these changes for about two
weeks with no apparent problems. Prior to making these changes,
we would crash at random times, varying from about 5 minutes to 48
hours.
More information about the Comp.bugs.2bsd
mailing list