Trap handler
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 8 lines
Quoted 4 lines
I just happened to notice that the system almost totally stalled running the test. The load average jumps from 1 to about 9. You just have to compile and run to see the effect. Line 127 writes to unmapped memory and causes multiple entries in
/var/log/debug.Dave, can you send the test program and details to the list? i didn't see the beginning of this thread and am not sure which program you are refering to.
Here it is.
Dave
Signature · 244 lines
J. David Anglin [email protected] National Research Council of Canada (613) 990-0752 (FAX: 952-6605) #include <sys/types.h> #include <sys/mman.h> #include <fcntl.h> #include <signal.h> #include <setjmp.h> #include <stdio.h> #if !defined (MAP_ANONYMOUS) && defined (MAP_ANON) # define MAP_ANONYMOUS MAP_ANON #endif /* This mess was copied from the GNU getpagesize.h. */ #ifndef HAVE_GETPAGESIZE # ifdef HAVE_UNISTD_H # include <unistd.h> # endif /* Assume that all systems that can run configure have sys/param.h. */ # ifndef HAVE_SYS_PARAM_H # define HAVE_SYS_PARAM_H 1 # endif # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ # ifdef HAVE_SYS_PARAM_H # include <sys/param.h> # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE # else /* no EXEC_PAGESIZE */ # ifdef NBPG # define getpagesize() NBPG * CLSIZE # ifndef CLSIZE # define CLSIZE 1 # endif /* no CLSIZE */ # else /* no NBPG */ # ifdef NBPC # define getpagesize() NBPC # else /* no NBPC */ # ifdef PAGESIZE # define getpagesize() PAGESIZE # endif /* PAGESIZE */ # endif /* no NBPC */ # endif /* no NBPG */ # endif /* no EXEC_PAGESIZE */ # else /* no HAVE_SYS_PARAM_H */ # define getpagesize() 8192 /* punt totally */ # endif /* no HAVE_SYS_PARAM_H */ # endif /* no _SC_PAGESIZE */ #endif /* no HAVE_GETPAGESIZE */ #ifndef MAP_FAILED # define MAP_FAILED -1 #endif #undef perror_exit #define perror_exit(str, val) \ do { perror(str); exit(val); } while (0) /* Some versions of cygwin mmap require that munmap is called with the same parameters as mmap. GCC expects that this is not the case. Test for various forms of this problem. Warning - icky signal games. */ static sigset_t unblock_sigsegv; static jmp_buf r; static size_t pg; static int devzero; static char * anonmap (size) size_t size; { #ifdef USE_MAP_ANON return (char *) mmap (0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); #else return (char *) mmap (0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, devzero, 0); #endif } static void sigsegv (unused) int unused; { sigprocmask (SIG_UNBLOCK, &unblock_sigsegv, 0); longjmp (r, 1); } /* Basic functionality test. */ void test_0 () { char *x = anonmap (pg); if (x == (char *) MAP_FAILED) perror_exit("test 0 mmap", 2); *(int *)x += 1; if (munmap(x, pg) < 0) perror_exit("test 0 munmap", 3); } /* 1. If we map a 2-page region and unmap its second page, the first page must remain. */ static void test_1 () { char *x = anonmap (pg * 2); if (x == (char *)MAP_FAILED) perror_exit ("test 1 mmap", 4); signal (SIGSEGV, sigsegv); if (setjmp (r)) perror_exit ("test 1 fault", 5); x[0] = 1; x[pg] = 1; if (munmap (x + pg, pg) < 0) perror_exit ("test 1 munmap 1", 6); x[0] = 2; if (setjmp (r) == 0) { x[pg] = 1; perror_exit ("test 1 no fault", 7); } if (munmap (x, pg) < 0) perror_exit ("test 1 munmap 2", 8); } /* 2. If we map a 2-page region and unmap its first page, the second page must remain. */ static void test_2 () { char *x = anonmap (pg * 2); if (x == (char *)MAP_FAILED) perror_exit ("test 2 mmap", 9); signal (SIGSEGV, sigsegv); if (setjmp (r)) perror_exit ("test 2 fault", 10); x[0] = 1; x[pg] = 1; if (munmap (x, pg) < 0) perror_exit ("test 2 munmap 1", 11); x[pg] = 2; if (setjmp (r) == 0) { x[0] = 1; perror_exit ("test 2 no fault", 12); } if (munmap (x+pg, pg) < 0) perror_exit ("test 2 munmap 2", 13); } /* 3. If we map two adjacent 1-page regions and unmap them both with one munmap, both must go away. Getting two adjacent 1-page regions with two mmap calls is slightly tricky. All OS's tested skip over already-allocated blocks; therefore we have been careful to unmap all allocated regions in previous tests. HP/UX allocates pages backward in memory. No OS has yet been observed to be so perverse as to leave unmapped space between consecutive calls to mmap. */ static void test_3 () { char *x, *y, *z; x = anonmap (pg); if (x == (char *)MAP_FAILED) perror_exit ("test 3 mmap 1", 14); y = anonmap (pg); if (y == (char *)MAP_FAILED) perror_exit ("test 3 mmap 2", 15); if (y != x + pg) { if (y == x - pg) z = y, y = x, x = z; else { fprintf (stderr, "test 3 nonconsecutive pages - %lx, %lx\n", (unsigned long)x, (unsigned long)y); exit (16); } } signal (SIGSEGV, sigsegv); if (setjmp (r)) perror_exit ("test 3 fault", 17); x[0] = 1; y[0] = 1; if (munmap (x, pg*2) < 0) perror_exit ("test 3 munmap", 18); if (setjmp (r) == 0) { x[0] = 1; perror_exit ("test 3 no fault 1", 19); } signal (SIGSEGV, sigsegv); if (setjmp (r) == 0) { y[0] = 1; perror_exit ("test 3 no fault 2", 20); } } int main () { sigemptyset (&unblock_sigsegv); sigaddset (&unblock_sigsegv, SIGSEGV); pg = getpagesize (); #ifndef USE_MAP_ANON devzero = open ("/dev/zero", O_RDWR); if (devzero < 0) perror_exit ("open /dev/zero", 1); #endif test_0(); test_1(); test_2(); test_3(); exit(0); }
In reference to a message from John David Anglin, dated Dec 08:
Quoted 10 lines
Quoted 8 lines
Quoted 4 lines
I just happened to notice that the system almost totally stalled running the test. The load average jumps from 1 to about 9. You just have to compile and run to see the effect. Line 127 writes to unmapped memory and causes multiple entries in
/var/log/debug.Dave, can you send the test program and details to the list? i didn't see the beginning of this thread and am not sure which program you are refering to.
Here it is.
well, something is just very broken, even this simple code triggers the bug:
int main(int argc, char **argv)
{
int *p = 0;
return *p;
}the kernel goes nuts trying to page fault continuously.
:-(
randolph
Signature · 3 lines
Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/
Quoted 4 lines
Quoted 1 line
Here it is.
well, something is just very broken, even this simple code triggers the bug:
and with Grant's help, it's fixed in 2.4.20-pa12 :)
question for willy/jsm, etc though:
the fix has to do with where we should return to after handling an interruption. in pre-2.4.20 code we used to return to intr_return. Grant thinks that is incorrect and changed it to intr_restore (basically just doing the rfi). the -pa12 patch changes it back so it will handle pending signals. The items that remain not handled are restoring I-bit, softirqs (and irqstats) and rescheduling. We are not sure if those bits are needed for interruptions.... can you guys shed some light on this?
thanks,
randolph
Quoted 7 lines · Randolph Chung
the fix has to do with where we should return to after handling an interruption. in pre-2.4.20 code we used to return to
intr_return. Grant thinks that is incorrect and changed it tointr_restore(basically just doing the rfi). the -pa12 patch changes it back so it will handle pending signals. The items that remain not handled are restoring I-bit, softirqs (and irqstats) and rescheduling. We are not sure if those bits are needed for interruptions.... can you guys shed some light on this?
Well, let's look at the reference platform (ie x86):
ENTRY(page_fault)
pushl $do_page_fault
jmp error_code
error_code:
(blah blah blah. sets up stuff & calls the address on the stack)
call *%edi
addl $8, %esp
jmp ret_from_exceptionret_from_exception:
preempt_stopret_from_intr:
GET_THREAD_INFO(%ebx)
movl EFLAGS(%esp), %eax # mix EFLAGS and CS
movb CS(%esp), %al
testl $(VM_MASK | 3), %eax
jz resume_kernel # returning to kernel or vm86-spaceENTRY(resume_userspace)
cli # make sure we don't miss an interrupt
# setting need_resched or sigpending # between sampling and the iret
movl TI_FLAGS(%ebx), %ecx
andl $_TIF_WORK_MASK, %ecx # is there any work to be done on
# int/exception return?
jne work_pending
jmp restore_all
(with preemption disabled, resume_kernel == restore_all)
restore_all:
RESTORE_ALL
# perform work that needs to be done immediately before resumption ALIGNwork_pending:
testb $_TIF_NEED_RESCHED, %cl
jz work_notifysigwork_resched:
So x86 will potentially reschedule on successfully handling a page fault. softirqs seem to only get run if we're returning to userspace, unless we're switching tasks. That might be a bug in the x86 code. Judging from the use of cli & sti in the x86 asm, I would venture to suggest that the I bit should be cleared. It makes sense anyway -- you can't expect interrupts to be disabled over a page fault.
Signature · 3 lines
"It's not Hollywood. War is real, war is primarily not about defeat or victory, it is about death. I've seen thousands and thousands of dead bodies. Do you think I want to have an academic debate on this subject?" -- Robert Fisk
Quoted 1 line · Matthew Wilcox
x86 will potentially reschedule on successfully handling a page fault.
ok.
Quoted 2 lines
softirqs seem to only get run if we're returning to userspace, unless we're switching tasks. That might be a bug in the x86 code.
ok.
Quoted 3 lines
Judging from the use of cli & sti in the x86 asm, I would venture to suggest that the I bit should be cleared. It makes sense anyway -- you can't expect interrupts to be disabled over a page fault.
The above two statements don't make sense to me. Clearing I-bit (ie rsm) will disable interrupts. The second sentence suggests the opposite. Or did I read it wrong?
thanks,
grant
Quoted 8 lines · Grant Grundler
Quoted 3 lines
Judging from the use of cli & sti in the x86 asm, I would venture to suggest that the I bit should be cleared. It makes sense anyway -- you can't expect interrupts to be disabled over a page fault.
The above two statements don't make sense to me. Clearing I-bit (ie rsm) will disable interrupts. The second sentence suggests the opposite. Or did I read it wrong?
i misremembered the sense of the I bit
Signature · 3 lines
"It's not Hollywood. War is real, war is primarily not about defeat or victory, it is about death. I've seen thousands and thousands of dead bodies. Do you think I want to have an academic debate on this subject?" -- Robert Fisk
Quoted 4 lines · Matthew Wilcox
Quoted 3 lines · Grant Grundler
Quoted 3 lines
Judging from the use of cli & sti in the x86 asm, I would venture to suggest that the I bit should be cleared. It makes sense anyway -- you can't expect interrupts to be disabled over a page fault.
...
Quoted 1 line
i misremembered the sense of the I bit
As jsm agreed, if interrupts were disabled when we took the fault, we can't re-enable them while handling a page fault. Where x86 disables interrupts seems ok to me.
But the 2.4.20 parisc code (entry.S) re-enables interrupts at intr_return label (ssm insn). Should parisc *not* be re-enabling interrupts at all or at least not until after intr_check_resched code block?
I'm trying to align x86/parisc implementations. And "misaligned trap handler" is one difference I suspect the x86 code doesn't have to handle.
thanks,
grant
Quoted 3 lines · Grant Grundler
As jsm agreed, if interrupts were disabled when we took the fault, we can't re-enable them while handling a page fault. Where x86 disables interrupts seems ok to me.
um, there's a difference between a page fault and a TLB miss. if you have interrupts disabled and you take a page fault, something's gone horribly wrong. having interrupts disabled when you miss the TLB cache is no big deal. we _absolutely must not_ tamper with interrupt enable state when handling a TLB miss.
Signature · 3 lines
"It's not Hollywood. War is real, war is primarily not about defeat or victory, it is about death. I've seen thousands and thousands of dead bodies. Do you think I want to have an academic debate on this subject?" -- Robert Fisk
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Here it is.
well, something is just very broken, even this simple code triggers the bug:
and with Grant's help, it's fixed in 2.4.20-pa12 :)
The system doesn't seem to drop core on a segmentation fault anymore.
Dave
Signature · 2 lines
J. David Anglin [email protected] National Research Council of Canada (613) 990-0752 (FAX: 952-6605)
Quoted 1 line
The system doesn't seem to drop core on a segmentation fault anymore.
Forget last message.
Dave
Signature · 2 lines
J. David Anglin [email protected] National Research Council of Canada (613) 990-0752 (FAX: 952-6605)