David S. Ahern wrote:
Avi:
We did not get a chance to do this at the Forum. I'd be interested in
whatever options you have for reducing the scan time further (e.g., try
to get scan time down to 1-2 seconds).
I'm unlikely to get time to do this properly for at least a week, as
this will be quite difficult and I'm already horribly backlogged.
However there's an alternative option, modifying the source and getting
it upstreamed, as I think RHEL 3 is still maintained.
The attached patch (untested) should give a 3X boost for kmap_atomics,
by folding the two accesses to set the pte into one, and by dropping the
access that clears the pte. Unfortunately it breaks the ABI, since
external modules will inline the original kmap_atomic() which expects
the pte to be cleared.
This can be worked around by allocating new fixmap slots for kmap_atomic
with the new behavior, and keeping the old slots with the old behavior,
but we should first see if the maintainers are open to performance
optimizations targeting kvm.
--
Do not meddle in the internals of kernels, for they are subtle and quick to
panic.
--- include/asm-i386/atomic_kmap.h.orig 2007-06-12 00:24:29.000000000 +0300
+++ include/asm-i386/atomic_kmap.h 2008-06-22 09:23:26.000000000 +0300
@@ -51,18 +51,13 @@ static inline void *__kmap_atomic(struct
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-#if HIGHMEM_DEBUG
- if (!pte_none(*(kmap_pte-idx)))
- out_of_line_bug();
-#else
/*
* Performance optimization - do not flush if the new
* pte is the same as the old one:
*/
if (pte_val(*(kmap_pte-idx)) == pte_val(mk_pte(page, kmap_prot)))
return (void *) vaddr;
-#endif
- set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
+ set_pte_atomic(kmap_pte-idx, mk_pte(page, kmap_prot));
__flush_tlb_one(vaddr);
return (void*) vaddr;
@@ -77,12 +72,6 @@ static inline void __kunmap_atomic(void
if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
out_of_line_bug();
- /*
- * force other mappings to Oops if they'll try to access
- * this pte without first remap it
- */
- pte_clear(kmap_pte-idx);
- __flush_tlb_one(vaddr);
#endif
}