Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 May 2008 18:08:20 +0300
From:      Teemu Rinta-aho <teemu@rinta-aho.org>
To:        Mark Tinguely <tinguely@casselton.net>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: copy-on-write anonymous memory?
Message-ID:  <482DA364.7000106@rinta-aho.org>
In-Reply-To: <200805161434.m4GEY6N3082155@casselton.net>
References:  <200805161434.m4GEY6N3082155@casselton.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Mark Tinguely wrote:
> Teemu Rinta-aho wrote (some edits):
> 
>>  I have created a kernel module that stores references to memory objects.
>>  I.e. when a process makes a syscall to the module, it will create a
>>  snapshot of the memory area, and after that the writes from the process to
>>  that memory area should create a shadow object. The next syscall should
>>  again store a pointer to the current topmost shadow object and then the
>>  next write creates yet another shadow object. Etc... When the snapshots
>>  are removed, the shadow chains may collapse normally.
>>
>>  Here's an illustration of what I want (first syscall OK, second one not):
>>
>>       * Legend: U/u = userspace K/k = kernel
>>       *
>>       * U:vm_map_entry_u -> object
>>       *             ||
>>       *           SYSCALL
>>       *             ||
>>       *             \/
>>       * U:vm_map_entry_u -> object_shadow -> object
>>       *                                  /
>>       * K:vm_map_entry_k ----------------
>>       *             ||
>>       *           SYSCALL
>>       *             ||
>>       *             \/
>>       * U:vm_map_entry_u -> object_shadow -> object_shadow -> object
>>       *                                  /                /
>>       * K:vm_map_entry_k ----------------                /
>>       * K:vm_map_entry_k --------------------------------
>>
>>  Now, the problem is that the first snapshot works as it should. However,
>>  the second one doesn't, and  the write goes to the one and same shadow
>>  object, even if I restore MAP_ENTRY_COW and MAP_ENTRY_NEEDS_COPY manually
>>  in my handler function which is storing the snapshot.
>>
>>  Any ideas?
> 
> Usually, a fork() creates the inheritance between parent and child COW memory
> space. Start:
>    vm_map_entry -> object_shadow -> object
> 
> fork():
>    vm_map_entry -> object_shadow -\
>                                    |-> (object_shadow*) -> object
>    vm_map_entry -> object_shadow -/
> 
> This is slightly different from your description/drawing, in the way changes
> are inherited; for example: process 1 is created, process 1 writes page 0.
> process 2 is created. process 1 writes p1 (or p0 again). Your
> description/drawing implies that process 2 see this change from process 1.
> 
> You are not forking over a COW memory area. Sounds like the syscall will have
> manually create the inheritance. You can manually link the object_shadows
> the way you want to get the desired inheritance. Process removals should
> collapse the shadows automatically.
> 
> Matt Dillion wrote a brief VM description
> (http://www.freebsd.org/doc/en_US.ISO8859-1/articles/vm-design/).
> The book, "The Design and Implementation of the 4.4BSD Operating System"
> is another great reference.
> 
> Mark Tinguely

Hi Mark,

thanks a lot. I was just about to write to the list that I found the
solution, to give future Googler's some help :-)

The problem was that of course there is no page fault for every
write to the same page. However, I can manually set the COW flag in the map
entry, and then call pmap_protect() to set the physical page read only.
Then the next write after the syscall will trigger the vm_map_lookup()
and the creation of a shadow object.

So, for now, this problem is solved. I'm about to head towards
new problems now :-)

Best regards,
Teemu Rinta-aho

P.S. Yes I have both the D&I of 4.4BSD and D&I of FreeBSD books,
they're quite good and become understandable after browsing the
code for a while :-)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?482DA364.7000106>