From owner-freebsd-current Sat Apr 15 21:43:50 2000 Delivered-To: freebsd-current@freebsd.org Received: from cs.rice.edu (cs.rice.edu [128.42.1.30]) by hub.freebsd.org (Postfix) with ESMTP id 2E62A37B86A; Sat, 15 Apr 2000 21:43:45 -0700 (PDT) (envelope-from alc@cs.rice.edu) Received: (from alc@localhost) by cs.rice.edu (8.9.0/8.9.0) id XAA00553; Sat, 15 Apr 2000 23:43:42 -0500 (CDT) Date: Sat, 15 Apr 2000 23:43:42 -0500 From: Alan Cox To: Matthew Dillon Cc: Brian Fundakowski Feldman , current@freebsd.org Subject: Re: panic: vm_object_shadow: source object has OBJ_ONEMAPPING set. Message-ID: <20000415234342.H3462@cs.rice.edu> References: <20000415140945.B3462@cs.rice.edu> <20000415185718.E3462@cs.rice.edu> <200004160313.UAA82143@apollo.backplane.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 0.95.5us In-Reply-To: <200004160313.UAA82143@apollo.backplane.com>; from Matthew Dillon on Sat, Apr 15, 2000 at 08:13:20PM -0700 Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Sat, Apr 15, 2000 at 08:13:20PM -0700, Matthew Dillon wrote: > > :Here's what I worry about: We only clear OBJ_ONEMAPPING on the top-level > :object, and none of its backing objects. Nothing guarantees that these > :backing objects have OBJ_ONEMAPPING cleared. The page that we're "double" > :mapping may, however, reside in one of its backing objects. This is > :bad. > > I don't think this is an issue. The only double-mapped pages we care > about are those at the top-level (vm_object's connected directly to a > vm_map_entry). This is because these are the only pages effected by > write-faults and copy-on-write issues. > I disagree. If a backing object (BO) has OBJ_ONEMAPPING set, and someone call vm_map_delete(map, start, end) on an address space that references BO directly, then the system will crash and burn because vm_map_delete will (incorrectly) free physical pages: ... pmap_remove(map->pmap, s, e); if (object != NULL && object->ref_count != 1 && (object->flags & (OBJ_NOSPLIT|OBJ_ONEMAPPING)) == OBJ_ONEMAPPING && (object->type == OBJT_DEFAULT || object->type == OBJT_SWAP)) { vm_object_collapse(object); vm_object_page_remove(object, offidxstart, offidxend, FALSE); ^^^^^^^^^^^^^^^^^^^^^ The reason why John Dyson introduced OBJ_ONEMAPPING was so that he could know that physical pages were unreferenced (and thus free the pages) even though the object's ref count > 1. He was spurred on by the UVM work, which accomplished the same thing via per-page reference counting. > For example, if you dirty a page that is mapped privately the system must > copy-on-write the page. More importantly, if you fork() and either parent > or child dirties what is now a shared page, they need to copy on write > and the other process cannot see that change. OBJ_ONEMAPPING is an > optimization that allows a process to dirty an anonymous (not vnode-backed) > page without doing a copy-on-write in the case where that process is > the ONLY process mapping the page. > Umm, it can do this without the OBJ_ONEMAPPING attribute, because the ref count on the object == 1. Note that the code from vm_object_shadow doesn't even check OBJ_ONEMAPPING: /* * Don't create the new object if the old object isn't shared. */ if (source != NULL && source->ref_count == 1 && source->handle == NULL && (source->type == OBJT_DEFAULT || source->type == OBJT_SWAP)) return; > Copy-on-write is an issue that only effects the top level object. So > we shouldn't care whether OBJ_ONEMAPPING is set or cleared in deeper > objects. > I do care, because I don't want those pages freed by a vm_map_delete. > Copying a page that was previously shared is an expensive operation not > only in having to do the copy, but also in having to split the vm_map_entry > and create a new holding vm_object to hold the copy. This new object must > have OBJ_ONEMAPPING set so that when pages are dirtied around it, it can > be pre-pended or post-pended with the new pages rather then have to create > a new vm_object (and thus not be able to coalesce the associated > vm_map_entry structures) every time we take a copy-on-write fault. > Huh? It's always been the case that when a shadow object is created, its size is equal to the size of the mapping. This predates the existance of OBJ_ONEMAPPING. vm_map_lookup, where shadow objects are normally created on COW faults, has always done: if (fault_type & VM_PROT_WRITE) { /* * Make a new object, and place it in the object * chain. Note that no new references have appeared * -- one just moved from the map to the new * object. */ if (vm_map_lock_upgrade(map)) goto RetryLookup; vm_object_shadow( &entry->object.vm_object, &entry->offset, atop(entry->end - entry->start)); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ so that pages can be added to the shadow object without creating a new object. > In this respect, the OBJ_ONEMAPPING optimization is *CRITICAL* to the > scaleability of our VM system. > It's not critical. COW worked just fine (performance-wise) before OBJ_ONEMAPPING. John Dyson introduced OBJ_ONEMAPPING so that he could free individual pages within an object earlier, without waiting for the entire object to be freed. Alan To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message