On 11/6/26 06:18, Andrew Morton wrote: > The second column assumes that the child touches all the file THPs, > yes? If the child touches only a small proportion of those mappings, > or just does fork+exec, that changes the "Cost" comparison?
Yes. I measured it again on bare metal, with a fork()+exec column: x86_64 with 4 NUMA nodes, the benchmark bound to node 0, both kernels v7.4-rc1 with the same config, 4 GB of shmem THPs mapped MAP_PRIVATE with an anon_vma, medians of 2000 forks, range over the rounds. The exec is of /bin/true. +-----------------+------------+-----------------+--------------+ | kernel | fork() | child reads all | fork()+exec | +-----------------+------------+-----------------+--------------+ | v7.4-rc1 | 135-141 us | 3820-4036 us | 559-567 us | | v7.4-rc1+series | 429-440 us | 1007-1036 us | 1190-1226 us | +-----------------+------------+-----------------+--------------+ So a child that execs right away, or touches little, pays about 0.3 us per huge PMD: the copy at fork and the teardown at exec or exit. A child that faults a PMD in itself pays about 1.8 us for it, so the copy wins once the child touches more than about a sixth of them. > And on ppc64 hash-mode setups this also allocates deposited page tables > for mappings which the child might never touch? So a modest increase > in memory use is to be expected? Yes, but a small one, judging from the code (I have no ppc64 to test): one 4 KB page table fragment per copied 16 MB PMD, 1/4096 of the mapping. Radix and other arches deposit nothing. It is freed when the child unmaps the range, execs or exits, and a PMD the child faults in itself deposits the same 4 KB anyway. > But I worry that this change is not an overall win for thp-file > mappings, which are the common case. Only a narrow case pays the extra cost, a file THP that is: - mapped MAP_PRIVATE; - in a VMA written to at least once, so it has an anon_vma; - a PMD-sized folio in the page cache, mapped by one PMD; - itself never written to. For example: - a big data file mapped MAP_PRIVATE that is mostly read and patched in a few places; - a private mapping of a memfd or tmpfs file. The common case does not get here. fork() skips a VMA without an anon_vma and without VM_COPY_ON_FORK (vma_needs_copy()), so shared file mappings and private ones that were never written are still left to faults. In these VMAs fork() already copies the PTEs of the same file folios; only their PMDs were skipped. > I'm not understanding why we need to mess with thp-file behavior at all > in order to address a special-PMD bug? It came from the review of v3: David asked to make copy_huge_pmd() decide the way copy_present_ptes() does, instead of keeping rules of its own for PMDs: https://lore.kernel.org/all/[email protected]/ > Changelog is soooo long. I replaced this Reproducer section with simply > > - A reproducer is at the Link; Sure, thanks. And thanks for the pmd_psize fixup. -- Cheers, Konstantin
