summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/powerpc
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2013-08-29 15:49:05 +0000
committeralc <alc@FreeBSD.org>2013-08-29 15:49:05 +0000
commitaa9a7bb9e6c374d0ee2f00489abd48f856d79aee (patch)
tree548fcd5f51d9d645c37a8a20f515a3b39c70329c /sys/powerpc/powerpc
parent4212d5ac38bc35cd7d1671a7a93ad65425dbdded (diff)
downloadFreeBSD-src-aa9a7bb9e6c374d0ee2f00489abd48f856d79aee.zip
FreeBSD-src-aa9a7bb9e6c374d0ee2f00489abd48f856d79aee.tar.gz
Significantly reduce the cost, i.e., run time, of calls to madvise(...,
MADV_DONTNEED) and madvise(..., MADV_FREE). Specifically, introduce a new pmap function, pmap_advise(), that operates on a range of virtual addresses within the specified pmap, allowing for a more efficient implementation of MADV_DONTNEED and MADV_FREE. Previously, the implementation of MADV_DONTNEED and MADV_FREE relied on per-page pmap operations, such as pmap_clear_reference(). Intuitively, the problem with this implementation is that the pmap-level locks are acquired and released and the page table traversed repeatedly, once for each resident page in the range that was specified to madvise(2). A more subtle flaw with the previous implementation is that pmap_clear_reference() would clear the reference bit on all mappings to the specified page, not just the mapping in the range specified to madvise(2). Since our malloc(3) makes heavy use of madvise(2), this change can have a measureable impact. For example, the system time for completing a parallel "buildworld" on a 6-core amd64 machine was reduced by about 1.5% to 2.0%. Note: This change only contains pmap_advise() implementations for a subset of our supported architectures. I will commit implementations for the remaining architectures after further testing. For now, a stub function is sufficient because of the advisory nature of pmap_advise(). Discussed with: jeff, jhb, kib Tested by: pho (i386), marcel (ia64) Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'sys/powerpc/powerpc')
-rw-r--r--sys/powerpc/powerpc/mmu_if.m19
-rw-r--r--sys/powerpc/powerpc/pmap_dispatch.c9
2 files changed, 28 insertions, 0 deletions
diff --git a/sys/powerpc/powerpc/mmu_if.m b/sys/powerpc/powerpc/mmu_if.m
index 0382bd8..f9f37cb 100644
--- a/sys/powerpc/powerpc/mmu_if.m
+++ b/sys/powerpc/powerpc/mmu_if.m
@@ -133,6 +133,25 @@ CODE {
/**
+ * @brief Apply the given advice to the specified range of addresses within
+ * the given pmap. Depending on the advice, clear the referenced and/or
+ * modified flags in each mapping and set the mapped page's dirty field.
+ *
+ * @param _pmap physical map
+ * @param _start virtual range start
+ * @param _end virtual range end
+ * @param _advice advice to apply
+ */
+METHOD void advise {
+ mmu_t _mmu;
+ pmap_t _pmap;
+ vm_offset_t _start;
+ vm_offset_t _end;
+ int _advice;
+};
+
+
+/**
* @brief Change the wiring attribute for the page in the given physical
* map and virtual address.
*
diff --git a/sys/powerpc/powerpc/pmap_dispatch.c b/sys/powerpc/powerpc/pmap_dispatch.c
index 7fd98f4..24e6076 100644
--- a/sys/powerpc/powerpc/pmap_dispatch.c
+++ b/sys/powerpc/powerpc/pmap_dispatch.c
@@ -91,6 +91,15 @@ RB_GENERATE(pvo_tree, pvo_entry, pvo_plink, pvo_vaddr_compare);
void
+pmap_advise(pmap_t pmap, vm_offset_t start, vm_offset_t end, int advice)
+{
+
+ CTR5(KTR_PMAP, "%s(%p, %#x, %#x, %d)", __func__, pmap, start, end,
+ advice);
+ MMU_ADVISE(mmu_obj, pmap, start, end, advice);
+}
+
+void
pmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired)
{
OpenPOWER on IntegriCloud