Page MenuHomeFreeBSD

vm_page: use lookup_ge in grab_valid_iter()
ClosedPublic

Authored by dougm on Thu, May 29, 6:54 PM.
Tags
None
Referenced Files
F119837313: D50601.id156272.diff
Thu, Jun 12, 3:37 PM
F119823989: D50601.id156283.diff
Thu, Jun 12, 1:03 PM
Unknown Object (File)
Tue, Jun 10, 12:37 AM
Unknown Object (File)
Mon, Jun 9, 12:09 PM
Unknown Object (File)
Sat, May 31, 7:07 PM
Subscribers

Details

Summary

To improve performance slightly, use vm_radix_iter_lookup_ge to skip over several missing pages at once in grab_valid_iter().

Test Plan

Buildworld testing shows this code rarely used after startup. So, the numbers before world building starts are

Original:
debug.counters.grab_valid_cycles: 323418
debug.counters.grab_valid_calls: 122

Modified;
debug.counters.grab_valid_cycles: 298258
debug.counters.grab_valid_calls: 121

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

dougm requested review of this revision.Thu, May 29, 6:54 PM
dougm created this revision.
dougm retitled this revision from vm_page: use lookup_range in grab_vaid_iter() to vm_page: use lookup_range in grab_valid_iter().
dougm edited the summary of this revision. (Show Details)
dougm edited the test plan for this revision. (Show Details)

@alc advises that having lookup_range return a positive value in this case will be rare, and testing shows that. So, instead of using lookup_range to find a bunch of pages, try using lookup_ge to quickly identify a range of missing pages.

dougm retitled this revision from vm_page: use lookup_range in grab_valid_iter() to vm_page: use lookup_ge in grab_valid_iter().

Don't let ahead exceed after.

sys/vm/vm_page.c
4956

Don't you only want to test vm_page_any_valid(m) || !vm_page_tryxbusy(m) if m->pindex == pindex + i?

4958

Buildworld testing shows this code rarely used after startup.

It's used a lot for I/O to tmpfs mounts, and for sendfile. These aren't exercised by buildworld, though you could try mounting the src and obj trees in tmpfs to cover the first case.

dougm marked 2 inline comments as done.
sys/vm/vm_page.c
4956

I meant, shouldn't we check the valid bits and busy the page at pindex + i before the loop, assuming it exists?

sys/vm/vm_page.c
4956

I can write it that way. I think "i < ahead" and "m->pindex != pindex + i" are both ways to test for early exit from the inner loop.

4956

Currently, if the first non-NULL page is at pindex + 2, we would alloc pindex+1, and then break if page pindex+2 was any_valid or !tryxbusy, and 'after' would be set to 2. If I understand your suggestion properly, it would have us break if page pindex+2 was any_valid or !trybusy, and then 'after' would be set to 1, with nothing allocated. That's a change in behavior of the function. I'm only seeking to improve the performance of the function without changing its behavior. Is this a desirable behavior change?

markj added inline comments.
sys/vm/vm_page.c
4956

To be clear, I think the previous version of this patch had a bug: it could potentially busy a resident page that's far beyond the end of the range designated by after.

I think this version is right, earlier I had just missed how the m->pindex != pindex + i check ensures that we only busy the page at pindex + ahead. It also catches an early break from the inner loop.

This revision is now accepted and ready to land.Fri, May 30, 10:47 PM
alc added inline comments.
sys/vm/vm_page.c
4977

We have not reset the iterator.

This revision was automatically updated to reflect the committed changes.