Sourav Sen wrote: > > > Martin Maletinsky wrote: > > > > > > Hello Joe, > > > > > > Thanks again for your answer. I have one more question regarding a statement you make in your answer: > > > > > > Joseph A Knapka wrote: > > > > > > > > > > > In this case, A and B will always share page mappings, even > > > > when writing to copy-on-write pages, and C will get its own > > > > copy if/when it attempts to write the page. Here's why: > > > > > > > > In do_fork(), we call copy_mm(), which, in the case of > > > > CLONE_VM being set, just copies the entire mm context > > > > for the new thread, -without- marking anything copy-on-write. > > > > So thread A and thread B both have non-COW mappings. > > > > > > > > When Thread B forks process C, C gets an entirely new MM > > > > context, with -no- user-space PTEs. So in order to write > > > > A+B's virtual page, C takes a "not-present" page fault.regards > > > > > > Why is it that C will have no user-space PTEs in it's MM. I thought at a fork call, the user-space PTEs are copied from the parent's MM into the childs MM, and write protected in both > > > MMs. > > > I concluded that from the following call sequence (in 2.4.10): > > > do_fork() > > > -> copy_mm() > > > --> dup_mmap() [note that since C is created by a call to fork(), CLONE_VM is *not* set, when creating C] > > > ---> copy_page_range() [here the PTEs are copied for one vmarea; both PTEs (child and parent) are write protected at line 256, if the conditions to make them COW are fullfilled]. > > > > > > My understanding was therefore that all physical pages backing A&B's page mapping would now be shared among A&B and C, and write access to this pages (by either A/B or C would cause a > > > copy-on-write). > > > > > > Did I misunderstand somthing in your answer or in the source code? > > > > No, you're right. I didn't read dup_mmap() carefully. Now I don't > > understand it either :-( > > Could you explain the problem here? Now, pages are write > protected, and B (ie, A+B) writes to the page containing the buffer to > which A has initiated read(), gets a new physical page to which old > contents are copied and old virtual address of the buffer(in A+B address > space)are mapped, read() resumes and copy_to_user() copies the remaining > data to this new page, and read() completes normally with the buffer > filled with data. The problem comes if the device is doing a DMA write directly to the user page. In that case doing COW will cause the DMA buffer to mysteriously vanish, from the point of view of the thread that initiated the write. I am taking Martin's word that it's actually possible to do DMA in this way (directly to a user page, bypassing kernel buffers and copy-to-user). If all I/O passes through kernelspace buffers, then there is no problem. I have not studied the I/O system in much detail. Upon further though, though, I think DMA to user pages is probably -not- done, because in general userspace buffers won't be page- or disk-block-boundary aligned, and anyway, all reads and writes must pass through the buffer cache. The stuff I wrote previously in this thread, about COW, was just totally wrong. Contrary to what I wrote earlier, it is critical for both the original process and the forked process to have read-only mappings of COW pages, otherwise race conditions happen and we have a big mess. -- Joe # "You know how many remote castles there are along the # gorges? You can't MOVE for remote castles!" - Lu Tze re. Uberwald # Linux MM docs: http://home.earthlink.net/~jknapka/linux-mm/vmoutline.html - Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ IRC Channel: irc.openprojects.net / #kernelnewbies Web Page: http://www.kernelnewbies.org/