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 perf-discuss@opensolaris.org