From owner-freebsd-hackers@FreeBSD.ORG Thu May 15 14:51:32 2008 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B6F401065672 for ; Thu, 15 May 2008 14:51:32 +0000 (UTC) (envelope-from teemu@rinta-aho.org) Received: from smtp.piuha.net (p130.piuha.net [IPv6:2001:14b8:400::130]) by mx1.freebsd.org (Postfix) with ESMTP id 7234E8FC16 for ; Thu, 15 May 2008 14:51:32 +0000 (UTC) (envelope-from teemu@rinta-aho.org) Received: from smtp.piuha.net (localhost [127.0.0.1]) by smtp.piuha.net (Postfix) with ESMTP id E55C41987F5; Thu, 15 May 2008 17:51:30 +0300 (EEST) Received: from [127.0.0.1] (unknown [IPv6:2001:14b8:400::130]) by smtp.piuha.net (Postfix) with ESMTP id B05D5198713; Thu, 15 May 2008 17:51:30 +0300 (EEST) Message-ID: <482C4DF3.8030709@rinta-aho.org> Date: Thu, 15 May 2008 17:51:31 +0300 From: Teemu Rinta-aho User-Agent: Thunderbird 2.0.0.14 (X11/20080505) MIME-Version: 1.0 To: Kostik Belousov References: <482C0E70.4020305@rinta-aho.org> <20080515111847.GX18958@deviant.kiev.zoral.com.ua> <482C2D7C.5070703@rinta-aho.org> In-Reply-To: <482C2D7C.5070703@rinta-aho.org> X-Enigmail-Version: 0.95.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Virus-Scanned: ClamAV using ClamSMTP Cc: freebsd-hackers@freebsd.org Subject: Re: copy-on-write anonymous memory? X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 May 2008 14:51:32 -0000 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