diff -urN 2.4.7pre7aa1/fs/inode.c prefetch/fs/inode.c --- 2.4.7pre7aa1/fs/inode.c Wed Jul 18 17:40:02 2001 +++ prefetch/fs/inode.c Wed Jul 18 17:40:21 2001 @@ -15,6 +15,7 @@ #include #include #include +#include /* * New inode.c implementation. @@ -785,6 +786,8 @@ static unsigned long last_ino; struct inode * inode; + spin_lock_prefetch(&inode_lock); + inode = alloc_inode(); if (inode) { diff -urN 2.4.7pre7aa1/include/asm-i386/processor.h prefetch/include/asm-i386/processor.h --- 2.4.7pre7aa1/include/asm-i386/processor.h Wed Jul 18 17:40:02 2001 +++ prefetch/include/asm-i386/processor.h Wed Jul 18 17:40:21 2001 @@ -474,4 +474,32 @@ __asm__ __volatile__("rep;nop"); } +/* Prefetch instructions for Pentium III and AMD Athlon */ +#ifdef CONFIG_M686FXSR + +#define ARCH_HAS_PREFETCH +extern inline void prefetch(const void *x) +{ + __asm__ __volatile__ ("prefetchnta (%0)" : : "r"(x)); +} + +#elif CONFIG_X86_USE_3DNOW + +#define ARCH_HAS_PREFETCH +#define ARCH_HAS_PREFETCHW +#define ARCH_HAS_SPINLOCK_PREFETCH + +extern inline void prefetch(const void *x) +{ + __asm__ __volatile__ ("prefetch (%0)" : : "r"(x)); +} + +extern inline void prefetchw(const void *x) +{ + __asm__ __volatile__ ("prefetch (%0)" : : "r"(x)); +} +#define spin_lock_prefetch(x) prefetchw(x) + +#endif + #endif /* __ASM_I386_PROCESSOR_H */ diff -urN 2.4.7pre7aa1/include/asm-i386/uaccess.h prefetch/include/asm-i386/uaccess.h --- 2.4.7pre7aa1/include/asm-i386/uaccess.h Wed Jul 18 17:40:02 2001 +++ prefetch/include/asm-i386/uaccess.h Wed Jul 18 17:40:21 2001 @@ -531,6 +531,7 @@ static inline unsigned long __constant_copy_to_user(void *to, const void *from, unsigned long n) { + prefetch(from); if (access_ok(VERIFY_WRITE, to, n)) __constant_copy_user(to,from,n); return n; diff -urN 2.4.7pre7aa1/include/linux/list.h prefetch/include/linux/list.h --- 2.4.7pre7aa1/include/linux/list.h Wed Jul 18 17:40:02 2001 +++ prefetch/include/linux/list.h Wed Jul 18 17:40:21 2001 @@ -3,6 +3,8 @@ #if defined(__KERNEL__) || defined(_LVM_H_INCLUDE) +#include + /* * Simple doubly linked list implementation. * @@ -147,8 +149,9 @@ * @head: the head for your list. */ #define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - + for (pos = (head)->next, prefetch(pos->next); pos != (head); \ + pos = pos->next, prefetch(pos->next)) + #endif /* __KERNEL__ || _LVM_H_INCLUDE */ #endif diff -urN 2.4.7pre7aa1/include/linux/prefetch.h prefetch/include/linux/prefetch.h --- 2.4.7pre7aa1/include/linux/prefetch.h Thu Jan 1 01:00:00 1970 +++ prefetch/include/linux/prefetch.h Wed Jul 18 17:40:21 2001 @@ -0,0 +1,60 @@ +/* + * Generic cache management functions. Everything is arch-specific, + * but this header exists to make sure the defines/functions can be + * used in a generic way. + * + * 2000-11-13 Arjan van de Ven + * + */ + +#ifndef _LINUX_PREFETCH_H +#define _LINUX_PREFETCH_H + +#include +#include + +/* + prefetch(x) attempts to pre-emptively get the memory pointed to + by address "x" into the CPU L1 cache. + prefetch(x) should not cause any kind of exception, prefetch(0) is + specifically ok. + + prefetch() should be defined by the architecture, if not, the + #define below provides a no-op define. + + There are 3 prefetch() macros: + + prefetch(x) - prefetches the cacheline at "x" for read + prefetchw(x) - prefetches the cacheline at "x" for write + spin_lock_prefetch(x) - prefectches the spinlock *x for taking + + there is also PREFETCH_STRIDE which is the architecure-prefered + "lookahead" size for prefetching streamed operations. + +*/ + +/* + * These cannot be do{}while(0) macros. See the mental gymnastics in + * the loop macro. + */ + +#ifndef ARCH_HAS_PREFETCH +#define ARCH_HAS_PREFETCH +static inline void prefetch(const void *x) {;} +#endif + +#ifndef ARCH_HAS_PREFETCHW +#define ARCH_HAS_PREFETCHW +static inline void prefetchw(const void *x) {;} +#endif + +#ifndef ARCH_HAS_SPINLOCK_PREFETCH +#define ARCH_HAS_SPINLOCK_PREFETCH +#define spin_lock_prefetch(x) prefetchw(x) +#endif + +#ifndef PREFETCH_STRIDE +#define PREFETCH_STRIDE (4*L1_CACHE_BYTE) +#endif + +#endif diff -urN 2.4.7pre7aa1/kernel/sched.c prefetch/kernel/sched.c --- 2.4.7pre7aa1/kernel/sched.c Wed Jul 18 17:40:02 2001 +++ prefetch/kernel/sched.c Wed Jul 18 17:40:39 2001 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -575,6 +576,8 @@ #ifdef CONFIG_NUMA_SCHED int recalculate_all; #endif + + spin_lock_prefetch(&runqueue_lock); if (!current->active_mm) BUG(); need_resched_back: