Hi all,
To slove the infinite loop caused by a page fault in a RT task, I added a
test in the
do_page_fault function:
asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long
error_code)
{
struct task_struct *tsk;
struct mm_struct *mm;
struct vm_area_struct * vma;
unsigned long address;
unsigned long page;
unsigned long fixup;
int write;
/* get the address */
__asm__("movl %%cr2,%0":"=r" (address));
tsk = current;
mm = tsk->mm;
/********* NEW LINES ***********/
if (((unsigned int)mm & 0xF0000000) != 0xC0000000) {
printk("Page fault: mm=0x%x pid=0x%x\n", (unsigned int)mm, (unsigned
int)tsk->pid);
tsk->pid = 0; /* To cause a panic */
goto no_context;
}
/********* END OF NEW LINES ************/
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
if (in_interrupt() || mm == &init_mm)
goto no_context;
....
With these lines all the information about the bad access are displayed,
and it finishes by a panic "Attempted to kill the idle task !".
Have you another idea ??
Thanks.
Denis RICHARD wrote:
> Hi all,
>
> We work on LINUX 2.2.13 and RTL 2.0.
>
> When a RT task produces a page fault (bad pointer, ....: see the
> following code),
> the exception function (do_page_fault: arch/i386/mm/fault.c)
> also produces a page fault -> infinite loop.
>
> >From a RT task, it seems that the current task structure is not valide
> (tsk variable in do_page_fault function: tsk = current;).
>
> Is it normal ????
>
> How to solve the problem and display information about the page fault ?
>
> If this page fault is produced in a simple module (not from a RT task),
> the panic displays all the informations about the access (address, IP,
> stack, ...).
> For debugging it is very useful.
>
> Many thanks.
>
> Denis
>
> #include <rtl.h>
> #include <rtl_sched.h>
> #include <linux/module.h>
>
> RT_TASK k_test_task;
> int nb;
>
> void k_test(int data) {
> char *ptr = 0;
>
> for (;;) {
> rtl_printf("k_test: %d\n", nb);
> rtl_printf("ptr=0x%x\n", ptr);
> rtl_printf("Before access in zero\n");
> *ptr = 0; /* Access in zero to produce a page fault */
> rtl_printf("After access in zero\n");
> nb++;
> rt_task_wait();
> }
> }
>
> int init_module(void) {
>
> nb = 0;
> /* Create task */
> if (rt_task_init(&k_test_task, k_test, 0, 8192, 1) < 0) {
> printk("init_module: Error rt_task_init\n");
> return(-1);
> }
> if (rt_task_make_periodic(&k_test_task, rt_get_time() +
> (RTIME)(RT_TICKS_PER_SEC * 2),
> (RTIME)(RT_TICKS_PER_SEC * 5)) < 0) {
> printk("init_module: Error rt_task_make_periodic\n");
> return(-1);
> }
> return(0);
> }
>
> void cleanup_module(void) {
> rt_task_delete(&k_test_task);
> rtl_printf("Cleanup module\n");
> }
>
> -- [rtl] ---
> To unsubscribe:
> echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
> echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
> ---
> For more information on Real-Time Linux see:
> http://www.rtlinux.org/rtlinux/
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
---
For more information on Real-Time Linux see:
http://www.rtlinux.org/rtlinux/