Index: linux-2.6.16-rc4/arch/ia64/kernel/ivt.S =================================================================== --- linux-2.6.16-rc4.orig/arch/ia64/kernel/ivt.S 2006-02-17 14:23:45.000000000 -0800 +++ linux-2.6.16-rc4/arch/ia64/kernel/ivt.S 2006-02-21 17:42:37.000000000 -0800 @@ -12,6 +12,7 @@ * * 00/08/23 Asit Mallick TLB handling for SMP * 00/12/20 David Mosberger-Tang DTLB/ITLB handler now uses virtual PT. + * 06/02/20 Christoph Lameter Count dirty ptes. */ /* * This file defines the interruption vector table used by the CPU. @@ -535,7 +536,7 @@ ENTRY(dkey_miss) END(dkey_miss) .org ia64_ivt+0x2000 -///////////////////////////////////////////////////////////////////////////////////////// +//////////://///////////////////////////////////////////////////////////////////////////// // 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54) ENTRY(dirty_bit) DBG_FAULT(8) @@ -547,23 +548,31 @@ ENTRY(dirty_bit) * normally do this without additional TLB misses. In case the necessary virtual * page table TLB entry isn't present, we take a nested TLB miss hit where we look * up the physical address of the L3 PTE and then continue at label 1 below. + * + * We also count the number of pte dirties in the thread_info structure + * to help us decide when to throttle a process that is dirtying too much + * memory. */ mov r16=cr.ifa // get the address that caused the fault movl r30=1f // load continuation point in case of nested fault + mov r28=ar.ccv // save ar.ccv + mov r19=IA64_KR(CURRENT) + mov r29=b0 // save b0 in case of nested fault ;; thash r17=r16 // compute virtual address of L3 PTE - mov r29=b0 // save b0 in case of nested fault mov r31=pr // save pr + adds r19=TI_DIRTY_PTE_COUNT+IA64_TASK_SIZE,r19 // address of nr dirty ptes #ifdef CONFIG_SMP - mov r28=ar.ccv // save ar.ccv ;; 1: ld8 r18=[r17] - ;; // avoid RAW on r18 + ld8 r20=[r19] // number of dirty ptes + flags + mov r24=PAGE_SHIFT<<2 + ;; mov ar.ccv=r18 // set compare value for cmpxchg +// dep.z r20=1, TIF_PTE_DIRTY + 32, 1 // Set TIF_DIRTY bit in process flags or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits ;; cmpxchg8.acq r26=[r17],r25,ar.ccv - mov r24=PAGE_SHIFT<<2 ;; cmp.eq p6,p7=r26,r18 ;; @@ -576,22 +585,28 @@ ENTRY(dirty_bit) dv_serialize_data ld8 r18=[r17] // read PTE again +(p6) add r20=1,r20 // And count dirtied PTEs ;; + st8 [r19]=r20 // Save new number of dirty ptes */ cmp.eq p6,p7=r18,r25 // is it same as the newly installed + mov ar.ccv=r28 // restore ar.ccv ;; (p7) ptc.l r16,r24 - mov b0=r29 // restore b0 - mov ar.ccv=r28 #else ;; 1: ld8 r18=[r17] + ld8 r20=[r19] // Load number of dirty ptes ;; // avoid RAW on r18 + add r20=1,r20 // increment number of dirty ptes or r18=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits - mov b0=r29 // restore b0 ;; + dep.z r20=1, TIF_PTE_DIRTY + 32, 1 // Set TIF_DIRTY bit in process flags + ;; + st8 [r19]=r20 // Save new number of dirty ptes */ st8 [r17]=r18 // store back updated PTE itc.d r18 // install updated PTE #endif + mov b0=r29 // restore b0 mov pr=r31,-1 // restore pr rfi END(dirty_bit) Index: linux-2.6.16-rc4/arch/ia64/kernel/asm-offsets.c =================================================================== --- linux-2.6.16-rc4.orig/arch/ia64/kernel/asm-offsets.c 2006-02-17 14:23:45.000000000 -0800 +++ linux-2.6.16-rc4/arch/ia64/kernel/asm-offsets.c 2006-02-21 17:40:52.000000000 -0800 @@ -37,6 +37,7 @@ void foo(void) DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count)); + DEFINE(TI_DIRTY_PTE_COUNT, offsetof(struct thread_info, dirty_pte_count)); BLANK();