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
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