Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src change uvm_uarea_alloc() to indicate whether the returned ua...
details: https://anonhg.NetBSD.org/src/rev/69a9d6e80eb2
branches: trunk
changeset: 539457:69a9d6e80eb2
user: chs <chs%NetBSD.org@localhost>
date: Sun Nov 17 08:32:43 2002 +0000
description:
change uvm_uarea_alloc() to indicate whether the returned uarea is already
backed by physical pages (ie. because it reused a previously-freed one),
so that we can skip a bunch of useless work in that case.
this fixes the underlying problem behind PR 18543, and also speeds up fork()
quite a bit (eg. 7% on my pc, 1% on my ultra2) when we get a cache hit.
diffstat:
share/man/man9/uvm.9 | 17 +++++++++++------
sys/arch/arm/arm32/cpu.c | 15 ++++++++-------
sys/kern/kern_fork.c | 11 ++++++-----
sys/kern/kern_kthread.c | 6 +++---
sys/uvm/uvm_extern.h | 4 ++--
sys/uvm/uvm_glue.c | 33 ++++++++++++++++++++-------------
6 files changed, 50 insertions(+), 36 deletions(-)
diffs (240 lines):
diff -r dfe5cda6a9d8 -r 69a9d6e80eb2 share/man/man9/uvm.9
--- a/share/man/man9/uvm.9 Sun Nov 17 07:21:11 2002 +0000
+++ b/share/man/man9/uvm.9 Sun Nov 17 08:32:43 2002 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: uvm.9,v 1.36 2002/09/27 07:52:48 wiz Exp $
+.\" $NetBSD: uvm.9,v 1.37 2002/11/17 08:32:44 chs Exp $
.\"
.\" Copyright (c) 1998 Matthew R. Green
.\" All rights reserved.
@@ -133,10 +133,10 @@
.Fn uvmspace_share "struct proc *p1" "struct proc *p2"
.Ft void
.Fn uvmspace_unshare "struct proc *p"
-.Ft vaddr_t
-.Fn uvm_uarea_alloc "void"
+.Ft boolean_t
+.Fn uvm_uarea_alloc "vaddr_t *uaddrp"
.Ft void
-.Fn uvm_uarea_free "vaddr_t va"
+.Fn uvm_uarea_free "vaddr_t uaddr"
.nr nS 0
.Pp
.Fn uvm_map
@@ -359,8 +359,13 @@
.Fn uvmspace_fork .
.Pp
.Fn uvm_uarea_alloc
-allocates virtual space for a u-area (i.e., a kernel stack) and returns
-its virtual address.
+allocates virtual space for a u-area (i.e., a kernel stack) and stores
+its virtual address in
+.Fa *uaddrp .
+The return value is
+.Dv TRUE
+if the u-area is already backed by wired physical memory, otherwise
+.Dv FALSE .
.Pp
.Fn uvm_uarea_free
frees a u-area allocated with
diff -r dfe5cda6a9d8 -r 69a9d6e80eb2 sys/arch/arm/arm32/cpu.c
--- a/sys/arch/arm/arm32/cpu.c Sun Nov 17 07:21:11 2002 +0000
+++ b/sys/arch/arm/arm32/cpu.c Sun Nov 17 08:32:43 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.45 2002/10/13 21:14:28 chris Exp $ */
+/* $NetBSD: cpu.c,v 1.46 2002/11/17 08:32:43 chs Exp $ */
/*
* Copyright (c) 1995 Mark Brinicombe.
@@ -45,7 +45,7 @@
#include <sys/param.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.45 2002/10/13 21:14:28 chris Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.46 2002/11/17 08:32:43 chs Exp $");
#include <sys/systm.h>
#include <sys/malloc.h>
@@ -527,11 +527,12 @@
* Generate a kernel stack and PCB (in essence, a u-area) for the
* new CPU.
*/
- uaddr = uvm_uarea_alloc();
- error = uvm_fault_wire(kernel_map, uaddr, uaddr + USPACE,
- VM_FAULT_WIRE, VM_PROT_READ | VM_PROT_WRITE);
- if (error)
- return error;
+ if (uvm_uarea_alloc(&uaddr)) {
+ error = uvm_fault_wire(kernel_map, uaddr, uaddr + USPACE,
+ VM_FAULT_WIRE, VM_PROT_READ | VM_PROT_WRITE);
+ if (error)
+ return error;
+ }
ci->ci_idlepcb = pcb = (struct pcb *)uaddr;
/*
diff -r dfe5cda6a9d8 -r 69a9d6e80eb2 sys/kern/kern_fork.c
--- a/sys/kern/kern_fork.c Sun Nov 17 07:21:11 2002 +0000
+++ b/sys/kern/kern_fork.c Sun Nov 17 08:32:43 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_fork.c,v 1.98 2002/11/13 00:51:02 provos Exp $ */
+/* $NetBSD: kern_fork.c,v 1.99 2002/11/17 08:32:44 chs Exp $ */
/*-
* Copyright (c) 1999, 2001 The NetBSD Foundation, Inc.
@@ -78,7 +78,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.98 2002/11/13 00:51:02 provos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.99 2002/11/17 08:32:44 chs Exp $");
#include "opt_ktrace.h"
#include "opt_systrace.h"
@@ -198,6 +198,7 @@
uid_t uid;
int count, s;
vaddr_t uaddr;
+ boolean_t inmem;
static int nextpid, pidchecked;
/*
@@ -231,10 +232,10 @@
* Allocate virtual address space for the U-area now, while it
* is still easy to abort the fork operation if we're out of
* kernel virtual address space. The actual U-area pages will
- * be allocated and wired in uvm_fork().
+ * be allocated and wired in uvm_fork() if needed.
*/
- uaddr = uvm_uarea_alloc();
+ inmem = uvm_uarea_alloc(&uaddr);
if (__predict_false(uaddr == 0)) {
(void)chgproccnt(uid, -1);
nprocs--;
@@ -280,7 +281,7 @@
* Increase reference counts on shared objects.
* The p_stats and p_sigacts substructs are set in uvm_fork().
*/
- p2->p_flag = P_INMEM | (p1->p_flag & P_SUGID);
+ p2->p_flag = (inmem ? P_INMEM : 0) | (p1->p_flag & P_SUGID);
p2->p_emul = p1->p_emul;
p2->p_execsw = p1->p_execsw;
diff -r dfe5cda6a9d8 -r 69a9d6e80eb2 sys/kern/kern_kthread.c
--- a/sys/kern/kern_kthread.c Sun Nov 17 07:21:11 2002 +0000
+++ b/sys/kern/kern_kthread.c Sun Nov 17 08:32:43 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_kthread.c,v 1.13 2002/06/01 23:51:05 lukem Exp $ */
+/* $NetBSD: kern_kthread.c,v 1.14 2002/11/17 08:32:44 chs Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.13 2002/06/01 23:51:05 lukem Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.14 2002/11/17 08:32:44 chs Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -82,7 +82,7 @@
* to init(8) when they exit. init(8) can easily wait them
* out for us.
*/
- p2->p_flag |= P_INMEM | P_SYSTEM | P_NOCLDWAIT; /* XXX */
+ p2->p_flag |= P_SYSTEM | P_NOCLDWAIT;
/* Name it as specified. */
va_start(ap, fmt);
diff -r dfe5cda6a9d8 -r 69a9d6e80eb2 sys/uvm/uvm_extern.h
--- a/sys/uvm/uvm_extern.h Sun Nov 17 07:21:11 2002 +0000
+++ b/sys/uvm/uvm_extern.h Sun Nov 17 08:32:43 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_extern.h,v 1.73 2002/09/22 07:20:31 chs Exp $ */
+/* $NetBSD: uvm_extern.h,v 1.74 2002/11/17 08:32:45 chs Exp $ */
/*
*
@@ -572,7 +572,7 @@
boolean_t uvm_kernacc __P((caddr_t, size_t, int));
__dead void uvm_scheduler __P((void)) __attribute__((noreturn));
void uvm_swapin __P((struct proc *));
-vaddr_t uvm_uarea_alloc(void);
+boolean_t uvm_uarea_alloc(vaddr_t *);
void uvm_uarea_free(vaddr_t);
boolean_t uvm_useracc __P((caddr_t, size_t, int));
int uvm_vslock __P((struct proc *, caddr_t, size_t,
diff -r dfe5cda6a9d8 -r 69a9d6e80eb2 sys/uvm/uvm_glue.c
--- a/sys/uvm/uvm_glue.c Sun Nov 17 07:21:11 2002 +0000
+++ b/sys/uvm/uvm_glue.c Sun Nov 17 08:32:43 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_glue.c,v 1.60 2002/09/22 07:20:32 chs Exp $ */
+/* $NetBSD: uvm_glue.c,v 1.61 2002/11/17 08:32:45 chs Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_glue.c,v 1.60 2002/09/22 07:20:32 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_glue.c,v 1.61 2002/11/17 08:32:45 chs Exp $");
#include "opt_kgdb.h"
#include "opt_kstack.h"
@@ -290,15 +290,20 @@
* Wire down the U-area for the process, which contains the PCB
* and the kernel stack. Wired state is stored in p->p_flag's
* P_INMEM bit rather than in the vm_map_entry's wired count
- * to prevent kernel_map fragmentation.
+ * to prevent kernel_map fragmentation. If we reused a cached U-area,
+ * P_INMEM will already be set and we don't need to do anything.
*
- * Note the kernel stack gets read/write accesses right off
- * the bat.
+ * Note the kernel stack gets read/write accesses right off the bat.
*/
- error = uvm_fault_wire(kernel_map, (vaddr_t)up, (vaddr_t)up + USPACE,
- VM_FAULT_WIRE, VM_PROT_READ | VM_PROT_WRITE);
- if (error)
- panic("uvm_fork: uvm_fault_wire failed: %d", error);
+
+ if ((p2->p_flag & P_INMEM) == 0) {
+ error = uvm_fault_wire(kernel_map, (vaddr_t)up,
+ (vaddr_t)up + USPACE, VM_FAULT_WIRE,
+ VM_PROT_READ | VM_PROT_WRITE);
+ if (error)
+ panic("uvm_fork: uvm_fault_wire failed: %d", error);
+ p2->p_flag |= P_INMEM;
+ }
#ifdef KSTACK_CHECK_MAGIC
/*
@@ -354,8 +359,8 @@
* uvm_uarea_alloc: allocate a u-area
*/
-vaddr_t
-uvm_uarea_alloc(void)
+boolean_t
+uvm_uarea_alloc(vaddr_t *uaddrp)
{
vaddr_t uaddr;
@@ -367,10 +372,12 @@
if (uaddr) {
uvm_uareas = *(void **)uvm_uareas;
uvm_nuarea--;
+ *uaddrp = uaddr;
+ return TRUE;
} else {
- uaddr = uvm_km_valloc_align(kernel_map, USPACE, USPACE_ALIGN);
+ *uaddrp = uvm_km_valloc_align(kernel_map, USPACE, USPACE_ALIGN);
+ return FALSE;
}
- return uaddr;
}
/*
Home |
Main Index |
Thread Index |
Old Index