Module Name: src
Committed By: rmind
Date: Sat Apr 21 22:22:48 UTC 2012
Modified Files:
src/sys/arch/x86/x86: pmap_tlb.c
Log Message:
- pmap_tlb_shootdown: do not overwrite tp_cpumask with pm_cpus, but merge
like pm_kernel_cpus. Remove unecessary intersection with kcpuset_running.
Do not reset tp_userpmap if pmap_kernel().
- Remove pmap_tlb_mailbox_t wrapping, which is pointless after recent changes.
- pmap_tlb_invalidate, pmap_tlb_intr: constify for packet structure.
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x86/x86/pmap_tlb.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/x86/x86/pmap_tlb.c
diff -u src/sys/arch/x86/x86/pmap_tlb.c:1.5 src/sys/arch/x86/x86/pmap_tlb.c:1.6
--- src/sys/arch/x86/x86/pmap_tlb.c:1.5 Fri Apr 20 22:23:24 2012
+++ src/sys/arch/x86/x86/pmap_tlb.c Sat Apr 21 22:22:48 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap_tlb.c,v 1.5 2012/04/20 22:23:24 rmind Exp $ */
+/* $NetBSD: pmap_tlb.c,v 1.6 2012/04/21 22:22:48 rmind Exp $ */
/*-
* Copyright (c) 2008-2012 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap_tlb.c,v 1.5 2012/04/20 22:23:24 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap_tlb.c,v 1.6 2012/04/21 22:22:48 rmind Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -77,17 +77,13 @@ typedef struct {
/* No more than N seperate invlpg. */
#define TP_MAXVA 6
-typedef struct {
- volatile u_int tm_pendcount;
- volatile u_int tm_gen;
-} pmap_tlb_mailbox_t;
-
/*
* TLB shootdown state.
*/
-static struct evcnt pmap_tlb_evcnt __cacheline_aligned;
static pmap_tlb_packet_t pmap_tlb_packet __cacheline_aligned;
-static pmap_tlb_mailbox_t pmap_tlb_mailbox __cacheline_aligned;
+static volatile u_int pmap_tlb_pendcount __cacheline_aligned;
+static volatile u_int pmap_tlb_gen __cacheline_aligned;
+static struct evcnt pmap_tlb_evcnt __cacheline_aligned;
/*
* TLB shootdown statistics.
@@ -121,7 +117,8 @@ pmap_tlb_init(void)
{
memset(&pmap_tlb_packet, 0, sizeof(pmap_tlb_packet_t));
- memset(&pmap_tlb_mailbox, 0, sizeof(pmap_tlb_mailbox_t));
+ pmap_tlb_pendcount = 0;
+ pmap_tlb_gen = 0;
evcnt_attach_dynamic(&pmap_tlb_evcnt, EVCNT_TYPE_INTR,
NULL, "TLB", "shootdown");
@@ -189,7 +186,7 @@ pmap_tlbstat_count(struct pmap *pm, vadd
}
static inline void
-pmap_tlb_invalidate(pmap_tlb_packet_t *tp)
+pmap_tlb_invalidate(const pmap_tlb_packet_t *tp)
{
int i;
@@ -261,15 +258,13 @@ pmap_tlb_shootdown(struct pmap *pm, vadd
}
if (pm != pmap_kernel()) {
- kcpuset_copy(tp->tp_cpumask, pm->pm_cpus);
+ kcpuset_merge(tp->tp_cpumask, pm->pm_cpus);
if (va >= VM_MAXUSER_ADDRESS) {
kcpuset_merge(tp->tp_cpumask, pm->pm_kernel_cpus);
}
- kcpuset_intersect(tp->tp_cpumask, kcpuset_running);
tp->tp_userpmap = 1;
} else {
kcpuset_copy(tp->tp_cpumask, kcpuset_running);
- tp->tp_userpmap = 0;
}
pmap_tlbstat_count(pm, va, why);
splx(s);
@@ -281,7 +276,6 @@ pmap_tlb_shootdown(struct pmap *pm, vadd
static inline void
pmap_tlb_processpacket(pmap_tlb_packet_t *tp, kcpuset_t *target)
{
- pmap_tlb_mailbox_t *tm = &pmap_tlb_mailbox;
if (tp->tp_count != (uint16_t)-1) {
/* Invalidating a single page or a range of pages. */
@@ -293,7 +287,7 @@ pmap_tlb_processpacket(pmap_tlb_packet_t
}
/* Remote CPUs have been synchronously flushed. */
- tm->tm_pendcount = 0;
+ pmap_tlb_pendcount = 0;
}
#else
@@ -337,7 +331,6 @@ void
pmap_tlb_shootnow(void)
{
pmap_tlb_packet_t *tp;
- pmap_tlb_mailbox_t *tm;
struct cpu_info *ci;
kcpuset_t *target;
u_int local, gen, rcpucount;
@@ -359,7 +352,6 @@ pmap_tlb_shootnow(void)
splx(s);
return;
}
- tm = &pmap_tlb_mailbox;
cid = cpu_index(ci);
target = tp->tp_cpumask;
@@ -378,11 +370,11 @@ pmap_tlb_shootnow(void)
*/
KASSERT(rcpucount < ncpu);
- while (atomic_cas_uint(&tm->tm_pendcount, 0, rcpucount) != 0) {
+ while (atomic_cas_uint(&pmap_tlb_pendcount, 0, rcpucount)) {
splx(s);
count = SPINLOCK_BACKOFF_MIN;
- while (tm->tm_pendcount != 0) {
- KASSERT(tm->tm_pendcount < ncpu);
+ while (pmap_tlb_pendcount) {
+ KASSERT(pmap_tlb_pendcount < ncpu);
SPINLOCK_BACKOFF(count);
}
s = splvm();
@@ -395,9 +387,10 @@ pmap_tlb_shootnow(void)
/*
* Start a new generation of updates. Copy our shootdown
- * requests into the global buffer.
+ * requests into the global buffer. Note that tp_cpumask
+ * will not be used by remote CPUs (it would be unsafe).
*/
- gen = ++tm->tm_gen;
+ gen = ++pmap_tlb_gen;
memcpy(&pmap_tlb_packet, tp, sizeof(*tp));
pmap_tlb_evcnt.ev_count++;
@@ -434,11 +427,11 @@ pmap_tlb_shootnow(void)
* Now wait for the current generation of updates to be
* processed by remote CPUs.
*/
- if (rcpucount && tm->tm_pendcount) {
+ if (rcpucount && pmap_tlb_pendcount) {
int count = SPINLOCK_BACKOFF_MIN;
- while (tm->tm_pendcount && tm->tm_gen == gen) {
- KASSERT(tm->tm_pendcount < ncpu);
+ while (pmap_tlb_pendcount && pmap_tlb_gen == gen) {
+ KASSERT(pmap_tlb_pendcount < ncpu);
SPINLOCK_BACKOFF(count);
}
}
@@ -452,12 +445,10 @@ pmap_tlb_shootnow(void)
void
pmap_tlb_intr(void)
{
- pmap_tlb_packet_t *tp = &pmap_tlb_packet;
- pmap_tlb_mailbox_t *tm = &pmap_tlb_mailbox;
+ const pmap_tlb_packet_t *tp = &pmap_tlb_packet;
struct cpu_info *ci = curcpu();
- cpuid_t cid = cpu_index(ci);
- KASSERT(tm->tm_pendcount > 0);
+ KASSERT(pmap_tlb_pendcount > 0);
/* First, TLB flush. */
pmap_tlb_invalidate(tp);
@@ -469,11 +460,12 @@ pmap_tlb_intr(void)
*/
if (ci->ci_tlbstate == TLBSTATE_LAZY && tp->tp_userpmap) {
struct pmap *pm = ci->ci_pmap;
+ cpuid_t cid = cpu_index(ci);
kcpuset_atomic_clear(pm->pm_cpus, cid);
ci->ci_tlbstate = TLBSTATE_STALE;
}
/* Finally, ack the request. */
- atomic_dec_uint(&tm->tm_pendcount);
+ atomic_dec_uint(&pmap_tlb_pendcount);
}