Date: Wed, 17 May 2006 06:15:39 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 97324 for review Message-ID: <200605170615.k4H6FdXc052993@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=97324 Change 97324 by kmacy@kmacy_storage:sun4v_rwbuf on 2006/05/17 06:15:38 simplify pmap_enter and pmap_map work around broken calls to pmap_qremove copious other cleanups Affected files ... .. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/pmap.c#49 edit Differences ... ==== //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/pmap.c#49 (text+ko) ==== @@ -429,7 +429,7 @@ struct pmap *pm; vm_offset_t off, va; vm_paddr_t pa, kernel_hash_pa; - vm_size_t physsz, virtsz; + vm_size_t physsz, virtsz, kernel_hash_size; ihandle_t pmem, vmem; int i, sz, j; uint64_t tsb_8k_size, tsb_4m_size, error; @@ -559,7 +559,13 @@ * Allocate and map a 4MB page for the kernel hashtable * */ - kernel_hash_pa = pmap_bootstrap_alloc(PAGE_SIZE_4M); +#ifndef SIMULATOR + kernel_hash_size = PAGE_SIZE_4M*2; +#else + kernel_hash_size = PAGE_SIZE_8K*64; +#endif + + kernel_hash_pa = pmap_bootstrap_alloc(kernel_hash_size); if (kernel_hash_pa & PAGE_MASK_4M) panic("pmap_bootstrap: hashtable pa unaligned\n"); /* @@ -724,7 +730,7 @@ * This could happen earlier - but I put it here to avoid * attempts to do updates until they're legal */ - pm->pm_hash = tte_hash_kernel_create(TLB_PHYS_TO_DIRECT(kernel_hash_pa), PAGE_SIZE_4M); + pm->pm_hash = tte_hash_kernel_create(TLB_PHYS_TO_DIRECT(kernel_hash_pa), kernel_hash_size); pm->pm_hashscratch = tte_hash_set_scratchpad_kernel(pm->pm_hash); for (i = 0; i < translations_size; i++) { @@ -807,7 +813,7 @@ vm_offset_t addr, end_addr; end_addr = src_addr + len; - + /* * Don't let optional prefaulting of pages make us go * way below the low water mark of free pages or way @@ -831,10 +837,10 @@ tte_t tte_data; vm_page_t m; - tte_data = tte_hash_lookup_nolock(src_pmap->pm_hash, addr); + tte_data = tte_hash_lookup(src_pmap->pm_hash, addr); if ((tte_data & VTD_MANAGED) != 0) { - if (tte_hash_lookup_nolock(dst_pmap->pm_hash, addr) == 0) { + if (tte_hash_lookup(dst_pmap->pm_hash, addr) == 0) { m = PHYS_TO_VM_PAGE(TTE_GET_PA(tte_data)); tte_hash_insert(dst_pmap->pm_hash, addr, tte_data & ~(VTD_W|VTD_REF)); @@ -864,6 +870,19 @@ } +static __inline void +pmap_add_tte(pmap_t pmap, vm_offset_t va, vm_page_t m, tte_t *tte_data, int wired) +{ + + if (wired) + pmap->pm_stats.wired_count++; + + if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) { + pmap_insert_entry(pmap, va, m); + *tte_data |= VTD_MANAGED; + } +} + /* * Map the given physical page at the specified virtual address in the * target pmap with the protection requested. If specified the page @@ -889,20 +908,33 @@ sched_pin(); tte_data = pa = VM_PAGE_TO_PHYS(m); - otte_data = tte_hash_lookup(pmap->pm_hash, va); + otte_data = tte_hash_delete(pmap->pm_hash, va); opa = TTE_GET_PA(otte_data); -#ifdef PMAP_DEBUG - if (opa > (1 << 31)) - panic("opa out of range 0x%lx\n", opa); - if ((vm_offset_t)PHYS_TO_VM_PAGE(opa) > ((1UL << 31) | VM_MIN_DIRECT_ADDRESS)) { - DELAY(curcpu*5000); - panic("om out of range %p\n", PHYS_TO_VM_PAGE(opa)); - } -#endif + /* * Mapping has not changed, must be protection or wiring change. */ - if (pa == opa) { + + if (opa == 0) { + pmap->pm_stats.resident_count++; + pmap_add_tte(pmap, va, m, &tte_data, wired); + + } else if (pa != opa) { + /* + * Mapping has changed, invalidate old range and fall through to + * handle validating new mapping. + */ + if (otte_data & VTD_WIRED) + pmap->pm_stats.wired_count--; + + if (otte_data & VTD_MANAGED) { + om = PHYS_TO_VM_PAGE(opa); + pmap_remove_entry(pmap, om, va); + } + + pmap_add_tte(pmap, va, m, &tte_data, wired); + + } else /* (pa == opa) */ { /* * Wiring change, just update stats. We don't worry about * wiring PT pages as they remain resident as long as there @@ -922,37 +954,9 @@ om = m; tte_data |= VTD_MANAGED; } - goto validate; + } - } else if (opa) { - /* - * Mapping has changed, invalidate old range and fall through to - * handle validating new mapping. - */ - if (otte_data & VTD_WIRED) - pmap->pm_stats.wired_count--; - if (otte_data & VTD_MANAGED) { - om = PHYS_TO_VM_PAGE(opa); - pmap_remove_entry(pmap, om, va); - } - } else - pmap->pm_stats.resident_count++; - /* - * Enter on the PV list if part of our managed memory. - */ - if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) { - pmap_insert_entry(pmap, va, m); - tte_data |= VTD_MANAGED; - } - /* - * Increment counters - */ - if (wired) - pmap->pm_stats.wired_count++; - -validate: - /* * Now validate mapping with desired protection/wiring. */ if ((prot & VM_PROT_WRITE) != 0) @@ -965,7 +969,7 @@ tte_data |= TTE_KERNEL_MINFLAGS; - otte_data = tte_hash_update(pmap->pm_hash, va, tte_data | TTE_MINFLAGS); + tte_hash_insert(pmap->pm_hash, va, tte_data | TTE_MINFLAGS); tsb_set_tte(&pmap->pm_tsb, va, tte_data|TTE_MINFLAGS, pmap->pm_context); invlva = FALSE; @@ -1075,7 +1079,7 @@ vm_page_lock_queues(); PMAP_LOCK(pmap); sched_pin(); - tte_data = tte_hash_lookup_nolock(pmap->pm_hash, va); + tte_data = tte_hash_lookup(pmap->pm_hash, va); if (tte_data != 0 && ((tte_data & VTD_SW_W) || (prot & VM_PROT_WRITE) == 0)) { m = PHYS_TO_VM_PAGE(TTE_GET_PA(tte_data)); @@ -1181,7 +1185,6 @@ else active = PCPU_GET(other_cpus); -#if 1 for (cpu_count = 0, i = 0, ackexpect = 0, cpus = active; i < 32 && cpus;) { @@ -1195,23 +1198,12 @@ cpulist[cpu_count] = (uint16_t)i; cpu_count++; ackexpect |= (1 << i); -#if 0 - inext = ((i & ~0x3) + 4); - cpus = (cpus >> (inext - i)); - i = inext; -#else inext = i++; cpus = cpus >> 1; -#endif } -#else - inext = i = cpus = 0; - cpulist[0] = curcpu ? 0 : 1; - cpu_count = 1; - ackexpect = curcpu ? 1 : 2; -#endif + if (cpu_count == 0) return; @@ -1257,20 +1249,39 @@ char *func; #endif + + if ((eva - sva) == PAGE_SIZE) { + pmap_invalidate_page(pmap, sva, cleartsb); + return; + } + + if (sva >= eva) + panic("invalidating negative or zero range sva=0x%lx eva=0x%lx", sva, eva); + + spinlock_enter(); if (cleartsb == TRUE) { +#if 0 if ((((eva - sva) >> PAGE_SHIFT) < MAX_TSB_CLEARS) || (pmap->pm_context == 0)) +#endif tsb_clear_range(&pmap->pm_tsb, sva, eva); +#if 0 else tsb_clear(&pmap->pm_tsb); +#endif } - /* XXX */ + /* XXX - this is needed to make sure that the first page of a process' text + * is flushed from the TLB - there aren't any exisiting pmap implementation's + * that show how to flush just the page in question - on x86 the TLB is flushed + * every time cr3 is changed + */ +#if 0 invltlb(); - - if ((((eva - sva) >> PAGE_SHIFT) < MAX_INVALIDATES)) { +#endif + if ((sva - eva) < PAGE_SIZE*32 ) { for (tva = sva; tva < eva; tva += PAGE_SIZE_8K) invlpg(tva, pmap->pm_context); } else if (pmap->pm_context) @@ -1395,19 +1406,7 @@ vm_offset_t pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot) { - vm_offset_t va, sva; - - va = sva = *virt; - while (start < end) { - pmap_kenter(va, start); - va += PAGE_SIZE; - start += PAGE_SIZE; - } - - pmap_invalidate_range(kernel_pmap, sva, va, FALSE); - - *virt = va; - return (sva); + return TLB_PHYS_TO_DIRECT(start); } int @@ -1542,17 +1541,13 @@ sched_pin(); for (tva = sva; tva < eva; tva += PAGE_SIZE) { - uint64_t otte_data, tte_data; + uint64_t otte_data; vm_page_t m; - if ((tte_data = tte_hash_lookup(pmap->pm_hash, tva)) == 0) + if ((otte_data = tte_hash_clear_bits(pmap->pm_hash, tva, (VTD_SW_W | VTD_W | VTD_REF))) == 0) continue; - tte_data &= ~(VTD_SW_W | VTD_W | VTD_REF); - - otte_data = tte_hash_update(pmap->pm_hash, tva, tte_data); - - if (tte_data != otte_data) + if (otte_data & (VTD_SW_W | VTD_W | VTD_REF)) anychanged = 1; if (otte_data & VTD_MANAGED) { @@ -1593,6 +1588,7 @@ va += PAGE_SIZE; m++; } + pmap_invalidate_range(kernel_pmap, sva, va, FALSE); } @@ -1606,10 +1602,16 @@ vm_offset_t va; va = sva; + +#ifndef NFS_NOT_BROKEN + if (count == 0) + count = 1; +#endif while (count-- > 0) { pmap_kremove(va); va += PAGE_SIZE; } + pmap_invalidate_range(kernel_pmap, sva, va, TRUE); } @@ -1769,10 +1771,15 @@ tte_data = tte_hash_delete(pmap->pm_hash, pv->pv_va); if (tte_data == 0) { - printf("TTE IS ZERO @ VA %016lx\n", pv->pv_va); - panic("bad tte"); + membar(Sync); + DELAY(100); + membar(Sync); + tte_data = tte_hash_delete(pmap->pm_hash, pv->pv_va); + if (tte_data == 0) { + printf("TTE IS ZERO @ VA %016lx\n", pv->pv_va); + panic("bad tte"); + } } - /* * We cannot remove wired pages from a * process' mapping at this time
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200605170615.k4H6FdXc052993>