Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/alpha - Centralize per-CPU pmap initialization into...
details: https://anonhg.NetBSD.org/src/rev/655e7229b83f
branches: trunk
changeset: 943288:655e7229b83f
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sat Aug 29 20:06:59 2020 +0000
description:
- Centralize per-CPU pmap initialization into a new pmap_init_cpu()
function. Call in from pmap_bootstrap() for the boot CPU, and
from cpu_hatch() for secondaary CPUs.
- Eliminiate the dedicated I-stream memory barrier IPI; handle it all from
the TLB shootdown IPI. Const poison, and add some additional memory
barriers and a TBIA to the PAUSE IPI.
- Completly rewrite TLB management in the alpha pmap module, borrowing
somoe ideas from the x86 pmap and adapting them to the alpha environment.
See the comments for theory of operation. Add a bunch of stats that
can be reported (disabled by default).
- Add some additional symbol decorations to improve cache behavior on
MP systems. Ensure coherency unit alignment for several structures
in the pmap module. Use hashed locks for pmap structures.
- Start out all new processes on the kernel page tables until their
first trip though pmap_activate() to avoid the potential of polluting
the current ASN in TLB with cross-process mappings.
diffstat:
sys/arch/alpha/alpha/cpu.c | 8 +-
sys/arch/alpha/alpha/ipifuncs.c | 65 +-
sys/arch/alpha/alpha/pmap.c | 2275 ++++++++++++++++++++----------------
sys/arch/alpha/alpha/vm_machdep.c | 14 +-
sys/arch/alpha/include/cpu.h | 8 +-
sys/arch/alpha/include/intr.h | 13 +-
sys/arch/alpha/include/pmap.h | 65 +-
7 files changed, 1341 insertions(+), 1107 deletions(-)
diffs (truncated from 3635 to 300 lines):
diff -r 49f883360967 -r 655e7229b83f sys/arch/alpha/alpha/cpu.c
--- a/sys/arch/alpha/alpha/cpu.c Sat Aug 29 19:35:38 2020 +0000
+++ b/sys/arch/alpha/alpha/cpu.c Sat Aug 29 20:06:59 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.98 2020/08/07 14:20:08 fcambus Exp $ */
+/* $NetBSD: cpu.c,v 1.99 2020/08/29 20:06:59 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.98 2020/08/07 14:20:08 fcambus Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.99 2020/08/29 20:06:59 thorpej Exp $");
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
@@ -549,8 +549,8 @@
u_long cpu_id = cpu_number();
u_long cpumask = (1UL << cpu_id);
- /* Mark the kernel pmap active on this processor. */
- atomic_or_ulong(&pmap_kernel()->pm_cpus, cpumask);
+ /* pmap initialization for this processor. */
+ pmap_init_cpu(ci);
/* Initialize trap vectors for this processor. */
trap_init();
diff -r 49f883360967 -r 655e7229b83f sys/arch/alpha/alpha/ipifuncs.c
--- a/sys/arch/alpha/alpha/ipifuncs.c Sat Aug 29 19:35:38 2020 +0000
+++ b/sys/arch/alpha/alpha/ipifuncs.c Sat Aug 29 20:06:59 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ipifuncs.c,v 1.51 2020/08/15 16:09:07 thorpej Exp $ */
+/* $NetBSD: ipifuncs.c,v 1.52 2020/08/29 20:06:59 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.51 2020/08/15 16:09:07 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.52 2020/08/29 20:06:59 thorpej Exp $");
/*
* Interprocessor interrupt handlers.
@@ -62,21 +62,15 @@
static void alpha_ipi_halt(struct cpu_info *, struct trapframe *);
static void alpha_ipi_microset(struct cpu_info *, struct trapframe *);
-static void alpha_ipi_imb(struct cpu_info *, struct trapframe *);
static void alpha_ipi_ast(struct cpu_info *, struct trapframe *);
static void alpha_ipi_pause(struct cpu_info *, struct trapframe *);
static void alpha_ipi_xcall(struct cpu_info *, struct trapframe *);
static void alpha_ipi_generic(struct cpu_info *, struct trapframe *);
-/*
- * NOTE: This table must be kept in order with the bit definitions
- * in <machine/intr.h>.
- */
const ipifunc_t ipifuncs[ALPHA_NIPIS] = {
[ilog2(ALPHA_IPI_HALT)] = alpha_ipi_halt,
[ilog2(ALPHA_IPI_MICROSET)] = alpha_ipi_microset,
- [ilog2(ALPHA_IPI_SHOOTDOWN)] = pmap_do_tlb_shootdown,
- [ilog2(ALPHA_IPI_IMB)] = alpha_ipi_imb,
+ [ilog2(ALPHA_IPI_SHOOTDOWN)] = pmap_tlb_shootdown_ipi,
[ilog2(ALPHA_IPI_AST)] = alpha_ipi_ast,
[ilog2(ALPHA_IPI_PAUSE)] = alpha_ipi_pause,
[ilog2(ALPHA_IPI_XCALL)] = alpha_ipi_xcall,
@@ -87,7 +81,6 @@
[ilog2(ALPHA_IPI_HALT)] = "halt ipi",
[ilog2(ALPHA_IPI_MICROSET)] = "microset ipi",
[ilog2(ALPHA_IPI_SHOOTDOWN)] = "shootdown ipi",
- [ilog2(ALPHA_IPI_IMB)] = "imb ipi",
[ilog2(ALPHA_IPI_AST)] = "ast ipi",
[ilog2(ALPHA_IPI_PAUSE)] = "pause ipi",
[ilog2(ALPHA_IPI_XCALL)] = "xcall ipi",
@@ -156,7 +149,7 @@
* Send an interprocessor interrupt.
*/
void
-alpha_send_ipi(u_long cpu_id, u_long ipimask)
+alpha_send_ipi(u_long const cpu_id, u_long const ipimask)
{
KASSERT(cpu_id < hwrpb->rpb_pcs_cnt);
@@ -171,14 +164,13 @@
* Broadcast an IPI to all but ourselves.
*/
void
-alpha_broadcast_ipi(u_long ipimask)
+alpha_broadcast_ipi(u_long const ipimask)
{
struct cpu_info *ci;
CPU_INFO_ITERATOR cii;
- u_long cpu_id = cpu_number();
- u_long cpumask;
- cpumask = cpus_running & ~(1UL << cpu_id);
+ const u_long cpu_id = cpu_number();
+ const u_long cpumask = cpus_running & ~(1UL << cpu_id);
for (CPU_INFO_FOREACH(cii, ci)) {
if ((cpumask & (1UL << ci->ci_cpuid)) == 0)
@@ -191,7 +183,7 @@
* Send an IPI to all in the list but ourselves.
*/
void
-alpha_multicast_ipi(u_long cpumask, u_long ipimask)
+alpha_multicast_ipi(u_long cpumask, u_long const ipimask)
{
struct cpu_info *ci;
CPU_INFO_ITERATOR cii;
@@ -209,10 +201,11 @@
}
static void
-alpha_ipi_halt(struct cpu_info *ci, struct trapframe *framep)
+alpha_ipi_halt(struct cpu_info * const ci,
+ struct trapframe * const framep __unused)
{
- u_long cpu_id = ci->ci_cpuid;
- u_long wait_mask = (1UL << cpu_id);
+ const u_long cpu_id = ci->ci_cpuid;
+ const u_long wait_mask = (1UL << cpu_id);
/* Disable interrupts. */
(void) splhigh();
@@ -242,21 +235,16 @@
}
static void
-alpha_ipi_microset(struct cpu_info *ci, struct trapframe *framep)
+alpha_ipi_microset(struct cpu_info * const ci,
+ struct trapframe * const framep __unused)
{
cc_calibrate_cpu(ci);
}
static void
-alpha_ipi_imb(struct cpu_info *ci, struct trapframe *framep)
-{
-
- alpha_pal_imb();
-}
-
-static void
-alpha_ipi_ast(struct cpu_info *ci, struct trapframe *framep)
+alpha_ipi_ast(struct cpu_info * const ci,
+ struct trapframe * const framep __unused)
{
if (ci->ci_onproc != ci->ci_data.cpu_idlelwp)
@@ -264,16 +252,16 @@
}
static void
-alpha_ipi_pause(struct cpu_info *ci, struct trapframe *framep)
+alpha_ipi_pause(struct cpu_info * const ci, struct trapframe * const framep)
{
- u_long cpumask = (1UL << ci->ci_cpuid);
+ const u_long cpumask = (1UL << ci->ci_cpuid);
int s;
s = splhigh();
/* Point debuggers at our trapframe for register state. */
ci->ci_db_regs = framep;
-
+ alpha_wmb();
atomic_or_ulong(&ci->ci_flags, CPUF_PAUSED);
/* Spin with interrupts disabled until we're resumed. */
@@ -282,12 +270,13 @@
} while (cpus_paused & cpumask);
atomic_and_ulong(&ci->ci_flags, ~CPUF_PAUSED);
-
+ alpha_wmb();
ci->ci_db_regs = NULL;
splx(s);
- /* Do an IMB on the way out, in case the kernel text was changed. */
+ /* Do a TBIA+IMB on the way out, in case things have changed. */
+ ALPHA_TBIA();
alpha_pal_imb();
}
@@ -296,13 +285,14 @@
*/
static void
-alpha_ipi_xcall(struct cpu_info *ci, struct trapframe *framep)
+alpha_ipi_xcall(struct cpu_info * const ci __unused,
+ struct trapframe * const framep __unused)
{
xc_ipi_handler();
}
void
-xc_send_ipi(struct cpu_info *ci)
+xc_send_ipi(struct cpu_info * const ci)
{
KASSERT(kpreempt_disabled());
KASSERT(curcpu() != ci);
@@ -317,13 +307,14 @@
}
static void
-alpha_ipi_generic(struct cpu_info *ci, struct trapframe *framep)
+alpha_ipi_generic(struct cpu_info * const ci __unused,
+ struct trapframe * const framep __unused)
{
ipi_cpu_handler();
}
void
-cpu_ipi(struct cpu_info *ci)
+cpu_ipi(struct cpu_info * const ci)
{
KASSERT(kpreempt_disabled());
KASSERT(curcpu() != ci);
diff -r 49f883360967 -r 655e7229b83f sys/arch/alpha/alpha/pmap.c
--- a/sys/arch/alpha/alpha/pmap.c Sat Aug 29 19:35:38 2020 +0000
+++ b/sys/arch/alpha/alpha/pmap.c Sat Aug 29 20:06:59 2020 +0000
@@ -1,12 +1,14 @@
-/* $NetBSD: pmap.c,v 1.268 2020/08/17 00:57:37 thorpej Exp $ */
+/* $NetBSD: pmap.c,v 1.269 2020/08/29 20:06:59 thorpej Exp $ */
/*-
- * Copyright (c) 1998, 1999, 2000, 2001, 2007, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 1999, 2000, 2001, 2007, 2008, 2020
+ * The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
- * NASA Ames Research Center and by Chris G. Demetriou.
+ * NASA Ames Research Center, by Andrew Doran and Mindaugas Rasiukevicius,
+ * and by Chris G. Demetriou.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -93,26 +95,19 @@
* The locking protocol was written by Jason R. Thorpe,
* using Chuck Cranor's i386 pmap for UVM as a model.
*
- * TLB shootdown code was written by Jason R. Thorpe.
+ * TLB shootdown code was written (and then subsequently
+ * rewritten some years later, borrowing some ideas from
+ * the x86 pmap) by Jason R. Thorpe.
*
- * Multiprocessor modifications by Andrew Doran.
+ * Multiprocessor modifications by Andrew Doran and
+ * Jason R. Thorpe.
*
* Notes:
*
- * All page table access is done via K0SEG. The one exception
- * to this is for kernel mappings. Since all kernel page
- * tables are pre-allocated, we can use the Virtual Page Table
- * to access PTEs that map K1SEG addresses.
- *
- * Kernel page table pages are statically allocated in
- * pmap_bootstrap(), and are never freed. In the future,
- * support for dynamically adding additional kernel page
- * table pages may be added. User page table pages are
- * dynamically allocated and freed.
- *
- * Bugs/misfeatures:
- *
- * - Some things could be optimized.
+ * All user page table access is done via K0SEG. Kernel
+ * page table access is done via the recursive Virtual Page
+ * Table becase kernel PT pages are pre-allocated and never
+ * freed, so no VPT fault handling is requiried.
*/
/*
@@ -140,7 +135,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.268 2020/08/17 00:57:37 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.269 2020/08/29 20:06:59 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -149,6 +144,7 @@
#include <sys/malloc.h>
#include <sys/pool.h>
#include <sys/buf.h>
+#include <sys/evcnt.h>
#include <sys/atomic.h>
#include <sys/cpu.h>
@@ -178,12 +174,18 @@
Home |
Main Index |
Thread Index |
Old Index