Date: Sat, 15 Apr 2000 11:19:14 -0700 (PDT) From: Matthew Dillon <dillon@apollo.backplane.com> To: Brian Fundakowski Feldman <green@FreeBSD.ORG> Cc: Alfred Perlstein <bright@wintelcom.net>, Michael Reifenberger <root@nihil.plaut.de>, current@FreeBSD.ORG, alc@FreeBSD.ORG Subject: Re: panic: vm_object_shadow: source object has OBJ_ONEMAPPING set. Message-ID: <200004151819.LAA79712@apollo.backplane.com> References: <Pine.BSF.4.21.0004151332140.16430-100000@green.dyndns.org>
next in thread | previous in thread | raw e-mail | index | archive | help
:Further elaboration: : :there is an assumption that it is wrong for OBJ_ONEMAPPING to be set but :not when ref_count > 1. This assumption is defeated in the multiple test :cases we can find. It seems that in the test cases, the common problem :is with (I think mmap()d) memory across multiple processes that _share_ :_a_VM_space_! It seems like what's happening is that the ref_count is :increased to reflect that each process has a hold of this object, which :may or may not be correct, and when that object is faulted on, the code :panics because it assumes that OBJ_ONEMAPPING means that there's only :one mapping of the object, but there are multiple references and so it :panics. : :The question is not just "why" a OBJ_ONEMAPPING object has a ref_count > 1, :it's whether or not that is correct WRT multiple, shared-VM processes. : :-- : Brian Fundakowski Feldman \ FreeBSD: The Power to Serve! / : green@FreeBSD.org `------------------------------' Originally (3.x and before), the OBJ_ONEMAPPING was not set entirely properly and people had hacked the code to use ref_count in combination with it. Alan and I fixed this all last year, but obviously didn't fix all the cases. Now OBJ_ONEMAPPING is the true indicator of there being a single mapping, and ref_count is irrelevant. Or supposed to be irrelevant, anyway. My patch was incorrect. Or, I should say, your original patch is incorrect. I don't think it's legal to put in the (source->flags & OBJ_ONEMAPPING) test that you added in vm_object.c, because OBJ_ONEMAPPING should be clear prior to calling vm_object_shadow anyway (or there's no point in shadowing the object in the first place!). My patch to vm_map.c should do the trick. But there is one more case we have to consider that I am not sure about, and that is the two calls to vm_object_shadow() in vm_map_pageable() (vm_map.c line 1356). vm_map_pageable() is used byvslock/vsunlock, which is used by the sysctl code (???), and used in kmem_alloc() (where OBJ_ONEMAPPING is not set anyway). I think we may have a case where sysctl() operates on a shared address space that may still panic. Here is a new patch. Please try it (and get rid of any prior patches to vm_object.c before applying this one). -Matt Matthew Dillon <dillon@backplane.com> Index: vm_map.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_map.c,v retrieving revision 1.187 diff -u -r1.187 vm_map.c --- vm_map.c 2000/02/28 04:10:35 1.187 +++ vm_map.c 2000/04/15 18:02:06 @@ -2119,10 +2119,14 @@ } /* - * Add the reference before calling vm_object_shadow - * to insure that a shadow object is created. + * Clear OBJ_ONEMAPPING before calling vm_object_shadow + * to ensure that a shadow object is created. Add a + * reference to cover the new vm_map_entry being + * associated with the object. */ vm_object_reference(object); + vm_object_clear_flag(object, OBJ_ONEMAPPING); + if (old_entry->eflags & MAP_ENTRY_NEEDS_COPY) { vm_object_shadow(&old_entry->object.vm_object, &old_entry->offset, @@ -2130,7 +2134,6 @@ old_entry->eflags &= ~MAP_ENTRY_NEEDS_COPY; object = old_entry->object.vm_object; } - vm_object_clear_flag(object, OBJ_ONEMAPPING); /* * Clone the entry, referencing the shared object. Index: vm_object.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_object.c,v retrieving revision 1.171.2.1 diff -u -r1.171.2.1 vm_object.c --- vm_object.c 2000/03/17 10:47:35 1.171.2.1 +++ vm_object.c 2000/04/15 18:13:58 @@ -900,7 +900,13 @@ source = *object; /* - * Don't create the new object if the old object isn't shared. + * If the old object is not shared we may be able to simply use it + * as the shadow rather then have to create a new object. Only + * objects that we can guarentee this case can be optimized - that is, + * only objects with no handles that other processes can get a hold + * of which are otherwise unassociated, have only one mapping, and + * only one reference count. XXX do we need the reference count check + * any more? XXX */ if (source != NULL && To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200004151819.LAA79712>