Skip to content

Commit 3e48cb3

Browse files
authored
test(uffd): unregister UFFD range before fd close in cross-process cleanup (#2476)
Add an unregister() helper around UFFDIO_UNREGISTER and call it from the late cmd.Wait() cleanup in configureCrossProcessTest, before the early uffdFd.close() cleanup runs (cleanups are LIFO). Today this is a no-op: no test enables UFFD_FEATURE_EVENT_REMOVE, so the kernel never queues REMOVE events that could keep munmap blocked on un-acked events against a registered range. Pulling this out as its own small change so the upcoming PR that does enable REMOVE events doesn't silently bring along a behavioural test-cleanup change too.
1 parent 9af47c0 commit 3e48cb3

2 files changed

Lines changed: 23 additions & 0 deletions

File tree

packages/orchestrator/pkg/sandbox/uffd/userfaultfd/cross_process_helpers_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,14 @@ func configureCrossProcessTest(t *testing.T, tt testConfig) (*testHandler, error
187187
waitErr == nil,
188188
"unexpected error: %v", waitErr,
189189
)
190+
191+
// Tear down the UFFD registration before the early uffdFd.close()
192+
// cleanup runs. Today this is a no-op (no test enables
193+
// UFFD_FEATURE_EVENT_REMOVE) but a follow-up that does will
194+
// otherwise see munmap block on un-acked REMOVE events queued
195+
// against the still-registered range. Cleanups run LIFO, so
196+
// this fires before the close registered earlier.
197+
assert.NoError(t, unregister(uffdFd, memoryStart, uint64(size)))
190198
})
191199

192200
// pageStatesOnce asks the serving process for a snapshot of its pageTracker

packages/orchestrator/pkg/sandbox/uffd/userfaultfd/fd_helpers_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,21 @@ func configureApi(f Fd, pagesize uint64) error {
4141
return nil
4242
}
4343

44+
// unregister tears down the UFFD registration over [addr, addr+size).
45+
// Used in test cleanup so that any in-flight REMOVE events the kernel
46+
// may have queued (once UFFD_FEATURE_EVENT_REMOVE is enabled in a
47+
// follow-up) don't keep munmap blocked on un-acked events.
48+
func unregister(f Fd, addr uintptr, size uint64) error {
49+
r := newUffdioRange(CULong(addr), CULong(size))
50+
51+
ret, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(f), UFFDIO_UNREGISTER, uintptr(unsafe.Pointer(&r)))
52+
if errno != 0 {
53+
return fmt.Errorf("UFFDIO_UNREGISTER ioctl failed: %w (ret=%d)", errno, ret)
54+
}
55+
56+
return nil
57+
}
58+
4459
// mode: UFFDIO_REGISTER_MODE_WP|UFFDIO_REGISTER_MODE_MISSING
4560
// This is already called by the FC, but only with the UFFDIO_REGISTER_MODE_MISSING
4661
// We need to call it with UFFDIO_REGISTER_MODE_WP when we use both missing and wp

0 commit comments

Comments
 (0)