Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Jul 2009 10:39:54 +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:  <4A5AF2DA.9050101@semihalf.com>
In-Reply-To: <200907101454.n6AEs7nJ087492@casselton.net>
References:  <200907101454.n6AEs7nJ087492@casselton.net>

next in thread | previous in thread | raw e-mail | index | archive | help
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
@@ -631,10 +631,10 @@ 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_idcache_wbinv_range((vm_offset_t)*vaddr &
+ ~PAGE_MASK, PAGE_SIZE);
+ cpu_l2cache_wbinv_range((vm_offset_t)*vaddr &
+ ~PAGE_MASK, PAGE_SIZE);
*vaddr = tmpaddr;
} else
newmap->origbuffer = newmap->allocbuffer = NULL;

============================================================

While debugging this problem we've found another in pmap_kremove(). 
There was an
invalidation on va + PAGE_SIZE instead of page which contains va address.
My patch:

=====================================================
diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
index 3cdab65..7988f40 100644
--- a/sys/arm/arm/pmap.c
+++ b/sys/arm/arm/pmap.c
@@ -2984,8 +2984,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;
=====================================================

I suggest, that maybe for now we should only change the 
cpu_(l2)idcache_wbinv_range()
routines by adding simple check:
If the va address is page aligned and size is equal to PAGE_SIZE we 
should write-back
and invalidate whole page. Otherwise we should invalidate line by line.

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4A5AF2DA.9050101>