Page MenuHomeFreeBSD

Implement sparse core dumps
ClosedPublic

Authored by markj on Sep 29 2020, 6:40 PM.
Tags
None
Referenced Files
Unknown Object (File)
Jan 8 2024, 6:37 PM
Unknown Object (File)
Jan 3 2024, 4:59 AM
Unknown Object (File)
Dec 27 2023, 4:49 AM
Unknown Object (File)
Dec 27 2023, 4:49 AM
Unknown Object (File)
Dec 27 2023, 4:49 AM
Unknown Object (File)
Dec 27 2023, 4:49 AM
Unknown Object (File)
Dec 27 2023, 4:49 AM
Unknown Object (File)
Dec 27 2023, 4:49 AM
Subscribers

Details

Summary

Currently we allocate and map zero-filled anonymous pages when dumping
core. This can result in lots of needless disk I/O and page
allocations. Try to make the core dumper more clever and represent
unbacked ranges of virtual memory by holes in the core dump.

To implement this, we need a way to test whether the pager for a given
virtual page contains the page's contents. This is done using a new
fault flag which causes vm_fault() to give up when it would otherwise
zero-fill an anonymous page.

Then, core_ouput() locates maximal runs of virtual memory that are
either contained or not contained in the backing pager. The former are
written as usual, using vn_rdwr_inchunks(), and the latter are written
by extending the core dump file using VOP_SETATTR. This assumes that
all writes to the core dump file are appending writes, but this is
already assumed by the compressed core dump code.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

markj requested review of this revision.Sep 29 2020, 6:40 PM
markj created this revision.
kib added inline comments.
sys/vm/vm.h
87 ↗(On Diff #77641)

I wonder if it is better to use fault flag for NOFILL instead of prot. There is no strong rule to prefer one to another when you control both, but we are running very close to end of the free bits in vm_prot_t.

This revision is now accepted and ready to land.Sep 29 2020, 8:13 PM
sys/vm/vm.h
87 ↗(On Diff #77641)

I used a prot flag since the change initially was using vm_fault_quick_hold_pages() via the VFS. I think it can become a fault flag.

Add a new fault flag instead of stuffing NOFILL into fault_type.

This revision now requires review to proceed.Sep 29 2020, 9:21 PM
This revision is now accepted and ready to land.Sep 30 2020, 2:09 AM
sys/kern/imgact_elf.c
1560 ↗(On Diff #77653)

I think we probably don't want to distinguish between different error values, the point is to determine whether we transitioned from error1 == KERN_SUCCESS to error1 != KERN_SUCCESS.

1567 ↗(On Diff #77653)

If we're writing out a mapped file and something concurrently truncates it, we'll get EFAULT here, in which case we should probably continue. vn_rdwr_inchunks() can return a resid value so we know where to restart from.

  • Handle EFAULT from core_write(): retry vm_fault(). Fall back to creating a hole if vm_fault() was successful but vn_rdwr_inchunks() returned EFAULT anyway.
  • Simplify handling of vm_fault() errors: we only care about whether the fault was successful or not.
  • Assert that the user address is page-aligned.
This revision now requires review to proceed.Sep 30 2020, 6:48 PM

To me the new runlen loop is more clear.

sys/vm/vm_fault.c
1483 ↗(On Diff #77694)

After re-reading the patch, I somewhat dislike KERN_RESTART there. Right now KERN_RESTART is internal to vm_fault(), and typically means that the fault should be handled other way. It is hard to distinguish leaked internal value against valid return.

For instance, although you do not use vm_fault_trap() with VM_FAULT_NOFILL, should the handling of KERN_RESTART added to the assert at the beginning of the function ?

sys/vm/vm_fault.c
1483 ↗(On Diff #77694)

I think I could reasonably use KERN_OUT_OF_BOUNDS here instead. I agree that KERN_RESTART is a strange choice.

Return KERN_OUT_OF_BOUNDS.

This revision is now accepted and ready to land.Sep 30 2020, 9:23 PM

I ran all of the stress2 tests without observing any problems.

This revision was automatically updated to reflect the committed changes.