On Tue, 9 Nov 2004, Mike Waychison wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
linux-os wrote:On Tue, 9 Nov 2004, Mike Waychison wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
linux-os wrote:
On Tue, 9 Nov 2004, Mike Waychison wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
linux-os wrote:
I have a memory-test procedure that tests
memory on a board, accessed via the PCI bus.
There is a lot of RAM and it's bank-switched
into some 64k windows so it takes a lot of
time to test, about 60 seconds.
This is in a module, therefore inside the kernel.
When it is invoked via an ioctl() call, the
kernel is frozen for the whole test-time. The
test procedure does not use any spin-locks nor
does it even use any semaphores. It just does a
bunch of read/write operations over the PCI/Bus.
I thought that I could enable the preemptible-
kernel option and the machine would then respond
normally. Not so. Even with 4 CPUs, when one
ioctl() is busy in the kernel, nothing else
happens until its done. Even keyboard activity
is gone, no Caps Lock and no Num Lock, no `ping`
response over the network. However, the machine
comes back to life when the memory-test is done.
This is kernel version 2.6.9. Is it possible that
somebody left on the BKL when calling a module
ioctl() on this version? If not, what do I do
to be able to execute a time-consuming procedure
from inside the kernel? Do I break it up into
sections and execute schedule() periodically
(temporary work-around --works)??
The BKL has always been grabbed across ioctls. Drop the lock when you
enter your f_op->ioctl call and grab it again open completion.
Hmmm. I get 'scheduling while atomic' screaming across the screen!
There are no atomic operations in my ioctl functions so I don't
know what its complaining about. I think I shouldn't have tried
to do anything with BKL because I (my task) doesn't own it.
'Scheduling while atomic' means you called some function that may
schedule itself out while you are holding a spinlock. Note that the BKL
is not a regular spinlock, and scheduling is allowed while holding it.
Please see
http://james.bond.edu.au/courses/inft73626@033/Assigs/Papers/kernel_locking_techniques.html
by Robert Love, the section titled "The Big Kernel Lock"
Something else is wrong with your code.
Not quite. Something is wrong with the e100 network driver used in
2.6.9. When I do:
int ioctl(,,,,)
{
int ret;
unlock_kernel();
ret = original_ioctl(...);
lock_kernel();
return ret;
}
In my driver, completely unrelated to the network.... It's
something in the e100 network driver that the kernel's
complaining about. If I shut down the network and remove
the network driver module I don't have any problems while
enabling BKL. Everything runs fine.
Don't do that. ioctls rightly-assume that the BKL is held when they are
called.
When I said drop the lock, I meant for _your_ ioctl code.
Hmmm. My code didn't do any locking, therefore I don't know
how to, as you say "drop the lock", except how other kernel drivers
do it. If I had any semaphores (which I don't here), or spin-locks
(which I don't), I could certainly unlock anything my code locked.
However, the kernel did something before my code was called.
Therefore, I have no way of undoing it except by calling
unlock_kernel().
Is there some other way?