Date: Fri, 30 Mar 2007 15:23:08 GMT From: Oleksandr Tymoshenko <gonzo@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 116925 for review Message-ID: <200703301523.l2UFN8CO006204@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=116925 Change 116925 by gonzo@gonzo_jeeves on 2007/03/30 15:22:20 o ASID generation logic reworked. o PTE for kernel virtual address space should have global bit set. With EntryHi set in pmap_active some undesirable effects appeared, i.e.: "splitting" KVA among processes. Affected files ... .. //depot/projects/mips2/src/sys/mips/mips/pmap.c#25 edit Differences ... ==== //depot/projects/mips2/src/sys/mips/mips/pmap.c#25 (text+ko) ==== @@ -169,7 +169,7 @@ /* * Active segtab. */ -struct segtab * segtab_active; +struct segtab * segtab_active = 0; /* * Data for the ASID allocator @@ -207,6 +207,7 @@ static int pte_prot(pmap_t pmap, vm_prot_t prot) { + if(prot & VM_PROT_WRITE) return PG_D; @@ -342,7 +343,7 @@ kernel_pmap->pm_private.pm_direct_map = kptmap; kernel_pmap->pm_active = ~0; kernel_pmap->pm_asid = PMAP_ASID_RESERVED; - kernel_pmap->pm_asid_generation = 1; + kernel_pmap->pm_asid_generation = 0; PMAP_LOCK_INIT(kernel_pmap); TAILQ_INIT(&kernel_pmap->pm_pvlist); @@ -509,8 +510,10 @@ * Invalidate all per-process mappings and I-cache */ PCPU_SET(next_asid, 1); - PCPU_SET(current_asid_generation, (PCPU_GET(current_asid_generation) + 1) & - ASIDGEN_MASK); + + /* It's OK to turn to 0 */ + PCPU_SET(current_asid_generation, + (PCPU_GET(current_asid_generation) + 1)); if (PCPU_GET(current_asid_generation) == 0) { /* @@ -679,7 +682,7 @@ pmap_kenter(vm_offset_t va, vm_offset_t pa) { - tlb_enter(kernel_pmap, va, pa, PG_V | PG_W | PG_D); + tlb_enter(kernel_pmap, va, pa, PG_V | PG_W | PG_D | PG_G); } /* @@ -730,12 +733,13 @@ pmap->pm_active = 0; pmap->pm_asid = PMAP_ASID_RESERVED; - pmap->pm_asid_generation = 1; + pmap->pm_asid_generation = 0; TAILQ_INIT(&pmap->pm_pvlist); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); mtx_init(&allpmaps_lock, "allpmaps", NULL, MTX_SPIN | MTX_QUIET); LIST_INSERT_HEAD(&allpmaps, pmap, pm_list); + PCPU_SET(current_asid_generation, 1); } /* @@ -771,9 +775,8 @@ pmap->pm_ptphint = NULL; pmap->pm_active = 0; - /* XXXMIPS: put proper asid generation here */ - pmap->pm_asid = 1; - pmap->pm_asid_generation = 1; + pmap->pm_asid = PMAP_ASID_RESERVED; + pmap->pm_asid_generation = 0; PMAP_LOCK_INIT(pmap); TAILQ_INIT(&pmap->pm_pvlist); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); @@ -974,7 +977,9 @@ int retval; oldpte = *ptq; - *ptq = 0; + /* Preserve global bit */ + *ptq &= PG_G; + if (oldpte & PG_W) pmap->pm_stats.wired_count -= 1; @@ -1029,6 +1034,7 @@ { pmap_remove_pte(pmap, pte, va); tlb_remove(pmap, va); + } va += PAGE_SIZE; } @@ -1185,7 +1191,7 @@ pt_entry_t *pte; vm_offset_t opa; vm_page_t mpte, mem; - int p, has_mapping = 0; + int p, has_mapping = 0, global; if (pmap == NULL) return; @@ -1298,8 +1304,9 @@ pmap->pm_stats.wired_count++; wired = wired ? PG_W : 0; + global = pmap == kernel_pmap ? PG_G : 0; p = pte_prot(pmap, prot); - tlb_enter(pmap, va, pa, PG_V | wired | p); + tlb_enter(pmap, va, pa, PG_V | wired | global | p); } /* @@ -1843,30 +1850,34 @@ pmap = vmspace_pmap(td->td_proc->p_vmspace); critical_enter(); - if (pmap_active && pmap != pmap_active) { - atomic_clear_int(&pmap_active->pm_active, - PCPU_GET(cpumask)); - pmap_active = 0; - segtab_active = 0; - } - if (pmap->pm_asid_generation != PCPU_GET(current_asid_generation)) + /* + * Kernel pmap has ASID equal zero and generation zero as well + * Just don't mess with it's ASID on generation turnover. + */ + if ((pmap != kernel_pmap) && + (pmap->pm_asid_generation != PCPU_GET(current_asid_generation))) pmap_get_asid(pmap); - mips_wr_entryhi(pmap->pm_asid); + if (td == curthread) + { + if (pmap_active && pmap != pmap_active) + { + atomic_clear_int(&pmap_active->pm_active, + PCPU_GET(cpumask)); + pmap_active = 0; + segtab_active = 0; + } + + mips_wr_entryhi(pmap->pm_asid); - pmap_active = pmap; - segtab_active = pmap->pm_private.pm_segtab; - atomic_set_int(&pmap->pm_active, PCPU_GET(cpumask)); + pmap_active = pmap; + segtab_active = pmap->pm_private.pm_segtab; + atomic_set_int(&pmap->pm_active, PCPU_GET(cpumask)); + mips_dcache_wbinv_all(); + } critical_exit(); - - if (td == curthread) { - /* XXX swap context? - alpha_pal_swpctx((u_long)td->td_md.md_pcbpaddr); - */ - } - mips_dcache_wbinv_all(); } void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703301523.l2UFN8CO006204>