[haiku-commits] r36033 - in haiku/trunk: headers/private/kernel/vm src/system/kernel/vm

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 5 Apr 2010 13:08:02 +0200 (CEST)

Author: bonefish
Date: 2010-04-05 13:08:01 +0200 (Mon, 05 Apr 2010)
New Revision: 36033
Changeset: http://dev.haiku-os.org/changeset/36033/haiku
Ticket: http://dev.haiku-os.org/ticket/5680

Modified:
   haiku/trunk/headers/private/kernel/vm/VMArea.h
   haiku/trunk/src/system/kernel/vm/VMArea.cpp
   haiku/trunk/src/system/kernel/vm/vm.cpp
Log:
* Removed the VMArea::Wire() version that has to allocate a VMAreaWiredRange.
  Since the requirement is that the area's top cache is locked, allocating
  memory isn't allowed.
* lock_memory_etc(): Create the VMAreaWiredRange object explicitly before
  locking the area's top cache.

Fixes #5680 (deadlocks when using the slab as malloc() backend).


Modified: haiku/trunk/headers/private/kernel/vm/VMArea.h
===================================================================
--- haiku/trunk/headers/private/kernel/vm/VMArea.h      2010-04-05 10:46:08 UTC 
(rev 36032)
+++ haiku/trunk/headers/private/kernel/vm/VMArea.h      2010-04-05 11:08:01 UTC 
(rev 36033)
@@ -94,7 +94,6 @@
                        bool                            IsWired(addr_t base, 
size_t size) const;
 
                        void                            Wire(VMAreaWiredRange* 
range);
-                       VMAreaWiredRange*       Wire(addr_t base, size_t size, 
bool writable);
                        void                            
Unwire(VMAreaWiredRange* range);
                        void                            Unwire(addr_t base, 
size_t size, bool writable);
 

Modified: haiku/trunk/src/system/kernel/vm/VMArea.cpp
===================================================================
--- haiku/trunk/src/system/kernel/vm/VMArea.cpp 2010-04-05 10:46:08 UTC (rev 
36032)
+++ haiku/trunk/src/system/kernel/vm/VMArea.cpp 2010-04-05 11:08:01 UTC (rev 
36033)
@@ -106,25 +106,6 @@
 }
 
 
-/*!    Adds a wired range to this area.
-       The area's top cache must be locked.
-
-       \return The newly created wired area object. \c NULL when out of memory.
-*/
-VMAreaWiredRange*
-VMArea::Wire(addr_t base, size_t size, bool writable)
-{
-       VMAreaWiredRange* range = new(std::nothrow) VMAreaWiredRange(base, size,
-               writable, true);
-       if (range == NULL)
-               return NULL;
-
-       Wire(range);
-
-       return range;
-}
-
-
 /*!    Removes the given wired range from this area.
        Must balance a previous Wire() call.
        The area's top cache must be locked.

Modified: haiku/trunk/src/system/kernel/vm/vm.cpp
===================================================================
--- haiku/trunk/src/system/kernel/vm/vm.cpp     2010-04-05 10:46:08 UTC (rev 
36032)
+++ haiku/trunk/src/system/kernel/vm/vm.cpp     2010-04-05 11:08:01 UTC (rev 
36033)
@@ -4792,17 +4792,23 @@
                addr_t areaStart = nextAddress;
                addr_t areaEnd = std::min(lockEndAddress, area->Base() + 
area->Size());
 
-               // Lock the area's top cache. This is a requirement for 
VMArea::Wire().
-               VMCacheChainLocker 
cacheChainLocker(vm_area_get_locked_cache(area));
-
-               // mark the area range wired
-               VMAreaWiredRange* range = area->Wire(areaStart, areaEnd - 
areaStart,
-                       writable);
+               // allocate the wired range (do that before locking the cache 
to avoid
+               // deadlocks)
+               uint32 mallocFlags = isUser
+                       ? 0 : HEAP_DONT_WAIT_FOR_MEMORY | 
HEAP_DONT_LOCK_KERNEL_SPACE;
+               VMAreaWiredRange* range = new(malloc_flags(mallocFlags))
+                       VMAreaWiredRange(areaStart, areaEnd - areaStart, 
writable, true);
                if (range == NULL) {
                        error = B_NO_MEMORY;
                        break;
                }
 
+               // Lock the area's top cache. This is a requirement for 
VMArea::Wire().
+               VMCacheChainLocker 
cacheChainLocker(vm_area_get_locked_cache(area));
+
+               // mark the area range wired
+               area->Wire(range);
+
                // Depending on the area cache type and the wiring, we may not 
need to
                // look at the individual pages.
                if (area->cache_type == CACHE_TYPE_NULL


Other related posts:

  • » [haiku-commits] r36033 - in haiku/trunk: headers/private/kernel/vm src/system/kernel/vm - ingo_weinhold