On Fri, 31 Mar 2000, Donald Becker wrote:
> Huh? This message confuses me: is request_irq() not module locking safe?
>
> If it is not, that is a signifcant semantic change.
All it is is that request_irq calls kmalloc, which can sleep. So it's
fine to call request_irq in foo_open (obviously!), but you just have to be
careful about locking. All these bugs are likely bugs in 2.2 as well,
incidentally..
The problem is that module locking relies on the big kernel lock, which is
automagically released when a process sleeps in the kernel (and locked
again when it wakes up).
The message I referred to in my previous mail was posted on 30th Jan 2000
with the subject "Please review all modules for unload races":
[...]
Many modules are violating this requirement by doing work that can
sleep before they issue MOD_INC_USE_COUNT, this code leaves itself
open to races. For example, this code is wrong
static int open_foo(struct inode *inode, struct file *file)
{
if (request_irq(FOO_IRQ, foo_interrupt, 0, "FOO", NULL))
return -EBUSY;
MOD_INC_USE_COUNT;
return 0;
}
request_irq calls kmalloc(,GFP_KERNEL) which can sleep. While it
is sleeping, open_foo loses the kernel lock, allowing other
routines such as delete_module to run. The module use count has
not been incremented yet so as far as delete_module is concerned,
the foo module is not in use and can be removed. But request_irq
will eventually return into the foo module after the module has
been deleted - Oops. The code must be rewritten this way
static int open_foo(struct inode *inode, struct file *file)
{
MOD_INC_USE_COUNT; /* must be first */
if (request_irq(FOO_IRQ, foo_interrupt, 0, "FOO", NULL)) {
MOD_DEC_USE_COUNT; /* failure path */
return -EBUSY;
}
return 0;
}
This is the only way to ensure that the code is protected by the
big kernel lock all the way through and therefore cannot be removed
in mid flight.
[...]
So it's not a semantic change, it's just that it never _has_ been safe.
Tim.
*/
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]