lkml.org 
[lkml]   [2005]   [Sep]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: Unusually long delay in the kernel
On Fri, 16 Sep 2005, Andrew Morton wrote:

> Alan Stern <stern@rowland.harvard.edu> wrote:
> >
> > This code excerpt is taken from the start of the control thread for the
> > usb-storage driver in 2.6.14-rc1:
> >
> >
> > static int usb_stor_control_thread(void * __us)
> > {
> > struct us_data *us = (struct us_data *)__us;
> > struct Scsi_Host *host = us_to_host(us);
> >
> > printk(KERN_INFO "Before thread start\n");
> > lock_kernel();
> >
> > /*
> > * This thread doesn't need any user-level access,
> > * so get rid of all our resources.
> > */
> > daemonize("usb-storage");
> > current->flags |= PF_NOFREEZE;
> > unlock_kernel();
> > printk(KERN_INFO "After thread start\n");
> >
> >
> > The code between the two printk's takes a long time to run. I don't have
> > precise numbers, but it feels like more than 1 second.
> >
> > (1) Can anyone explain why, or indicate how to speed it up?
>
> What's it doing at the time? (kgdb is great for this sort of thing: hit
> ^C, go for a wander through the thread callchains).
>
> Presumably it's spinning on the bkl. Is this actually an SMP machine? If
> so, perhaps some other process is holding the bkl for a long time. Perhaps
> a netdevice spending a long time diddling hardware in an ioctl, something
> like that.

I need to do more precise tests. Some quick informal tests indicated that
the lock_kernel call and the daemonize call each took a noticeable time.
I'll respond later with more details.

> > (2) Are the {un}lock_kernel calls really needed?
>
> Definitely not.

Good; I'll take them out.

> That code could be converted to the kthread API btw.

Hmph. Near as I can tell, the only changes that would involve are:

Converting the thread creation call from kernel_thread to
kthread_run.

Adding another call to wake the thread up once it has been
created.

Removing the call to daemonize.

There wouldn't be any need to call kthread_stop -- and in fact it wouldn't
work, as the thread waits on a semaphore while it is idle (kthread_stop
can't cope with things like that).

So overall, it appears that converting to the kthread API would add the
overhead of an extra context switch at startup and synchronous
termination, without bringing any advantages at all.


That reminds me, I've got another question. Once a thread has called
daemonize, or if it was started using kthread_run, all its signals are
blocked. Is it still possible that through some extraordinary
circumstance the thread could receive a signal, or are we absolutely
guaranteed that no signals will arrive until the thread enables them?
It's important to know the answer, because normally a thread spends its
idle time waiting on down_interruptible or something similar. If a signal
managed to get through somehow, the thread would never be able to go back
to sleep unless it explicitly flushed its signals.

(I ask because I once noticed, looking through the signal-processing code,
that the kernel itself could send an unblockable signal. Don't recall
where or when, though.)

Alan Stern

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-09-18 00:17    [W:0.087 / U:0.032 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site