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: Terry Lambert <email@hidden>
- Date: Fri, 7 Aug 2009 19:54:16 -0700
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