Re: Unusually long delay in the kernel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 16 Sep 2005, Andrew Morton wrote:

> Alan Stern <[email protected]> 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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux