From owner-freebsd-stable@FreeBSD.ORG Thu Aug 28 13:21:06 2003 Return-Path: Delivered-To: freebsd-stable@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 84C1F16A4BF for ; Thu, 28 Aug 2003 13:21:06 -0700 (PDT) Received: from cvsup.no.freebsd.org (c2h5oh.idi.ntnu.no [129.241.103.69]) by mx1.FreeBSD.org (Postfix) with ESMTP id 34BB143FDD for ; Thu, 28 Aug 2003 13:21:05 -0700 (PDT) (envelope-from Tor.Egge@cvsup.no.freebsd.org) Received: from localhost (localhost [127.0.0.1])h7SKL3Mb090710; Thu, 28 Aug 2003 20:21:03 GMT (envelope-from Tor.Egge@cvsup.no.freebsd.org) Date: Thu, 28 Aug 2003 20:20:11 +0000 (GMT) Message-Id: <20030828.202011.41715185.Tor.Egge@cvsup.no.freebsd.org> To: mike@sentex.net From: Tor Egge In-Reply-To: <5.2.0.9.0.20030828153925.03f3ed80@209.112.4.2> References: <20030827133126.D4269@odysseus.silby.com> <20030828.161240.74667710.Tor.Egge@cvsup.no.freebsd.org> <5.2.0.9.0.20030828153925.03f3ed80@209.112.4.2> X-Mailer: Mew version 2.2 on Emacs 20.7 / Mule 4.0 (HANANOEN) Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="--Next_Part(Thu_Aug_28_20:20:11_2003_868)--" Content-Transfer-Encoding: 7bit cc: silby@silby.com cc: stable@freebsd.org Subject: Re: Ok, are all the panics fixed now? X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Aug 2003 20:21:06 -0000 ----Next_Part(Thu_Aug_28_20:20:11_2003_868)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit > > Hi, > Forgive the naive question, but is this an easy issue to solve ? > Or is it just scratching the surface of a larger more complex problem not > easily resolved by a simple patch or two ? I'm enclosed a patch that introduces PADDR2/PMAP2 which is to be used by pmap_pte() (should not be called from interrupts on noncurrent pmaps) while pmap_pte_quick() (should not be called without splvm() protection) will use PADDR1/PMAP1. The patch also backs out revision 1.250.2.20 of src/sys/i386/i386/pmap.c. - Tor Egge ----Next_Part(Thu_Aug_28_20:20:11_2003_868)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="paefix.diff2" Index: sys/i386/i386/mp_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/mp_machdep.c,v retrieving revision 1.115.2.17 diff -u -r1.115.2.17 mp_machdep.c --- sys/i386/i386/mp_machdep.c 9 Aug 2003 16:21:18 -0000 1.115.2.17 +++ sys/i386/i386/mp_machdep.c 28 Aug 2003 20:05:38 -0000 @@ -2133,13 +2133,14 @@ /* allocate and set up an idle stack data page */ stack = (char *)kmem_alloc(kernel_map, UPAGES*PAGE_SIZE); for (i = 0; i < UPAGES; i++) - SMPpt[pg + 5 + i] = (pt_entry_t) + SMPpt[pg + 6 + i] = (pt_entry_t) (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); SMPpt[pg + 1] = 0; /* *prv_CMAP1 */ SMPpt[pg + 2] = 0; /* *prv_CMAP2 */ SMPpt[pg + 3] = 0; /* *prv_CMAP3 */ SMPpt[pg + 4] = 0; /* *prv_PMAP1 */ + SMPpt[pg + 5] = 0; /* *prv_PMAP2 */ /* prime data page for it to use */ gd->gd_cpuid = x; @@ -2148,10 +2149,12 @@ gd->gd_prv_CMAP2 = &SMPpt[pg + 2]; gd->gd_prv_CMAP3 = &SMPpt[pg + 3]; gd->gd_prv_PMAP1 = (pd_entry_t *)&SMPpt[pg + 4]; + gd->gd_prv_PMAP2 = (pd_entry_t *)&SMPpt[pg + 5]; gd->gd_prv_CADDR1 = SMP_prvspace[x].CPAGE1; gd->gd_prv_CADDR2 = SMP_prvspace[x].CPAGE2; gd->gd_prv_CADDR3 = SMP_prvspace[x].CPAGE3; gd->gd_prv_PADDR1 = (pt_entry_t *)SMP_prvspace[x].PPAGE1; + gd->gd_prv_PADDR2 = (pt_entry_t *)SMP_prvspace[x].PPAGE2; /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; @@ -2205,7 +2208,7 @@ /* Allocate and setup BSP idle stack */ stack = (char *)kmem_alloc(kernel_map, UPAGES * PAGE_SIZE); for (i = 0; i < UPAGES; i++) - SMPpt[5 + i] = (pt_entry_t) + SMPpt[6 + i] = (pt_entry_t) (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); for (x = 0; x < NKPT; x++) Index: sys/i386/i386/genassym.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/genassym.c,v retrieving revision 1.86.2.4 diff -u -r1.86.2.4 genassym.c --- sys/i386/i386/genassym.c 9 Aug 2003 16:21:17 -0000 1.86.2.4 +++ sys/i386/i386/genassym.c 28 Aug 2003 20:05:38 -0000 @@ -198,10 +198,12 @@ ASSYM(GD_PRV_CMAP2, offsetof(struct globaldata, gd_prv_CMAP2)); ASSYM(GD_PRV_CMAP3, offsetof(struct globaldata, gd_prv_CMAP3)); ASSYM(GD_PRV_PMAP1, offsetof(struct globaldata, gd_prv_PMAP1)); +ASSYM(GD_PRV_PMAP2, offsetof(struct globaldata, gd_prv_PMAP2)); ASSYM(GD_PRV_CADDR1, offsetof(struct globaldata, gd_prv_CADDR1)); ASSYM(GD_PRV_CADDR2, offsetof(struct globaldata, gd_prv_CADDR2)); ASSYM(GD_PRV_CADDR3, offsetof(struct globaldata, gd_prv_CADDR3)); ASSYM(GD_PRV_PADDR1, offsetof(struct globaldata, gd_prv_PADDR1)); +ASSYM(GD_PRV_PADDR2, offsetof(struct globaldata, gd_prv_PADDR2)); ASSYM(PS_IDLESTACK, offsetof(struct privatespace, idlestack)); ASSYM(PS_IDLESTACK_TOP, sizeof(struct privatespace)); #endif Index: sys/i386/i386/globals.s =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/Attic/globals.s,v retrieving revision 1.13.2.1 diff -u -r1.13.2.1 globals.s --- sys/i386/i386/globals.s 16 May 2000 06:58:06 -0000 1.13.2.1 +++ sys/i386/i386/globals.s 28 Aug 2003 20:05:38 -0000 @@ -109,7 +109,9 @@ .globl gd_cpuid, gd_cpu_lockid, gd_other_cpus .globl gd_ss_eflags, gd_inside_intr .globl gd_prv_CMAP1, gd_prv_CMAP2, gd_prv_CMAP3, gd_prv_PMAP1 + .globl gd_prv_PMAP2 .globl gd_prv_CADDR1, gd_prv_CADDR2, gd_prv_CADDR3, gd_prv_PADDR1 + .globl gd_prv_PADDR2 .set gd_cpuid,globaldata + GD_CPUID .set gd_cpu_lockid,globaldata + GD_CPU_LOCKID @@ -120,10 +122,12 @@ .set gd_prv_CMAP2,globaldata + GD_PRV_CMAP2 .set gd_prv_CMAP3,globaldata + GD_PRV_CMAP3 .set gd_prv_PMAP1,globaldata + GD_PRV_PMAP1 + .set gd_prv_PMAP2,globaldata + GD_PRV_PMAP2 .set gd_prv_CADDR1,globaldata + GD_PRV_CADDR1 .set gd_prv_CADDR2,globaldata + GD_PRV_CADDR2 .set gd_prv_CADDR3,globaldata + GD_PRV_CADDR3 .set gd_prv_PADDR1,globaldata + GD_PRV_PADDR1 + .set gd_prv_PADDR2,globaldata + GD_PRV_PADDR2 #endif #if defined(SMP) || defined(APIC_IO) Index: sys/i386/i386/pmap.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/pmap.c,v retrieving revision 1.250.2.20 diff -u -r1.250.2.20 pmap.c --- sys/i386/i386/pmap.c 26 Aug 2003 05:35:00 -0000 1.250.2.20 +++ sys/i386/i386/pmap.c 28 Aug 2003 20:05:38 -0000 @@ -114,6 +114,8 @@ #include #include +#include +#include #include #include #include @@ -215,15 +217,19 @@ #define CMAP2 prv_CMAP2 #define CMAP3 prv_CMAP3 #define PMAP1 prv_PMAP1 +#define PMAP2 prv_PMAP2 #define CADDR1 prv_CADDR1 #define CADDR2 prv_CADDR2 #define CADDR3 prv_CADDR3 #define PADDR1 prv_PADDR1 +#define PADDR2 prv_PADDR2 #else static pt_entry_t *CMAP1, *CMAP2, *CMAP3; static caddr_t CADDR1, CADDR2, CADDR3; static pd_entry_t *PMAP1; static pt_entry_t *PADDR1; +static pd_entry_t *PMAP2; +static pt_entry_t *PADDR2; #endif static pt_entry_t *ptmmap; @@ -257,6 +263,7 @@ static vm_page_t pmap_allocpte __P((pmap_t pmap, vm_offset_t va)); static vm_page_t _pmap_allocpte __P((pmap_t pmap, unsigned ptepindex)); +static pt_entry_t *pmap_pte_quick __P((pmap_t pmap, vm_offset_t va)); static vm_page_t pmap_page_lookup __P((vm_object_t object, vm_pindex_t pindex)); static int pmap_unuse_pt __P((pmap_t, vm_offset_t, vm_page_t)); static vm_offset_t pmap_kmem_choose(vm_offset_t addr); @@ -364,6 +371,7 @@ * ptemap is used for pmap_pte */ SYSMAP(pd_entry_t *, PMAP1, PADDR1, 1); + SYSMAP(pd_entry_t *, PMAP2, PADDR2, 1); #endif /* @@ -454,10 +462,12 @@ gd->gd_prv_CMAP2 = &SMPpt[2]; gd->gd_prv_CMAP3 = &SMPpt[3]; gd->gd_prv_PMAP1 = &SMPpt[4]; + gd->gd_prv_PMAP2 = &SMPpt[5]; gd->gd_prv_CADDR1 = SMP_prvspace[0].CPAGE1; gd->gd_prv_CADDR2 = SMP_prvspace[0].CPAGE2; gd->gd_prv_CADDR3 = SMP_prvspace[0].CPAGE3; gd->gd_prv_PADDR1 = (pt_entry_t *)SMP_prvspace[0].PPAGE1; + gd->gd_prv_PADDR2 = (pt_entry_t *)SMP_prvspace[0].PPAGE2; #endif invltlb(); @@ -663,13 +673,18 @@ * Function: * Extract the page table entry associated * with the given map/virtual_address pair. + * Note: Must be protected by splvm() */ -pt_entry_t * -pmap_pte(pmap_t pmap, vm_offset_t va) +static pt_entry_t * +pmap_pte_quick(pmap_t pmap, vm_offset_t va) { pd_entry_t *pde, newpf; +#ifdef INVARIANTS + if (~cpl & (net_imask | bio_imask | cam_imask)) + panic("pmap_pte_quick not protected by splvm()"); +#endif pde = pmap_pde(pmap, va); if (*pde & PG_V) { if (*pde & PG_PS) @@ -691,6 +706,44 @@ } /* + * Routine: pmap_pte + * Function: + * Extract the page table entry associated + * with the given map/virtual_address pair. + * Note: Must not be called from interrupts on non-current pmap + */ + +pt_entry_t * +pmap_pte(pmap_t pmap, vm_offset_t va) +{ + pd_entry_t *pde, newpf; + + pde = pmap_pde(pmap, va); + if (*pde & PG_V) { + if (*pde & PG_PS) + return (pt_entry_t *)pde; + if (pmap_is_current(pmap)) + return vtopte(va); +#ifdef INVARIANTS + if (intr_nesting_level != 0) { + panic("pmap_pte called from interrupt"); + } +#endif + newpf = *pde & PG_FRAME; + if ((*PMAP2 & PG_FRAME) != newpf) { + *PMAP2 = newpf | PG_RW | PG_V; +#ifdef SMP + cpu_invlpg(PADDR2); +#else + invltlb_1pg((vm_offset_t) PADDR2); +#endif + } + return PADDR2 + (i386_btop(va) & (NPTEPG - 1)); + } + return (0); +} + +/* * Routine: pmap_extract * Function: * Extract the physical page address associated @@ -1635,8 +1688,8 @@ if (nva > eva) nva = eva; - for (; sva < nva; sva += PAGE_SIZE) { - pte = pmap_pte(pmap, sva); + pte = pmap_pte(pmap, sva); + for (; sva < nva; sva += PAGE_SIZE, pte++) { if ((*pte & PG_V) == 0) continue; @@ -1684,7 +1737,7 @@ while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) { pv->pv_pmap->pm_stats.resident_count--; - pte = pmap_pte(pv->pv_pmap, pv->pv_va); + pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va); tpte = pte_store(pte, 0); if (tpte & PG_W) @@ -2681,7 +2734,7 @@ #ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY pte = vtopte(pv->pv_va); #else - pte = pmap_pte(pv->pv_pmap, pv->pv_va); + pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va); #endif tpte = *pte; @@ -2762,7 +2815,7 @@ continue; } #endif - pte = pmap_pte(pv->pv_pmap, pv->pv_va); + pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va); if (*pte & bit) { splx(s); return TRUE; @@ -2807,7 +2860,7 @@ } #endif - pte = pmap_pte(pv->pv_pmap, pv->pv_va); + pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va); if (setem) { *pte |= bit; @@ -2893,7 +2946,7 @@ if (!pmap_track_modified(pv->pv_va)) continue; - pte = pmap_pte(pv->pv_pmap, pv->pv_va); + pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va); if (pte && (*pte & PG_A)) { *pte &= ~PG_A; @@ -3180,6 +3233,7 @@ struct proc *p; int npte = 0; int index; + int s; LIST_FOREACH(p, &allproc, p_list) { if (p->p_pid != pid) continue; @@ -3195,6 +3249,7 @@ pde = &pmap->pm_pdir[i]; if (pde && pmap_pde_v(pde)) { + s = splvm(); for(j=0;j<1024;j++) { unsigned va = base + (j << PAGE_SHIFT); if (va >= (vm_offset_t) VM_MIN_KERNEL_ADDRESS) { @@ -3202,9 +3257,10 @@ index = 0; printf("\n"); } + splx(s); return npte; } - pte = pmap_pte( pmap, va); + pte = pmap_pte_quick(pmap, va); if (pte && pmap_pte_v(pte)) { vm_offset_t pa; vm_page_t m; @@ -3222,6 +3278,7 @@ } } } + splx(s); } } } @@ -3242,9 +3299,11 @@ { unsigned va, i, j; unsigned *ptep; + int s; if (pm == kernel_pmap) return; + s = splvm(); for (i = 0; i < 1024; i++) if (pm->pm_pdir[i]) for (j = 0; j < 1024; j++) { @@ -3253,10 +3312,11 @@ continue; if (pm != kernel_pmap && va > UPT_MAX_ADDRESS) continue; - ptep = pmap_pte(pm, va); + ptep = pmap_pte_quick(pm, va); if (pmap_pte_v(ptep)) printf("%x:%x ", va, *(int *) ptep); }; + splx(s); } Index: sys/i386/include/globaldata.h =================================================================== RCS file: /home/ncvs/src/sys/i386/include/Attic/globaldata.h,v retrieving revision 1.11.2.2 diff -u -r1.11.2.2 globaldata.h --- sys/i386/include/globaldata.h 9 Aug 2003 16:21:19 -0000 1.11.2.2 +++ sys/i386/include/globaldata.h 28 Aug 2003 20:05:38 -0000 @@ -61,10 +61,12 @@ pt_entry_t *gd_prv_CMAP2; pt_entry_t *gd_prv_CMAP3; pd_entry_t *gd_prv_PMAP1; + pd_entry_t *gd_prv_PMAP2; caddr_t gd_prv_CADDR1; caddr_t gd_prv_CADDR2; caddr_t gd_prv_CADDR3; pt_entry_t *gd_prv_PADDR1; + pt_entry_t *gd_prv_PADDR2; #endif u_int gd_astpending; }; @@ -80,13 +82,14 @@ struct globaldata globaldata; char __filler0[PAGE_SIZE - sizeof(struct globaldata)]; - /* page 1..4 - CPAGE1,CPAGE2,CPAGE3,PPAGE1 */ + /* page 1..5 - CPAGE1,CPAGE2,CPAGE3,PPAGE1,PPAGE2 */ char CPAGE1[PAGE_SIZE]; char CPAGE2[PAGE_SIZE]; char CPAGE3[PAGE_SIZE]; char PPAGE1[PAGE_SIZE]; + char PPAGE2[PAGE_SIZE]; - /* page 5..4+UPAGES - idle stack (UPAGES pages) */ + /* page 6..5+UPAGES - idle stack (UPAGES pages) */ char idlestack[UPAGES * PAGE_SIZE]; }; Index: sys/i386/include/globals.h =================================================================== RCS file: /home/ncvs/src/sys/i386/include/Attic/globals.h,v retrieving revision 1.5.2.2 diff -u -r1.5.2.2 globals.h --- sys/i386/include/globals.h 9 Aug 2003 16:21:19 -0000 1.5.2.2 +++ sys/i386/include/globals.h 28 Aug 2003 20:05:38 -0000 @@ -104,10 +104,12 @@ #define prv_CMAP2 GLOBAL_LVALUE(prv_CMAP2, pt_entry_t *) #define prv_CMAP3 GLOBAL_LVALUE(prv_CMAP3, pt_entry_t *) #define prv_PMAP1 GLOBAL_LVALUE(prv_PMAP1, pd_entry_t *) +#define prv_PMAP2 GLOBAL_LVALUE(prv_PMAP2, pd_entry_t *) #define prv_CADDR1 GLOBAL_RVALUE(prv_CADDR1, caddr_t) #define prv_CADDR2 GLOBAL_RVALUE(prv_CADDR2, caddr_t) #define prv_CADDR3 GLOBAL_RVALUE(prv_CADDR3, caddr_t) #define prv_PADDR1 GLOBAL_RVALUE(prv_PADDR1, pt_entry_t *) +#define prv_PADDR2 GLOBAL_RVALUE(prv_PADDR2, pt_entry_t *) #endif #endif /*UP kernel*/ @@ -134,10 +136,12 @@ GLOBAL_FUNC(prv_CMAP2) GLOBAL_FUNC(prv_CMAP3) GLOBAL_FUNC(prv_PMAP1) +GLOBAL_FUNC(prv_PMAP2) GLOBAL_FUNC(prv_CADDR1) GLOBAL_FUNC(prv_CADDR2) GLOBAL_FUNC(prv_CADDR3) GLOBAL_FUNC(prv_PADDR1) +GLOBAL_FUNC(prv_PADDR2) #endif #define SET_CURPROC(x) (_global_curproc_set_nv((int)x)) ----Next_Part(Thu_Aug_28_20:20:11_2003_868)----