summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorjah <jah@FreeBSD.org>2017-01-21 06:48:52 +0000
committerjah <jah@FreeBSD.org>2017-01-21 06:48:52 +0000
commitef59148ea0822705bf28a48ab2ad4698d04c91cd (patch)
treeb37e3c9a185cbfd529149aafc436c12a8efe0d57 /sys/i386
parentcc1cc488263a31a084bbac0b8c3f19bc2ac11e8a (diff)
downloadFreeBSD-src-ef59148ea0822705bf28a48ab2ad4698d04c91cd.zip
FreeBSD-src-ef59148ea0822705bf28a48ab2ad4698d04c91cd.tar.gz
MFC r312153, r312191
r312153: For i386 temporary mappings, unpin the thread before releasing the cmap lock. Releasing the lock first may result in the thread being immediately rescheduled and bound to the same CPU, only to unpin itself upon resuming execution. Noted by: skra (in review for armv6 equivalent) r312191: Add comment explaining relative order of sched_unpin() and mtx_unlock(). Suggested by: alc
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/pmap.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 83f1bbf..d717876 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -4231,8 +4231,14 @@ pmap_zero_page(vm_page_t m)
invlcaddr(pc->pc_cmap_addr2);
pagezero(pc->pc_cmap_addr2);
*cmap_pte2 = 0;
- mtx_unlock(&pc->pc_cmap_lock);
+
+ /*
+ * Unpin the thread before releasing the lock. Otherwise the thread
+ * could be rescheduled while still bound to the current CPU, only
+ * to unpin itself immediately upon resuming execution.
+ */
sched_unpin();
+ mtx_unlock(&pc->pc_cmap_lock);
}
/*
@@ -4261,8 +4267,8 @@ pmap_zero_page_area(vm_page_t m, int off, int size)
else
bzero(pc->pc_cmap_addr2 + off, size);
*cmap_pte2 = 0;
- mtx_unlock(&pc->pc_cmap_lock);
sched_unpin();
+ mtx_unlock(&pc->pc_cmap_lock);
}
/*
@@ -4316,8 +4322,8 @@ pmap_copy_page(vm_page_t src, vm_page_t dst)
bcopy(pc->pc_cmap_addr1, pc->pc_cmap_addr2, PAGE_SIZE);
*cmap_pte1 = 0;
*cmap_pte2 = 0;
- mtx_unlock(&pc->pc_cmap_lock);
sched_unpin();
+ mtx_unlock(&pc->pc_cmap_lock);
}
int unmapped_buf_allowed = 1;
@@ -4364,8 +4370,8 @@ pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
}
*cmap_pte1 = 0;
*cmap_pte2 = 0;
- mtx_unlock(&pc->pc_cmap_lock);
sched_unpin();
+ mtx_unlock(&pc->pc_cmap_lock);
}
/*
@@ -5349,8 +5355,8 @@ pmap_flush_page(vm_page_t m)
if (useclflushopt || cpu_vendor_id != CPU_VENDOR_INTEL)
mfence();
*cmap_pte2 = 0;
- mtx_unlock(&pc->pc_cmap_lock);
sched_unpin();
+ mtx_unlock(&pc->pc_cmap_lock);
} else
pmap_invalidate_cache();
}
OpenPOWER on IntegriCloud