COW and mprotect on non-shared memory
Luoqi Chen
lchen at briontech.com
Wed Aug 6 13:40:23 PDT 2003
> For that reason, when you mprotect an area of non-shared, anonymous
> memory to no access and then back to writable, Linux has no way of
> knowing that the memory wasn't set for COW before you make it
> unwritable. It goes ahead and makes all the pages in the area COW.
>
> That means that if I do this:
>
> for (i = 0; i < n; ++i) {
> assert(!mprotect(p, pgsiz, PROT_NONE));
> assert(!mprotect(p, pgsiz, PROT_READ|PROT_WRITE|PROT_EXEC));
> p[i] = i & 0xff;
> }
>
> ... I get n minor page faults! Pretty amazing, but I guess they
> figured nobody does that.
>
> More surprising is that the same test program has the same behavior on
> FreeBSD. (At least, the "/usr/bin/time -l ..." output shows the
> number of page reclaims increasing at the same rate that I increase
> the value of n in the loop.)
>
> I thought that in FreeBSD any COW area would have its own vm_map_entry
> with the MAP_ENTRY_COW bit set. That way, you could run this test
> without any minor faults at all. Now I suspect I was incorrect.
> Could anyone help clarify the situation for me?
>
> Thanks.
>
> --
> --Ed L Cashin | PGP public key:
> ecashin at uga.edu | http://noserose.net/e/pgp/
>
The first mprotect() removes the physical mapping from the page table,
the second mprotect() doesn't do anything because the mapping isn't
there. So when the page is accessed, a fault is needed to insert the
mapping back to the page table.
-lq
More information about the freebsd-hackers
mailing list