Re: Kernel panics even in OSMalloc_noblock() while holding a spinlock
Re: Kernel panics even in OSMalloc_noblock() while holding a spinlock
- Subject: Re: Kernel panics even in OSMalloc_noblock() while holding a spinlock
- From: Brendan Creane <email@hidden>
- Date: Fri, 7 Aug 2009 23:03:03 -0700
"...no allocation or free inside a spinlock..."
That's actually new information -- previous posts
(http://lists.apple.com/archives/darwin-kernel/2008/Jan/msg00007.html)
do indeed suggest OSMalloc_noblock() as a solution for allocating
memory from within a spinlock.
My reading of OSMalloc_noblock() is that it may block when obtaining
the zone mutex, but it won't wait for any other threads to complete a
memory allocation. So it's more like "OSMalloc_fast()." And yes, it
may panic inside a spinlock, just like OSMalloc().
For those of us porting existing code from operating systems that do
support memory allocation from within lock primitives (Linux,
Windows), we need to be aware that Darwin's design precludes this
approach and consequently may require a significant rewrite of
existing drivers.
regards, Brendan
On Fri, Aug 7, 2009 at 7:54 PM, Terry Lambert<email@hidden> wrote:
> On Aug 7, 2009, at 3:50 PM, Eric Ogren wrote:
>>
>> Hello there -
>>
>> I am working on a kernel extension that sometimes attempts to allocate
>> memory while holding a spinlock (lck_spin_t). I've read in several postings
>> to this list that doing so while OSMalloc can cause a kernel panic, and that
>> developers should instead use OSMalloc_noblock() and be prepared to deal
>> with a NULL result. However, I am seeing kernel panics even when calling
>> the noblock variant. The panic is occurring inside zalloc_canblock() at the
>> lock_zone() call, which is indeed trying to block. This problem is very
>> easily reproducible with a simple kext that spawns 2 threads with the
>> following thread routine:
>>
>> void alloc_thread(void *arg) {
>> lck_spin_t* mylock;
>> // ... initialize lock
>>
>> lck_spin_lock(mylock);
>>
>> while (true) {
>> void* foo = OSMalloc_noblock(8, tag); // tag is a global variable
>> initialized in the start function
>> }
>> }
>>
>> Loading the kext panics the system almost immediately with the following
>> stack, which is the same as the stack as I come across in the occasional
>> panics:
>>
>> #2 0x0012b4c6 in panic (str=0x1 <Address 0x1 out of bounds>) at
>> /SourceCache/xnu/xnu-1228.12.14/osfmk/kern/debug.c:275
>> #3 0x001368fd in thread_invoke (self=0x43018b8, thread=0x39a7c80,
>> reason=0) at /SourceCache/xnu/xnu-1228.12.14/osfmk/kern/sched_prim.c:1477
>
> [ ... ]
>
>
>> Am I missing something here, or is it unsafe to even call
>> OSMalloc_noblock() while holding a spinlock? If I look at the source code
>> for zalloc, lock/unlock_zone() is always called regardless of the canblock
>> parameter, and that zone lock is indeed a mutex. Seems almost like the
>> canblock parameter just means that the calling thread will not block for a
>> long time (ie will not try to refill or garbage collect the zone if it's
>> full), not that it will never block at all.
>
>
> Yes. You are missing several things...
>
> (A) You're in a tight while/true loop allocating all of kernel memory a tiny
> bit at a time until you exhaust it, which is known to cause a panic.
>
> (B) An infinite loop is too long a time to hold a spinlock; holding a
> spinlock too long is known to cause a panic
>
> (C) You're missing your paste of at least the lines above the portion of the
> backtrace you quoted (which is cut off at frame #2), which would include the
> actual panic message and frame #1 so that we could see if the panic was
> related to holding a spinlock or related to you exhausting the zone of
> zones, or running the wrong version of Parallels or dereferencing a NULL
> pointer, or some other known cause of panics, or some other unknown cause of
> panics.
>
> (D) You have already been told you can use Djikstra's algorithm, in which
> you speculatively do an allocation before holding the spinlock, and if you
> use it, fine, mark it as consumed at the point you would have done your
> allocation, and if you don't, fine, free it after you have dropped your
> spinlock, no harm no foul, no allocation or free inside a spinlock
>
> -- Terry
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Darwin-kernel mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden