Messages in this thread Patch in this message | | | Subject | Re: GGI and cli/sti in X | From | Jean Wolter <> | Date | 28 Mar 1998 16:48:06 +0200 |
| |
alan@lxorguk.ukuu.org.uk (Alan Cox) writes:
> > > I get 5 or 6 ughs everytime somone runs X onmy system so I'd say your > > correct, the ughs are allways in do_page_fault. The ughs are normal on > > any system I've seen with < 16 megs ram. The every once and a while > > The "Ugh" is logging the fact someone attempted to handle a page fault while > having interrupts disabled. This is an extremely bad thing. There are two causes > > 1. Incorrect kernel code (I think most of these are now dead) > 2. Some user process as root which has the misguided idea it can disable > interrupts after using the iopl() syscall. Well it can't. Not unless > its prepaged everything it needs and mlock()'d those pages > > so its either a kernel or an X bug. > > Alan
If this is a bug I would like to point out one place where such a bug still exists:
static int rs_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count) { ... save_flags(flags); while (1) { cli(); ... if (from_user) { c -= copy_from_user(tmp_buf, buf, c); ... } restore_flags(flags); ... }
Under heavy load both X and gpm are raising page faults at this place. Unfortunatly the Ugh is only generated by SMP kernels. I have found this sequence only after inserting some statements that check for disabled interrupts on non smp systems too. Maybe it would be a good idee to insert such a check in both systems (smp and non smp).
Jean
PS:
The backtrace looks like that (2.1.91):
>>EIP: c019416a <__generic_copy_from_user+36/40> Trace: c017b0ef <rs_write+10b/20c> Trace: c016dd56 <write_chan+152/1d0> Trace: c0169d75 <tty_write+121/178> Trace: c016dd56 <write_chan+152/1d0> Trace: c012373c <sys_write+b4/10c> Trace: c010992a <system_call+3a/40> Code: c019416a <__generic_copy_from_user+36/40> Code: c019416a <__generic_copy_from_user+36/40> f3 a4 repz movsb %ds:(%esi),%es:(%edi)
The added check like that:
--- fault.c.orig Sat Mar 28 16:15:29 1998 +++ fault.c Sat Mar 28 16:15:00 1998 @@ -76,6 +76,7 @@ } asmlinkage void do_invalid_op (struct pt_regs *, unsigned long); +extern void show_registers(struct pt_regs *regs); /* * This routine handles page faults. It determines the address, @@ -102,6 +103,13 @@ if (local_irq_count[smp_processor_id()]) die_if_kernel("page fault from irq handler",regs,error_code); + + if (!(regs->eflags & 0x200)) { + printk("program %s raised page fault at eip %lx while interrupts disabled\n", + current->comm, regs->eip); + show_registers(regs); + } + lock_kernel(); tsk = current; mm = tsk->mm;
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |