--- sp3/include/asm-i386/pgtable.h.~1~ 2003-09-29 18:47:36.000000000 +0200 +++ sp3/include/asm-i386/pgtable.h 2003-10-01 18:17:19.000000000 +0200 @@ -451,4 +451,6 @@ int change_page_attr(struct page *, int, #define io_remap_page_range remap_page_range +#define PTE_DIRTY_BIT_IN_HARDWARE + #endif /* _I386_PGTABLE_H */ --- sp3/include/asm-x86_64/pgtable.h.~1~ 2003-09-29 18:47:41.000000000 +0200 +++ sp3/include/asm-x86_64/pgtable.h 2003-10-01 18:17:05.000000000 +0200 @@ -469,5 +469,6 @@ extern void clear_kernel_mapping(unsigne #define pgtable_cache_init() do { } while (0) +#define PTE_DIRTY_BIT_IN_HARDWARE #endif /* _X86_64_PGTABLE_H */ --- sp3/mm/memory.c.~1~ 2003-09-29 18:48:54.000000000 +0200 +++ sp3/mm/memory.c 2003-10-01 18:19:59.000000000 +0200 @@ -1251,10 +1251,35 @@ static int do_swap_page(struct mm_struct mm->rss++; pte = mk_pte(page, vma->vm_page_prot); if (make_exclusive_page(page, write_access)) { +#ifdef PTE_DIRTY_BIT_IN_HARDWARE if (write_access) pte = pte_mkdirty(pte); if (vma->vm_flags & VM_WRITE) pte = pte_mkwrite(pte); +#else + /* + * When the page is in the swapcache, we can't mark + * the pte writeable without marking it dirty too + * otherwise architectures doing the dirty bit in software + * will not flush the page to disk, before releasing + * the swapcache. That's why we need an #ifdef here. + * Those architectures have to trigger a writeprotect + * fault on the not writeable swapcache to set the pte as + * dirty. + * + * If this is a read fault, we let the writeprotect + * fault to mark the page writeable and dirty if needed. + * This way if the page is still in the swapcache and it's + * clean, we can swapout it zerocost. + * + * This version is safe for archs with the dirty bit + * in hardware too (the other way around not), so if nothing + * is specified in the asm headers, the kernel will compile + * this one to go safe. + */ + if (write_access) + pte = pte_mkdirty(pte_mkwrite(pte)); +#endif } mark_page_accessed(page);