Re: [PATCH] coredump: add filesz truncation and filter
Christian Brauner <[email protected]>
| Newsgroups | org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <20260811-achtfach-backpulver-mundart-70a7e5a20ac6@brauner> |
On Fri, Jul 31, 2026 at 10:13:36AM -0700, Jacob Lalonde wrote: > From: Jacob Lalonde <[email protected]> > > This adds opt-in truncation of Coredump segments to > `/proc/pid/coredump_filter`. The primary motivation here is to reduce the > number of zero pages written via pipe to a user space coredump process. In > my testing this reduces coredump size, and thus IO by ~40% at Meta. With > some outliers such as PyTorch's TBE weights being loaded in right before a > crash being closer to 99%. > > We achieve this by having the Kernel not emit the trailing zeros of any > VMA, resulting in a PT_LOAD with filesz < memsz. I verified that both GDB > from v16 onward and trunk LLDB support loading cores with truncated > sections, however LLDB won't report zeros for the truncated region Hey! So I remember having talked to Josef (Bacik) about this a few months ago. He had a similar goal. I don't think this is the right place to fix this, though. coredump_filter allows exclusion/inclusion per-memory-type. So it says which mappings will end up in the dump. And such filters are inherited across fork. The new bit isn't a memory type at all though. All it does is to change the encoding of the data that's sent. So the receiver has to understand the new bit and not the crashing process. This scheme will only work with a subset of debuggers. That's kinda annoying. Basically the tail of a mapping can show up as unavailable memory rather than zeroes. And it's inherited across fork and exec so some unsuspecting crashing process does start generating such coredumps purely because its parent did opt in. Some time ago I added the coredump socket. There's a simple protocol built on top of it. See coredump_req and coredump_ack in include/uapi/linux/coredump.h. The kernel advertises the features it supports in coredump_req->mask. Userspace picks the ones it wants in coredump_ack->mask. It's explicitly extensible. And it's per-coredump. What you want to do can actually be achieved by just using the coredump socket today: Set coredump_filter to 0. The kernel now streams a complete skeleton: ELF header, the full PT_LOAD table and every note. The dumping process then blocks in coredump_sock_wait(). And now the coredump server in userspace can fill in the memory from /proc/<pid>/mem driven by PAGEMAP_SCAN and then writes the sparse file itself (also works with threads as they're also parked and you can always trace threads within your thread-group). That obviously means you have to assemble the ELF in userspace. But you get full control over what memory is collected and how. I find that quite appealing but if you wanted kernel-based zero filtering I have a proposal as well. Right now the mask only carries COREDUMP_{KERNEL,USERSPACE,REJECT,WAIT}. Adding memory options is simple enough. Extend the enum and raise the bit in coredump_sock_request(). Add a new bit COREDUMP_SPARSE to the protocol. The coredump socket stops streaming raw core data and becomes a sequence of records. The coredump server can reassemble the data as needed/wanted. So every__dump_emit() gets a data record and every __dump_skip() becomes a zero record with no payload. That can live entirely fs/coredump.c below binfmt. So it applies to every binfmt and needs no elf knowledge at all.