kernel - Fix recently introduced bus error w/postgres scoreboard
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 26 Oct 2011 22:44:13 +0000 (15:44 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 26 Oct 2011 22:44:13 +0000 (15:44 -0700)
* The OBJ_ONEMAPPING flag has to be cleared when forking a shared
  mapping.

* Fixed an issue with the postgres scoreboard.

Reported-by: Studbolt, thesjg
sys/vm/vm_map.c
sys/vm/vm_object.c

index 94e6c02..6165b0b 100644 (file)
@@ -3231,21 +3231,33 @@ vmspace_fork(struct vmspace *vm1)
                        if (old_entry->object.vm_object == NULL)
                                vm_map_entry_allocate_object(old_entry);
 
-                       /*
-                        * Shadow a map_entry which needs a copy, replacing
-                        * its object with a new object that points to the
-                        * old one.  Ask the shadow code to automatically add
-                        * an additional ref.  We can't do it afterwords
-                        * because we might race a collapse
-                        */
                        if (old_entry->eflags & MAP_ENTRY_NEEDS_COPY) {
+                               /*
+                                * Shadow a map_entry which needs a copy,
+                                * replacing its object with a new object
+                                * that points to the old one.  Ask the
+                                * shadow code to automatically add an
+                                * additional ref.  We can't do it afterwords
+                                * because we might race a collapse.  The call
+                                * to vm_map_entry_shadow() will also clear
+                                * OBJ_ONEMAPPING.
+                                */
                                vm_map_entry_shadow(old_entry, 1);
                        } else {
+                               /*
+                                * We will make a shared copy of the object,
+                                * and must clear OBJ_ONEMAPPING.
+                                *
+                                * XXX assert that object.vm_object != NULL
+                                *     since we allocate it above.
+                                */
                                if (old_entry->object.vm_object) {
                                        object = old_entry->object.vm_object;
                                        vm_object_hold(object);
                                        vm_object_chain_wait(object);
                                        vm_object_reference_locked(object);
+                                       vm_object_clear_flag(object,
+                                                            OBJ_ONEMAPPING);
                                        vm_object_drop(object);
                                }
                        }
index 1027a7a..7f0de90 100644 (file)
@@ -1442,8 +1442,8 @@ vm_object_shadow(vm_object_t *objectp, vm_ooffset_t *offset, vm_size_t length,
                     source->type == OBJT_SWAP)) {
                        vm_object_drop(source);
                        if (addref) {
-                               vm_object_clear_flag(source, OBJ_ONEMAPPING);
                                vm_object_reference_locked(source);
+                               vm_object_clear_flag(source, OBJ_ONEMAPPING);
                        }
                        return;
                }