Wed Mar 7 23:23:51 2012 UTC ()
Pull up following revision(s) (requested by reinoud in ticket #78):
	sys/arch/usermode/usermode/pmap.c: revision 1.103
Move from pool(9) to kmem_zalloc(9) for L2 page tables. A pool with PAGE_SIZE
elements is accepted but seems to panic now and then claiming it can't find
the header info.
XXX should this be PR'd?


(riz)
diff -r1.102 -r1.102.2.1 src/sys/arch/usermode/usermode/pmap.c

cvs diff -r1.102 -r1.102.2.1 src/sys/arch/usermode/usermode/pmap.c (expand / switch to unified diff)

--- src/sys/arch/usermode/usermode/pmap.c 2012/01/14 17:42:52 1.102
+++ src/sys/arch/usermode/usermode/pmap.c 2012/03/07 23:23:50 1.102.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pmap.c,v 1.102 2012/01/14 17:42:52 reinoud Exp $ */ 1/* $NetBSD: pmap.c,v 1.102.2.1 2012/03/07 23:23:50 riz Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Reinoud Zandijk <reinoud@NetBSD.org> 4 * Copyright (c) 2011 Reinoud Zandijk <reinoud@NetBSD.org>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,36 +17,37 @@ @@ -17,36 +17,37 @@
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.102 2012/01/14 17:42:52 reinoud Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.102.2.1 2012/03/07 23:23:50 riz Exp $");
31 31
32#include "opt_memsize.h" 32#include "opt_memsize.h"
33#include "opt_kmempages.h" 33#include "opt_kmempages.h"
34#include "opt_misc.h" 34#include "opt_misc.h"
35 35
36#include <sys/types.h> 36#include <sys/types.h>
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/mutex.h> 38#include <sys/mutex.h>
39#include <sys/buf.h> 39#include <sys/buf.h>
 40#include <sys/kmem.h>
40#include <sys/malloc.h> 41#include <sys/malloc.h>
41#include <sys/pool.h> 42#include <sys/pool.h>
42#include <machine/thunk.h> 43#include <machine/thunk.h>
43#include <machine/machdep.h> 44#include <machine/machdep.h>
44#include <machine/pcb.h> 45#include <machine/pcb.h>
45 46
46#include <uvm/uvm.h> 47#include <uvm/uvm.h>
47 48
48struct pv_entry { 49struct pv_entry {
49 struct pv_entry *pv_next; 50 struct pv_entry *pv_next;
50 pmap_t pv_pmap; 51 pmap_t pv_pmap;
51 uintptr_t pv_ppn; /* physical page number */ 52 uintptr_t pv_ppn; /* physical page number */
52 uintptr_t pv_lpn; /* logical page number */ 53 uintptr_t pv_lpn; /* logical page number */
@@ -85,27 +86,26 @@ struct pmap * const kernel_pmap_ptr = & @@ -85,27 +86,26 @@ struct pmap * const kernel_pmap_ptr = &
85static pmap_t active_pmap = NULL; 86static pmap_t active_pmap = NULL;
86 87
87static char mem_name[20] = ""; 88static char mem_name[20] = "";
88static int mem_fh; 89static int mem_fh;
89 90
90static int phys_npages = 0; 91static int phys_npages = 0;
91static int pm_nentries = 0; 92static int pm_nentries = 0;
92static int pm_nl1 = 0; 93static int pm_nl1 = 0;
93static int pm_l1_size = 0; 94static int pm_l1_size = 0;
94static uint64_t pm_entries_size = 0; 95static uint64_t pm_entries_size = 0;
95 96
96static struct pool pmap_pool; 97static struct pool pmap_pool;
97static struct pool pmap_l1_pool; 98static struct pool pmap_l1_pool;
98static struct pool pmap_l2_pool; 
99static struct pool pmap_pventry_pool; 99static struct pool pmap_pventry_pool;
100 100
101/* forwards */ 101/* forwards */
102void pmap_bootstrap(void); 102void pmap_bootstrap(void);
103static void pmap_page_activate(struct pv_entry *pv); 103static void pmap_page_activate(struct pv_entry *pv);
104static void pmap_page_deactivate(struct pv_entry *pv); 104static void pmap_page_deactivate(struct pv_entry *pv);
105static void pv_update(struct pv_entry *pv); 105static void pv_update(struct pv_entry *pv);
106static void pmap_update_page(uintptr_t ppn); 106static void pmap_update_page(uintptr_t ppn);
107bool pmap_fault(pmap_t pmap, vaddr_t va, vm_prot_t *atype); 107bool pmap_fault(pmap_t pmap, vaddr_t va, vm_prot_t *atype);
108 108
109static struct pv_entry *pv_get(pmap_t pmap, uintptr_t ppn, uintptr_t lpn); 109static struct pv_entry *pv_get(pmap_t pmap, uintptr_t ppn, uintptr_t lpn);
110static struct pv_entry *pv_alloc(void); 110static struct pv_entry *pv_alloc(void);
111static void pv_free(struct pv_entry *pv); 111static void pv_free(struct pv_entry *pv);
@@ -441,28 +441,26 @@ pmap_virtual_space(vaddr_t *vstartp, vad @@ -441,28 +441,26 @@ pmap_virtual_space(vaddr_t *vstartp, vad
441 *vstartp = kmem_kvm_cur_start; /* min to map in */ 441 *vstartp = kmem_kvm_cur_start; /* min to map in */
442 if (vendp) 442 if (vendp)
443 *vendp = kmem_kvm_end - PAGE_SIZE; /* max available */ 443 *vendp = kmem_kvm_end - PAGE_SIZE; /* max available */
444} 444}
445 445
446static void 446static void
447pmap_deferred_init(void) 447pmap_deferred_init(void)
448{ 448{
449 /* XXX we COULD realloc our pv_table etc with malloc() but for what? */ 449 /* XXX we COULD realloc our pv_table etc with malloc() but for what? */
450 450
451 /* create pmap pool */ 451 /* create pmap pool */
452 pool_init(&pmap_pool, sizeof(struct pmap), 0, 0, 0, 452 pool_init(&pmap_pool, sizeof(struct pmap), 0, 0, 0,
453 "pmappool", NULL, IPL_NONE); 453 "pmappool", NULL, IPL_NONE);
454 pool_init(&pmap_l2_pool, PMAP_L2_SIZE, 0, 0, 0, 
455 "pmapl2pool", NULL, IPL_HIGH); 
456 pool_init(&pmap_l1_pool, pm_l1_size, 0, 0, 0, 454 pool_init(&pmap_l1_pool, pm_l1_size, 0, 0, 0,
457 "pmapl1pool", NULL, IPL_NONE); 455 "pmapl1pool", NULL, IPL_NONE);
458 pool_init(&pmap_pventry_pool, sizeof(struct pv_entry), 0, 0, 0, 456 pool_init(&pmap_pventry_pool, sizeof(struct pv_entry), 0, 0, 0,
459 "pventry", NULL, IPL_HIGH); 457 "pventry", NULL, IPL_HIGH);
460} 458}
461 459
462pmap_t 460pmap_t
463pmap_create(void) 461pmap_create(void)
464{ 462{
465 static int pmap_initialised = 0; 463 static int pmap_initialised = 0;
466 struct pmap *pmap; 464 struct pmap *pmap;
467 465
468 if (!pmap_initialised) { 466 if (!pmap_initialised) {
@@ -519,27 +517,27 @@ pmap_destroy(pmap_t pmap) @@ -519,27 +517,27 @@ pmap_destroy(pmap_t pmap)
519 l2tbl = pmap->pm_l1[l1]; 517 l2tbl = pmap->pm_l1[l1];
520 if (!l2tbl) 518 if (!l2tbl)
521 continue; 519 continue;
522 for (l2 = 0; l2 < PMAP_L2_NENTRY; l2++) { 520 for (l2 = 0; l2 < PMAP_L2_NENTRY; l2++) {
523 if (l2tbl->pm_l2[l2]) 521 if (l2tbl->pm_l2[l2])
524 panic("pmap_destroy: pmap isn't empty"); 522 panic("pmap_destroy: pmap isn't empty");
525 } 523 }
526 } 524 }
527#endif 525#endif
528 for (l1 = 0; l1 < pm_nl1; l1++) { 526 for (l1 = 0; l1 < pm_nl1; l1++) {
529 l2tbl = pmap->pm_l1[l1]; 527 l2tbl = pmap->pm_l1[l1];
530 if (!l2tbl) 528 if (!l2tbl)
531 continue; 529 continue;
532 pool_put(&pmap_l2_pool, l2tbl); 530 kmem_free(l2tbl, PMAP_L2_SIZE);
533 } 531 }
534 pool_put(&pmap_l1_pool, pmap->pm_l1); 532 pool_put(&pmap_l1_pool, pmap->pm_l1);
535 pool_put(&pmap_pool, pmap); 533 pool_put(&pmap_pool, pmap);
536} 534}
537 535
538void 536void
539pmap_reference(pmap_t pmap) 537pmap_reference(pmap_t pmap)
540{ 538{
541 thunk_printf_debug("pmap_reference %p\n", (void *) pmap); 539 thunk_printf_debug("pmap_reference %p\n", (void *) pmap);
542 pmap->pm_count++; 540 pmap->pm_count++;
543} 541}
544 542
545long 543long
@@ -613,28 +611,28 @@ pmap_set_pv(pmap_t pmap, uintptr_t lpn,  @@ -613,28 +611,28 @@ pmap_set_pv(pmap_t pmap, uintptr_t lpn,
613{ 611{
614 struct pmap_l2 *l2tbl; 612 struct pmap_l2 *l2tbl;
615 int l1 = lpn / PMAP_L2_NENTRY; 613 int l1 = lpn / PMAP_L2_NENTRY;
616 int l2 = lpn % PMAP_L2_NENTRY; 614 int l2 = lpn % PMAP_L2_NENTRY;
617 615
618#ifdef DIAGNOSTIC 616#ifdef DIAGNOSTIC
619 if (lpn >= pm_nentries) 617 if (lpn >= pm_nentries)
620 panic("peeing outside box : addr in page around %"PRIx64"\n", 618 panic("peeing outside box : addr in page around %"PRIx64"\n",
621 (uint64_t) lpn*PAGE_SIZE); 619 (uint64_t) lpn*PAGE_SIZE);
622#endif 620#endif
623 621
624 l2tbl = pmap->pm_l1[l1]; 622 l2tbl = pmap->pm_l1[l1];
625 if (!l2tbl) { 623 if (!l2tbl) {
626 l2tbl = pmap->pm_l1[l1] = pool_get(&pmap_l2_pool, PR_WAITOK); 624 l2tbl = pmap->pm_l1[l1] = kmem_zalloc(PMAP_L2_SIZE, KM_SLEEP);
627 memset(l2tbl, 0, PMAP_L2_SIZE); 625 /* should be zero filled */
628 } 626 }
629 l2tbl->pm_l2[l2] = pv; 627 l2tbl->pm_l2[l2] = pv;
630} 628}
631 629
632static struct pv_entry * 630static struct pv_entry *
633pmap_lookup_pv(pmap_t pmap, uintptr_t lpn) 631pmap_lookup_pv(pmap_t pmap, uintptr_t lpn)
634{ 632{
635 struct pmap_l2 *l2tbl; 633 struct pmap_l2 *l2tbl;
636 int l1 = lpn / PMAP_L2_NENTRY; 634 int l1 = lpn / PMAP_L2_NENTRY;
637 int l2 = lpn % PMAP_L2_NENTRY; 635 int l2 = lpn % PMAP_L2_NENTRY;
638 636
639 if (lpn >= pm_nentries) 637 if (lpn >= pm_nentries)
640 return NULL; 638 return NULL;