copy-on-write anonymous memory?

Teemu Rinta-aho teemu at rinta-aho.org
Thu May 15 14:51:32 UTC 2008


Teemu Rinta-aho wrote:
> Kostik Belousov wrote:
>> On Thu, May 15, 2008 at 01:20:32PM +0300, Teemu Rinta-aho wrote:
>>> Hi all,
>>>
>>> is it possible to create a memory object that represents
>>> anonymous memory pages *and* is copy-on-write?
>>>
>>> I have this code in a kernel module:
>>>
>>>     object = vm_object_allocate(OBJT_DEFAULT, 1);
>>>
>>>     result = vm_map_find(vmmap_proc,
>>>                          object,
>>>                          0,
>>>                          &addr,
>>>                          len,
>>>                          TRUE,
>>>                          VM_PROT_ALL,
>>>                          VM_PROT_ALL,
>>>                          MAP_COPY_ON_WRITE);
>>>
>>> Then I pass the addr to the user space, but when
>>> I write to the addr, I see no shadow objects created,
>>> i.e. the changes are written to the original memory
>>> pages no matter if I have the map entry set as
>>> copy-on-write or not... I am assuming a write fault would
>>> create a new page and hang it to a shadow object thus
>>> leaving the original memory untouched.
>>>
>>> I'd appreciate any kind of help here.
>> I cannot get a complete handle on your problem without full code, but
>> I guess that you have only one reference to the backing object through
>> the vm map entry. If this is the case, then the shadow copying actually
>> does not make sense since no other users of the object need it.
>>
>> Look at the vm_object_shadow(), check at the start of the function.
> 
> Hi Kostik,
> 
> thanks, that was a good point. Adding a reference helps! :-)
> 
> Thanks for your quick reply,
> 
> Teemu

New problems... Let me first describe what I try to do:

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.
That's what I have assumed.

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?

Teemu


More information about the freebsd-hackers mailing list