Performance of SheevaPlug on 8-stable
Mark Tinguely
tinguely at casselton.net
Mon Mar 8 18:19:26 UTC 2010
> In message: <4B951CE2.6040507 at semihalf.com>
> Grzegorz Bernacki <gjb at semihalf.com> writes:
> : This is probably caused by mechanism which turns of cache for shared
> : pages.
> : When I add applied following path:
> :
> : diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
> : index 390dc3c..d17c0cc 100644
> : --- a/sys/arm/arm/pmap.c
> : +++ b/sys/arm/arm/pmap.c
> : @@ -1401,6 +1401,8 @@ pmap_fix_cache(struct vm_page *pg, pmap_t pm,
> : vm_offset_t va)
> : */
> :
> : TAILQ_FOREACH(pv, &pg->md.pv_list, pv_list) {
> : + if (pv->pv_flags & PVF_EXEC)
> : + return;
> : /* generate a count of the pv_entry uses */
> : if (pv->pv_flags & PVF_WRITE) {
> : if (pv->pv_pmap == pmap_kernel())
> :
> : execution time of 'test' program is:
> : mv78100-4# time ./test
> : 5.000u 0.000s 0:05.40 99.8% 40+1324k 0+0io 0pf+0w
> :
> : and without this path is:
> : mv78100-4# time ./test
> : 295.000u 0.000s 4:56.01 99.7% 40+1322k 0+0io 0pf+0w
> :
> :
> : I think we need to handle executable pages in different way.
>
> Agreed. Why would we turn off caching for shared pages? I can
> understand read/write pages in a system that has a virtually index
> cache with the classic cache aliasing problems as a workaround for
> lousy hardware, but otherwise, this one has me scratching my head...
>
> And if there's only one copy of 'test' running, why does it hit the
> 'shared' case for this code?
>
> Warner
Could you do this instead:
+ int stop;
TAILQ_FOREACH(pv, &pg->md.pv_list, pv_list) {
+ if (pv->pv_flags & PVF_EXEC)
+ stop = 1;
/* generate a count of the pv_entry uses */
if (pv->pv_flags & PVF_WRITE) {
if (pv->pv_pmap == pmap_kernel())
kwritable++;
else if (pv->pv_pmap == pm)
uwritable++;
writable++;
}
if (pv->pv_pmap == pmap_kernel())
kentries++;
else {
if (pv->pv_pmap == pm)
uentries++;
entries++;
}
}
+ if (stop) {
+ if (writable && entries)
+ printf("fix results %d %d %d %d\n", kwritable,uwritable,
+ kentries, uentries);
+ return;
+ }
This would give counts to make sure there is not a logic error in fix_cache.
My best guess kwritable/kentry will be non-zero and says there is another
"dangling kernel allocation" somewhere. We allocate a page into a kernel
mapping and then either:
1) we are not clearing the md.pv_kva entry all the time when
allocation is freed. I thought I was careful.
2) someone is temporarilly allocating the page and not telling
pmap that they are done with it.
The information that this page is mapped to a kernel mapping is incorrectly
remembered, and the cache are turned off.
We could look in the free page code for a non-empty md.pv_kva entry to
test this theory.
md.pv_kva is set for kernel mappings, so the culiprit will be in the
pmap_kenter calls.
Thank-you.
--Mark Tinguely
More information about the freebsd-arm
mailing list