Re: COW and mprotect on non-shared memory
Luoqi Chen [EMAIL PROTECTED] writes: [Ed writes] 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. ... 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. OK, thanks. I can see that in sys/i386/i386/pmap.c. It leaves me wondering what MAP_ENTRY_COW is for, though. -- --Ed L Cashin| PGP public key: [EMAIL PROTECTED]| http://noserose.net/e/pgp/ ___ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to [EMAIL PROTECTED]
RE: COW and mprotect on non-shared memory
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: [EMAIL PROTECTED]| 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 ___ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: COW and mprotect on non-shared memory
On Thu, Aug 07, 2003, Ed L Cashin wrote: Luoqi Chen [EMAIL PROTECTED] writes: [Ed writes] 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. ... 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. OK, thanks. I can see that in sys/i386/i386/pmap.c. It leaves me wondering what MAP_ENTRY_COW is for, though. It's an optimization that makes the map entries and corresponding vm_objects themselves copy-on-write. Specifically, when a process forks, FreeBSD does not allocate new shadow objects immediately. This is deferred until the object needs to be modified, which is usually never if the process subsequently calls exec. ___ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to [EMAIL PROTECTED]