From owner-freebsd-hackers@FreeBSD.ORG Fri May 16 15:08:18 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 5580E1065672 for ; Fri, 16 May 2008 15:08:18 +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 E8E328FC18 for ; Fri, 16 May 2008 15:08:17 +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 BF8041987F3; Fri, 16 May 2008 18:08:15 +0300 (EEST) Received: from [127.0.0.1] (unknown [IPv6:2001:14b8:400::130]) by smtp.piuha.net (Postfix) with ESMTP id 2DF1E1987F1; Fri, 16 May 2008 18:08:15 +0300 (EEST) Message-ID: <482DA364.7000106@rinta-aho.org> Date: Fri, 16 May 2008 18:08:20 +0300 From: Teemu Rinta-aho User-Agent: Thunderbird 2.0.0.14 (X11/20080505) MIME-Version: 1.0 To: Mark Tinguely References: <200805161434.m4GEY6N3082155@casselton.net> In-Reply-To: <200805161434.m4GEY6N3082155@casselton.net> 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: Fri, 16 May 2008 15:08:18 -0000 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 :-)