This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Page faults


On 09/09/2013 03:36 PM, Paddie O'Brien wrote:
> Hi,
> 
> I run the attached to print out the offsets of faulting pages. Both
> probes should (I think) print the same number but instead I get this:
> 
> hello: filemap_fault
> Page: 1678263179
> hello: find_get_page
> Page: 15
> 
> hello: filemap_fault
> Page: 1678263179
> hello: find_get_page
> Page: 1
> 
> hello: filemap_fault
> Page: 1678263179
> hello: find_get_page
> Page: 10
> 
> etc. etc.
> 
> Both functions are from mm/filemap.c. filemap_fault does this:
> 
> pgoff_t offset = vmf->offset;
> find_get_page(mapping, offset);
> 
> Basically, printing the offset in find_get_page works but printing
> vmf->offset in filemap_fault doesn't.
> 
> Why?

Here's your script:

====
probe kernel.function("filemap_fault")
{
	if (execname() != "hello") next;
	printf("%s: filemap_fault\n", execname());
	printf("Page: %lu\n", $vmf->pgoff);
}

probe kernel.function("find_get_page")
{
	if (execname() != "hello") next;
	printf("%s: find_get_page\n", execname());
	printf("Page: %lu\n", $offset);
}
=====

Here's filemap_fault() (at least my version of it):

====
int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
	int error;
	struct file *file = vma->vm_file;
	struct address_space *mapping = file->f_mapping;
	struct file_ra_state *ra = &file->f_ra;
	struct inode *inode = mapping->host;
	pgoff_t offset = vmf->pgoff;
	struct page *page;
	pgoff_t size;
	int ret = 0;

	size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
	if (offset >= size)
		return VM_FAULT_SIGBUS;

	/*
	 * Do we have something in the page cache already?
	 */
	page = find_get_page(mapping, offset);
====

Based on that, filemap_fault() can return before calling
find_get_page(), so your calls may not be matching up like you think
they do.

You might try something like this (untested), and see what happens:

=====
global handled

probe kernel.function("filemap_fault")
{
	if (execname() != "hello") next;
	printf("%s: filemap_fault\n", execname());
	printf("Page: %lu\n", $vmf->pgoff);
	handled[tid()] = 1
}
probe kernel.function("filemap_fault").return
{
	delete handled[tid()]
}

probe kernel.function("find_get_page")
{
	if (handled[tid()] != 1) next;
	printf("%s: find_get_page\n", execname());
	printf("Page: %lu\n", $offset);
}
=====

-- 
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]