2004-01-02 00:52:42

by Manfred Spraul

[permalink] [raw]
Subject: Re: [lhcs-devel] Re: in_atomic doesn't count local_irq_disable?

Srivatsa Vaddagiri wrote:

>More debugging reveals that the page fault happens
>always while doing a prefetch. The prefetch is
>present inside list_for_each_entry macros.
>
>For now I have disabled the x86 prefetch function
>to do nothing.
>
>The test seems to run fine so far w/o any of the
>page faults I was experiencing. Will update
>at the end of the overnight run if I hit the problem again.
>
>Wonder if prefetch has some issues on Intel x86 (P3) SMP systems?
>
>
Hmm. Perhaps prefetch updates CR2?
We know already that the CR2 is not directly linked to the page fault
interrupt - if a page fault happens at the same time as a higher
priority event (iirc hw interrupt), then CR2 is updated and the higher
priority event is handled. That prevents Linux from using CR2 to store
the cpu number - only netware can do that, because netware never causes
paging faults.

Could you write a test module that reads cr2, executes a few prefetch
instructions and then checks if cr2 changed? I won't have access to my
P3 SMP system in the next few days.

--
Manfred



2004-01-02 10:52:26

by Srivatsa Vaddagiri

[permalink] [raw]
Subject: Re: [lhcs-devel] Re: in_atomic doesn't count local_irq_disable?

On Fri, Jan 02, 2004 at 01:52:07AM +0100, Manfred Spraul wrote:
> Could you write a test module that reads cr2, executes a few prefetch
> instructions and then checks if cr2 changed? I won't have access to my
> P3 SMP system in the next few days.

Hi Manfred,
I wrote a test module and found that CR2 remains same across the
prefetch. The module source I used is as below. Note that I had
to used "my_prefetch" because the original prefetch (in asm/processor.h)
has been disabled in my tree to do nothing.



inline void my_prefetch(const void *x)
{
alternative_input(ASM_NOP4,
"prefetchnta (%1)",
X86_FEATURE_XMM,
"r" (x));
}

int array[10];

static int __init dummy_init_module(void)
{
unsigned long address;
int i=0;
int x;

/* get the address */
__asm__("movl %%cr2,%0":"=r" (address));

printk ("CR2 before prefetch is %x \n", address);

for (i=0; i<10; ++i)
my_prefetch(array+i);

for (i=0; i<10; ++i)
x = *(array+i);

/* get the address */
__asm__("movl %%cr2,%0":"=r" (address));


printk ("CR2 after prefetch is %x \n", address);


return 0;

}


static void __exit dummy_cleanup_module(void)
{
}

module_init(dummy_init_module);
module_exit(dummy_cleanup_module);
MODULE_LICENSE("GPL");


Output of the above printk is :


CR2 before prefetch is 40017000
CR2 after prefetch is 40017000








--


Thanks and Regards,
Srivatsa Vaddagiri,
Linux Technology Center,
IBM Software Labs,
Bangalore, INDIA - 560017