2002-11-22 09:00:32

by dan carpenter

[permalink] [raw]
Subject: calling schedule() from interupt context

I was running a script to find which functions call schedule() and I across something
strange.

In drivers/net/tokenring/3c359.c xl_interrupt() calls schedule().
The path from xl_interupt to schedule is:
xl_rx ==> netif_rx ==>
kfree_skb ==> __kfree_skb ==>
secpath_put ==> __secpath_destroy ==>
xfrm_state_put ==> __xfrm_state_destroy ==> xfrm_put_type ==>
module_put ==> put_cpu ==> preempt_schedule ==> schedule

The problem is that xl_interrupt is the interrupt handler for the 3c359 driver and
I did not think it was legal to call shedule() from interrupt context.

The second thing is that module_put() has a line that looks like it's decrementing
the module reference count (Is it supposed to do that?):
176 local_dec(&module->ref[cpu].count);

The third thing I was wondering is: xl_interupt is holding a
spin_lock(&xl_priv->xl_lock). I know that you're not supposed to call shedule()
while holding a spin lock, but is it ok to call preempt_schedule()?

thanks,
dan carpenter

--
_______________________________________________
Sign-up for your own FREE Personalized E-mail at Mail.com
http://www.mail.com/?sr=signup

One click access to the Top Search Engines
http://www.exactsearchbar.com/mailcom


2002-11-22 09:05:30

by David Miller

[permalink] [raw]
Subject: Re: calling schedule() from interupt context

From: "dan carpenter" <[email protected]>
Date: Fri, 22 Nov 2002 03:54:41 -0500

module_put ==> put_cpu ==> preempt_schedule ==> schedule

Oh we can't kill module references from interrupts?

Egads... that makes lots of the networking stuff
nearly impossible as SKB's hold references to modules
and thus skb freeing can thus put modules.

2002-11-22 09:07:02

by Robert Love

[permalink] [raw]
Subject: Re: calling schedule() from interupt context

On Fri, 2002-11-22 at 03:54, dan carpenter wrote:

(Next time trim your CC list: none of those poor guys needed this
email..)

> In drivers/net/tokenring/3c359.c xl_interrupt() calls schedule().
> The path from xl_interupt to schedule is:
> xl_rx ==> netif_rx ==>
> kfree_skb ==> __kfree_skb ==>
> secpath_put ==> __secpath_destroy ==>
> xfrm_state_put ==> __xfrm_state_destroy ==> xfrm_put_type ==>
> module_put ==> put_cpu ==> preempt_schedule ==> schedule

Are you actually seeing this code path or is this just what your script
is showing you?

preempt_schedule() will not call schedule() if the preempt_count is
non-zero. Inside an interrupt handler, it is always at least one. So
nothing will drop it to zero, and we will never preempt.

> The third thing I was wondering is: xl_interupt is holding a
> spin_lock(&xl_priv->xl_lock). I know that you're not supposed to call shedule()
> while holding a spin lock, but is it ok to call preempt_schedule()?

Same as above. preempt_schedule() only calls schedule when
preempt_count is zero. It is not if you hold a lock, and it is not
inside an interrupt handler.

Robert Love

2002-11-22 09:09:06

by Robert Love

[permalink] [raw]
Subject: Re: calling schedule() from interupt context

On Fri, 2002-11-22 at 04:09, David S. Miller wrote:
> From: "dan carpenter" <[email protected]>
> Date: Fri, 22 Nov 2002 03:54:41 -0500
>
> module_put ==> put_cpu ==> preempt_schedule ==> schedule
>
> Oh we can't kill module references from interrupts?

No, I think you can. Or at least the put_cpu() will not hurt you.

Inside the interrupt handlers, the preemption count is bumped so
preempt_schedule() will never call schedule().

Robert Love

2002-11-22 15:57:08

by dan carpenter

[permalink] [raw]
Subject: Re: calling schedule() from interupt context

From: Robert Love <[email protected]>

> On Fri, 2002-11-22 at 03:54, dan carpenter wrote:
>
> (Next time trim your CC list: none of those poor guys needed this
> email..)
>

trimmed.

> > In drivers/net/tokenring/3c359.c xl_interrupt() calls schedule().
> > The path from xl_interupt to schedule is:
> > xl_rx ==> netif_rx ==>
> > kfree_skb ==> __kfree_skb ==>
> > secpath_put ==> __secpath_destroy ==>
> > xfrm_state_put ==> __xfrm_state_destroy ==> xfrm_put_type ==>
> > module_put ==> put_cpu ==> preempt_schedule ==> schedule
>
> Are you actually seeing this code path or is this just what your script
> is showing you?
>

ok. I'm an idiot.

The script only checks things at compile time not at runtime. So you are
right, of course, that this couldn't happen in real life because of the
preemp_count.

Thanks for the explanation...

regards,
dan carpenter

--
_______________________________________________
Sign-up for your own FREE Personalized E-mail at Mail.com
http://www.mail.com/?sr=signup

One click access to the Top Search Engines
http://www.exactsearchbar.com/mailcom

2002-11-22 16:04:18

by Robert Love

[permalink] [raw]
Subject: Re: calling schedule() from interupt context

On Fri, 2002-11-22 at 11:04, dan carpenter wrote:

> ok. I'm an idiot.
>
> The script only checks things at compile time not at runtime. So you are
> right, of course, that this couldn't happen in real life because of the
> preemp_count.

Still, neat scripts.

Statically searching code has a lot of applications that run-time
checking does not have. For example, there _are_ a lot of things you do
not want to call from interrupts: down(), kmalloc() without GFP_ATOMIC,
etc. etc.

And could you get it to check for code paths that could possibly
double-acquire the same lock?

etc. etc... be creative.

> Thanks for the explanation...

No problem.

Robert Love

2002-11-24 22:25:28

by Rusty Russell

[permalink] [raw]
Subject: Re: calling schedule() from interupt context

In message <[email protected]> you write:
> From: "dan carpenter" <[email protected]>
> Date: Fri, 22 Nov 2002 03:54:41 -0500
>
> module_put ==> put_cpu ==> preempt_schedule ==> schedule
>
> Oh we can't kill module references from interrupts?

Err, no, that would be insane. get_cpu() & put_cpu() should work
perfectly fine inside interrupts, no?

> Egads... that makes lots of the networking stuff
> nearly impossible as SKB's hold references to modules
> and thus skb freeing can thus put modules.

Relax: modular networking was one of my aims 8)

Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

2002-11-24 22:34:35

by Robert Love

[permalink] [raw]
Subject: Re: calling schedule() from interupt context

On Sun, 2002-11-24 at 16:42, Rusty Russell wrote:

> > Oh we can't kill module references from interrupts?
>
> Err, no, that would be insane. get_cpu() & put_cpu() should work
> perfectly fine inside interrupts, no?

Yes, they do.

Since the preempt_count is bumped on entry to the interrupt handler, it
is always at least one, and thus put_cpu() will never call schedule.

Robert Love