Copy-on-write page accounting (source code)

= Copy-on-write page accounting

Assume exactly two <operating-system processes>, $N$ initially resident private <memory pages> of $P$ <bytes> each, initially distinct <page frames> shared by A and B. Neither unmaps, exits, forks again, or encounters <page replacement>; no other owner exists, allocation succeeds, and a first write copies one whole shared <memory page>. Once a <page frame> is exclusively owned it is reused on writes, without another copy; writable mappings remain writable. Count data storage only, excluding <page tables> and other bookkeeping. With B as the only writer, writing $k$ distinct <memory pages> gives
$$
\text{new allocations}=\text{whole-page copies}=k,\qquad \text{resident data bytes}=(N+k)P.
$$
This depends on distinct written <memory pages>, not the number of store instructions or reads. For the diagrams, take $N=3$ and an illustrative $P=4096$ <bytes>:

|| Access pattern
|| New <page frames>
|| Whole-page copies
|| Resident data <bytes>

| Both only read
| 0
| 0
| 12288

| B writes <memory page> `0x12` once
| 1
| 1
| 16384

| B writes <memory page> `0x12` one hundred times
| 1
| 1
| 16384

| B writes <memory pages> `0x12` and `0x14`
| 2
| 2
| 20480

| B writes all three <memory pages>
| 3
| 3
| 24576

| B then A each write <memory page> `0x12`
| 1
| 1
| 16384

For both writers, let $S_A,S_B$ be the <sets> of initial <memory page> numbers written by A and B. Under these assumptions, new allocations and copies both equal $|S_A\cup S_B|$, the <cardinality> of their <set union>, while resident data storage is $(N+|S_A\cup S_B|)P$. Each initially shared <page frame> needs at most one split: after the first writer copies it, the other owns the original exclusively. Both writing the same <memory page> therefore produces two versions with one copy, even if the final values happen to match. The last row can incur two protection <page faults>, one for each writer, while making only one copy. A handler that always allocates on a protected write can make a second copy and free the now-unreferenced original: allocation counts and final resident storage are different observables.

These are model counts, not measured Linux costs or a guaranteed bound on total <computer memory>. More descendants, other owners, <demand paging>, <page replacement>, different <memory page> sizes, and different exclusive-ownership rules change the accounting. The useful claim is conditional: deferred data copying can cost in proportion to the distinct shared <memory pages> that are written, while creating separate <page tables> has its own cost.

// Target: computer-science.bigb