G'Day Eric,
On Wed, 18 Jan 2006, Eric Lowe wrote:
> Coming into this thread late since I'm returning for vacation...
>
> On Thu, Jan 12, 2006 at 02:55:52AM +1100, Brendan Gregg wrote:
> |
> | I want segvn hit rate. There must be a function in the segvn code
> | somewhere that checks whether a page is already in the page cache or not,
>
> So in a nutshell, what you want to know is, for mmap() faults what is the
> hit rate in the page cache?
At the moment, yes.
> | which would be ideal for DTrace to trace. I would expect this to be
> | related to when a page fault occurs from a segvn mapping.
> |
> | I've looked at a number of functions, including the following,
> |
> | segvn_fault
> | page_exists
> | page_lookup
> | page_reclaim
> | ufs_getpage
> | ufs_getpage_ra
> | seg_plookup
>
> It's probably easier to track the number of misses and compare to the
> number of faults since there are so many places you can find a page.
> To do that you can just look for calls to page_create_va() from the
> context of {segvn_fault,segvn_faulta}.
Yes, page_create_va() is interesting, but I'm not getting enough faults
that end up calling it (which you explain below).
> Some other notes..
>
> Regarding the number of faults. The read-ahead is completely done within
> the filesystem layer in the current architecture so the behavior is highly
> FS specific.
Yep, and I'm back to ufs_getpage_ra() again - been here a few times over
the past year...
> Look for the callers to hat_memload() and hat_memload_array()
> in the system -- the read-ahead appears to be loading multiple mappings when
> the pages are read in. Further accesses therefore don't generate faults
> to these pages.
Hooray! I suspected the cache-read-ahead was loading the mappings
before they faulted; and now I'm using hat_memload() to see all of the
segvn mapping events. :-)
I'm currently using the following calculations,
segvn_miss == io strategy while in {segvn_fault,segvn_faulta}
segvn_hit == hat_memload in {segvn_fault,segvn_faulta} - segvn_miss
and so far, so good (need to add hat_memload_array and check for others).
I've attached a draft script that tests the above; if anyone can find me a
scenario where it doesn't work, please email...
> If OTOH you have a 100% hit rate in the cache I would
> expect to see ~1000 faults for a 8M segment on SPARC or 4M on x86 since
> you would get one fault and one attach per page. These would be counted
> as minor faults.
I'm never seeing all the faults due to the cache-read-ahead (ok, I should
really say FS-read-ahead-from-cache). Only by using hat_memload() I can
see all 1000 mappings..
The way a freshly written file (as opposed to a freshly mounted file)
changed the number of faults really threw me. Still haven't put my finger
on why, but I suspect it's a cache placement policy (maybe MPSS - I need
to go test this on SPARC where I have trapstat. :)
> Hope this helps.
This certainly helps!
thanks,
Brendan
[Sydney, Australia]
#!/usr/sbin/dtrace -s
/* todo: hat_memload_array */
#pragma D option quiet
#pragma D option defaultargs
inline int SCREEN = 21;
dtrace:::BEGIN
{
lines = SCREEN + 1;
secs = $1 ? $1 : 1;
counts = $2 ? $2 : -1;
first = 1;
@hits = sum(0);
@miss = sum(0);
}
profile:::tick-1sec
{
secs--;
}
profile:::tick-1sec
/first || (secs == 0 && lines > SCREEN)/
{
printf("%10s %10s\n", "HITS", "MISSES");
first = 0;
lines = 0;
}
fbt::segvn_fault:entry,
fbt::segvn_faulta:entry
{
self->segvn = 1;
}
fbt::hat_memload:entry
/self->segvn && args[2]->p_vnode->v_path != NULL/
{
/*
* hat_memload is interesting (thanks Eric L.) as we use it
* to track the total number of page creates in segvn, so
* long as our context is segvn_fault. This value minus io
* events is used as the hit rate.
*/
@path[execname, stringof(args[2]->p_vnode->v_path)] = count();
@hits = sum(1);
}
io:::start
/self->segvn/
{
/* a segvn miss is an io event within a segvn_fault context */
@iobytes[execname, args[2]->fi_pathname,
args[0]->b_flags & B_READ ? "R" : "W"] = sum(args[0]->b_bcount);
@miss = sum(args[0]->b_bcount / `_pagesize);
@hits = sum(- (args[0]->b_bcount / `_pagesize));
}
fbt::segvn_fault:return,
fbt::segvn_faulta:return
/self->segvn/
{
self->segvn = 0;
}
profile:::tick-1sec
/secs == 0/
{
printa("[EMAIL PROTECTED] ", @hits);
printa("[EMAIL PROTECTED]", @miss);
trunc(@hits);
trunc(@miss);
@hits = sum(0);
@miss = sum(0);
secs = $1 ? $1 : 1;
lines++;
counts--;
}
dtrace:::END
{
printf("hat_memload\n-----------\n");
printf("%-16s %-50s %8s\n", "CMD", "PATH", "COUNT");
printa("%-16s %-50s [EMAIL PROTECTED]", @path);
printf("\nio:::start\n----------\n");
printf("%-16s %32s %3s %10s\n", "CMD", "FILE", "DIR", "BYTES");
printa("%-16s %32s %3s [EMAIL PROTECTED]", @iobytes);
}
_______________________________________________
perf-discuss mailing list
[email protected]