Date: Mon, 13 Jul 2009 14:57:32 +0200 From: Michal Hajduk <mih@semihalf.com> To: Mark Tinguely <tinguely@casselton.net> Cc: freebsd-arm@freebsd.org Subject: Re: pmap problem in FreeBSD current - PS Message-ID: <4A5B2F3C.4030501@semihalf.com> In-Reply-To: <4A5AF2DA.9050101@semihalf.com> References: <200907101454.n6AEs7nJ087492@casselton.net> <4A5AF2DA.9050101@semihalf.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Michal Hajduk wrote: > Hi Mark, > > I've corrected busdma_machdep instead of adding this PVF_REF flag to arm > pmap code and it works good. > My patch: > =========================================================== > diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c > index a8b2de9..b55a714 100644 > --- a/sys/arm/arm/busdma_machdep.c > +++ b/sys/arm/arm/busdma_machdep.c > .... I've found another problem in busdma_machdep.c in function bus_dmamem_alloc. After write-back invalidate operation there is no tlb flush. Below there is complete patch: ============================================================ diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c index a8b2de9..9562615 100644 --- a/sys/arm/arm/busdma_machdep.c +++ b/sys/arm/arm/busdma_machdep.c @@ -631,10 +631,11 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, ((vm_offset_t)*vaddr & PAGE_MASK)); newmap->origbuffer = *vaddr; newmap->allocbuffer = tmpaddr; - cpu_idcache_wbinv_range((vm_offset_t)*vaddr, - dmat->maxsize); - cpu_l2cache_wbinv_range((vm_offset_t)*vaddr, - dmat->maxsize); + cpu_dcache_wbinv_range((vm_offset_t)*vaddr & + ~PAGE_MASK, PAGE_SIZE); + cpu_l2cache_wbinv_range((vm_offset_t)*vaddr & + ~PAGE_MASK, PAGE_SIZE); + cpu_tlb_flushID_SE((vm_offset_t)*vaddr); *vaddr = tmpaddr; } else newmap->origbuffer = newmap->allocbuffer = NULL; ============================================================ > I've also checked your patch and it didn't help (I had a panic) > ... > uhub0: 1 port with 1 removable, self powered > Root mount waiting for: usbus0 > panic: blockable sleep lock (sleep mutex) vm page queue mutex @ > /home/mih/git/marvell-current/sys/arm/arm/pmap.c:1947 > KDB: enter: panic > [thread pid 15 tid 100028 ] > Stopped at $d: ldrb r15, [r15, r15, ror r15]! > > Many thanks, > Michał Hajduk > Can we move vm_page_unlock_queues() (line 1693) and vm_page_lock_queues to pmap_get_pv_entry() ? Is it added only because of pagedaemon_wakeup()? If this is correct, I've prepared a patch: =========================================================== diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c index 3cdab65..b4ffbbf 100644 --- a/sys/arm/arm/pmap.c +++ b/sys/arm/arm/pmap.c @@ -1690,10 +1690,8 @@ pmap_enter_pv(struct vm_page *pg, struct pv_entry *pve, pmap_t pm, TAILQ_INSERT_HEAD(&pm->pm_pvlist, pve, pv_plist); if ((km = PMAP_OWNED(pmap_kernel()))) PMAP_UNLOCK(pmap_kernel()); - vm_page_unlock_queues(); if ((pve = pmap_get_pv_entry()) == NULL) panic("pmap_kenter_internal: no pv entries"); - vm_page_lock_queues(); if (km) PMAP_LOCK(pmap_kernel()); } @@ -2904,10 +2902,8 @@ pmap_kenter_internal(vm_offset_t va, vm_offset_t pa, int flags) vm_page_lock_queues(); if (!TAILQ_EMPTY(&m->md.pv_list) || m->md.pv_kva) { /* release vm_page lock for pv_entry UMA */ - vm_page_unlock_queues(); if ((pve = pmap_get_pv_entry()) == NULL) panic("pmap_kenter_internal: no pv entries"); - vm_page_lock_queues(); PMAP_LOCK(pmap_kernel()); pmap_enter_pv(m, pve, pmap_kernel(), va, PVF_WRITE | PVF_UNMAN); @@ -2984,8 +2980,8 @@ pmap_kremove(vm_offset_t va) pmap_free_pv_entry(pve); PMAP_UNLOCK(pmap_kernel()); vm_page_unlock_queues(); - cpu_dcache_wbinv_range(va, PAGE_SIZE); - cpu_l2cache_wbinv_range(va, PAGE_SIZE); + cpu_dcache_wbinv_range(va & ~PAGE_MASK, PAGE_SIZE); + cpu_l2cache_wbinv_range(va & ~PAGE_MASK, PAGE_SIZE); cpu_tlb_flushD_SE(va); cpu_cpwait(); *pte = 0; @@ -3935,8 +3931,11 @@ pmap_get_pv_entry(void) pv_entry_t ret_value; pv_entry_count++; - if (pv_entry_count > pv_entry_high_water) + if (pv_entry_count > pv_entry_high_water) { + vm_page_unlock_queues(); pagedaemon_wakeup(); + vm_page_lock_queues(); + } ret_value = uma_zalloc(pvzone, M_NOWAIT); return ret_value; } ========================================================== With this patch I didn't observe LORs (as well as with your + mine patch). Thanks for your help. Best regards, Michał Hajduk
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4A5B2F3C.4030501>