Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/mips Change lockless segtab management to use a mut...
details: https://anonhg.NetBSD.org/src/rev/f56ea2bf813b
branches: trunk
changeset: 780002:f56ea2bf813b
user: matt <matt%NetBSD.org@localhost>
date: Thu Jul 05 17:21:02 2012 +0000
description:
Change lockless segtab management to use a mutex for protection. Some minor
changes to make this closer to common/pmap/tlb/pmap_segtab.c
diffstat:
sys/arch/mips/include/pmap.h | 3 +-
sys/arch/mips/mips/pmap.c | 21 +++++++----
sys/arch/mips/mips/pmap_segtab.c | 73 +++++++++++++++++----------------------
3 files changed, 47 insertions(+), 50 deletions(-)
diffs (219 lines):
diff -r 84ae09d67af5 -r f56ea2bf813b sys/arch/mips/include/pmap.h
--- a/sys/arch/mips/include/pmap.h Thu Jul 05 16:55:11 2012 +0000
+++ b/sys/arch/mips/include/pmap.h Thu Jul 05 17:21:02 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.61 2011/09/22 05:08:52 macallan Exp $ */
+/* $NetBSD: pmap.h,v 1.62 2012/07/05 17:21:02 matt Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -148,6 +148,7 @@
void pmap_segtab_activate(struct pmap *, struct lwp *);
void pmap_segtab_init(struct pmap *);
void pmap_segtab_destroy(struct pmap *);
+extern kmutex_t pmap_segtab_lock;
#endif /* _KERNEL */
/*
diff -r 84ae09d67af5 -r f56ea2bf813b sys/arch/mips/mips/pmap.c
--- a/sys/arch/mips/mips/pmap.c Thu Jul 05 16:55:11 2012 +0000
+++ b/sys/arch/mips/mips/pmap.c Thu Jul 05 17:21:02 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.207 2012/02/02 18:59:44 para Exp $ */
+/* $NetBSD: pmap.c,v 1.208 2012/07/05 17:21:02 matt Exp $ */
/*-
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.207 2012/02/02 18:59:44 para Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.208 2012/07/05 17:21:02 matt Exp $");
/*
* Manages physical address maps.
@@ -276,8 +276,8 @@
paddr_t mips_avail_start; /* PA of first available physical page */
paddr_t mips_avail_end; /* PA of last available physical page */
vaddr_t mips_virtual_end; /* VA of last avail page (end of kernel AS) */
-vaddr_t iospace; /* VA of start of I/O space, if needed */
-vsize_t iospace_size = 0; /* Size of (initial) range of I/O addresses */
+vaddr_t iospace; /* VA of start of I/O space, if needed */
+vsize_t iospace_size = 0; /* Size of (initial) range of I/O addresses */
pt_entry_t *Sysmap; /* kernel pte table */
unsigned int Sysmapsize; /* number of pte's in Sysmap */
@@ -739,6 +739,11 @@
#endif
/*
+ * Initialize the segtab lock.
+ */
+ mutex_init(&pmap_segtab_lock, MUTEX_DEFAULT, IPL_HIGH);
+
+ /*
* Set a low water mark on the pv_entry pool, so that we are
* more likely to have these around even in extreme memory
* starvation.
@@ -2108,11 +2113,11 @@
pv_entry_t pv, npv, apv;
int16_t gen;
- KASSERT(kpreempt_disabled());
- KASSERT(!MIPS_KSEG0_P(va));
- KASSERT(!MIPS_KSEG1_P(va));
+ KASSERT(kpreempt_disabled());
+ KASSERT(!MIPS_KSEG0_P(va));
+ KASSERT(!MIPS_KSEG1_P(va));
#ifdef _LP64
- KASSERT(!MIPS_XKPHYS_P(va));
+ KASSERT(!MIPS_XKPHYS_P(va));
#endif
apv = NULL;
diff -r 84ae09d67af5 -r f56ea2bf813b sys/arch/mips/mips/pmap_segtab.c
--- a/sys/arch/mips/mips/pmap_segtab.c Thu Jul 05 16:55:11 2012 +0000
+++ b/sys/arch/mips/mips/pmap_segtab.c Thu Jul 05 17:21:02 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap_segtab.c,v 1.4 2012/01/26 02:14:08 matt Exp $ */
+/* $NetBSD: pmap_segtab.c,v 1.5 2012/07/05 17:21:02 matt Exp $ */
/*-
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap_segtab.c,v 1.4 2012/01/26 02:14:08 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap_segtab.c,v 1.5 2012/07/05 17:21:02 matt Exp $");
/*
* Manages physical address maps.
@@ -119,13 +119,8 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
-#include <sys/pool.h>
#include <sys/mutex.h>
#include <sys/atomic.h>
-#ifdef SYSVSHM
-#include <sys/shm.h>
-#endif
-#include <sys/socketvar.h> /* XXX: for sock_loan_thresh */
#include <uvm/uvm.h>
@@ -136,15 +131,19 @@
CTASSERT(NBPG >= sizeof(union segtab));
-union segtab * volatile free_segtab; /* free list kept locally */
+struct pmap_segtab_info {
+ union segtab *free_segtab; /* free list kept locally */
#ifdef DEBUG
-uint32_t nget_segtab;
-uint32_t nput_segtab;
-uint32_t npage_segtab;
-#define SEGTAB_ADD(n, v) (n ## _segtab += (v))
+ uint32_t nget_segtab;
+ uint32_t nput_segtab;
+ uint32_t npage_segtab;
+#define SEGTAB_ADD(n, v) (pmap_segtab_info.n ## _segtab += (v))
#else
#define SEGTAB_ADD(n, v) ((void) 0)
#endif
+} pmap_segtab_info;
+
+kmutex_t pmap_segtab_lock __cacheline_aligned;
static inline struct vm_page *
pmap_pte_pagealloc(void)
@@ -184,14 +183,11 @@
/*
* Insert the the segtab into the segtab freelist.
*/
- for (;;) {
- void *tmp = free_segtab;
- stp->seg_tab[0] = tmp;
- if (tmp == atomic_cas_ptr(&free_segtab, tmp, stp)) {
- SEGTAB_ADD(nput, 1);
- break;
- }
- }
+ mutex_spin_enter(&pmap_segtab_lock);
+ stp->seg_tab[0] = (void *) pmap_segtab_info.free_segtab;
+ pmap_segtab_info.free_segtab = stp;
+ SEGTAB_ADD(nput, 1);
+ mutex_spin_exit(&pmap_segtab_lock);
}
static void
@@ -261,21 +257,18 @@
pmap_segtab_alloc(void)
{
union segtab *stp;
+
again:
- stp = NULL;
- while (__predict_true(free_segtab != NULL)) {
- union segtab *next_stp;
- stp = free_segtab;
- next_stp = (union segtab *)stp->seg_tab[0];
- if (stp == atomic_cas_ptr(&free_segtab, stp, next_stp)) {
- SEGTAB_ADD(nget, 1);
- break;
- }
+ mutex_spin_enter(&pmap_segtab_lock);
+ if (__predict_true((stp = pmap_segtab_info.free_segtab) != NULL)) {
+ pmap_segtab_info.free_segtab =
+ (union segtab *)stp->seg_tab[0];
+ stp->seg_tab[0] = NULL;
+ SEGTAB_ADD(nget, 1);
}
-
- if (__predict_true(stp != NULL)) {
- stp->seg_tab[0] = NULL;
- } else {
+ mutex_spin_exit(&pmap_segtab_lock);
+
+ if (__predict_false(stp == NULL)) {
struct vm_page * const stp_pg = pmap_pte_pagealloc();
if (__predict_false(stp_pg == NULL)) {
@@ -292,7 +285,7 @@
KASSERT(mips_options.mips3_xkphys_cached);
#endif
stp = (union segtab *)mips_pmap_map_poolpage(stp_pa);
- const size_t n = NBPG / sizeof(union segtab);
+ const size_t n = NBPG / sizeof(*stp);
if (n > 1) {
/*
* link all the segtabs in this page together
@@ -303,13 +296,11 @@
/*
* Now link the new segtabs into the free segtab list.
*/
- for (;;) {
- void *tmp = free_segtab;
- stp[n-1].seg_tab[0] = tmp;
- if (tmp == atomic_cas_ptr(&free_segtab, tmp, stp+1))
- break;
- }
+ mutex_spin_enter(&pmap_segtab_lock);
+ stp[n-1].seg_tab[0] = (void *)pmap_segtab_info.free_segtab;
+ pmap_segtab_info.free_segtab = stp + 1;
SEGTAB_ADD(nput, n - 1);
+ mutex_spin_exit(&pmap_segtab_lock);
}
}
@@ -433,7 +424,7 @@
union segtab *ostp = atomic_cas_ptr(stp_p, NULL, nstp);
if (__predict_false(ostp != NULL)) {
pmap_segtab_free(nstp);
- stp = ostp;
+ nstp = ostp;
}
#else
*stp_p = nstp;
Home |
Main Index |
Thread Index |
Old Index