Re: kernel thread preemption

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

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Fri, 31 Oct 2003 21:43:21 +0900
Shinpei Kato <shinny@j02.itscom.net> wrote:


>> In  2.4, a  process running  in the  kernel (whether  its  a normal
>> process  or  a  kernel   thread)  cannot  be  preempted.   It  only
>> relinquishes the processor when it voluntarily does so.  >

>You mean  a process  running in the  kernel would be  never preempted
>unless it relinquishes the processor voluntarily?
>If so,  I get to have  one concern. There are  several kernel threads
>created  at the  beginning of  kernel processing,  aren't  there? For
>instance, keventd or kapm, etc.
>How  are they  scheduled? I  mean how  they are  switched  to another
>kernel thread if they doens't have I/O-block or any other block?
>Do they have  to relinquish the CPU share  time voluntarily? But they
>wouldn't know when to relinquish, would they?


A kernel thread  can simply be viewed as a  process without user space
context.  If  you  look  it  in  this manner  it's  difficult  not  to
understand that a kernel thread is "passed through the scheduler" just
like any other process. For understanding  it, take a look at the core
of keventd  which is  the kernel thread  which runs the  schedule task
queue.


/*
 * If one of the functions on a task queue re-adds itself
 * to the task queue we call schedule() in state TASK_RUNNING
 */
 for (;;) {
       set_task_state(curtask, TASK_INTERRUPTIBLE);
       add_wait_queue(&context_task_wq, &wait);
       if (TQ_ACTIVE(tq_context))
               set_task_state(curtask, TASK_RUNNING);
       schedule();
       remove_wait_queue(&context_task_wq, &wait);
       run_task_queue(&tq_context);
       wake_up(&context_task_done);
       if (signal_pending(curtask)) {
               while (waitpid(-1, (unsigned int *)0, __WALL|WNOHANG) > 0);
               spin_lock_irq(&curtask->sigmask_lock);
               flush_signals(curtask);
               recalc_sigpending(curtask);
               spin_unlock_irq(&curtask->sigmask_lock);
       }
}

As  you can  see, when  keventd  is scheduled,  it sets  its state  to
TASK_INTERRUPTIBLE, it adds itself  in the context_task wait queue. Do
not  consider  the test  done  by  TQ_ACTIVE  now.  So  let's  suppose
curtask's state is TASK_INTERRUPTIBLE.

After doing  it, it calls schedule()  and so it  relinquishes the CPU.
In  this   moment,  keventd  is   not  schedulable  since  it   is  in
TASK_INTERRUPTIBLE   state.    It   will   become   schedulable   when
someone/something add  a task to  the schedule task queue  so changing
keventd state.

Let's see it. F.e. a driver code calls schedule_task().

int schedule_task(struct tq_struct *task) {
        int ret;
        need_keventd(__FUNCTION__);
        ret = queue_task(task, &tq_context);
        wake_up(&context_task_wq);
        return ret; 
}

It calls queue_task() which simply enques the task and then wake_up().
This  last function  has  the  effect of  setting  keventd's state  to
TASK_RUNNING (please walk by yourself through kernel/sched.c).

So  when there's  a scheduled  task, keventd  MAY be  selected  by the
scheduler.  When it  will be scheduled in, it will  simply run all the
enqueued tasks  and will repeat the  same steps until  your machine is
up.

Hope this helps.

Regards.


- --

Angelo Dell'Aera 'buffer' 
Antifork Research, Inc.	  	http://buffer.antifork.org

PGP information in e-mail header


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQE/orv+pONIzxnBXKIRAoScAJ9x0OHo0dkIgdyDRtNinPiyIBi8HQCeIKrv
SfCzKQ7lrk3LL57D13dJSJs=
=LurC
-----END PGP SIGNATURE-----
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux