Questions about process state manipulation
Hi All, I had a question about manipulating process state information in the kernel and am curious about the right way to go about it. (I'm just messing around with some stuff to try and understand the kernel better). I had 2 questions: 1. I'm trying to create a process in the TASK_INTERRUPTIBLE state in the kernel. Since do_fork() creates a process/task that is ready to be scheduled, I was thinking what might be a good way to pull it off the runqueue/stop its execution after do_fork() returns? 2.I'm curious if someone can explain the correct way to use the "set_task_state()" macro. Its implementation just seems to boil down to an assignment to the appropriate member of the task_struct. The question I had in mind was, what if the process is already running? Is it safe to do it? Don't we need to acquire some sort of lock before we manipulate a task_struct ? 3. I would also be interested to read the correct way to use task_lock() that locks on alloc_lock field of the task_struct. What exactly is this lock for and does acquiring it/or any other lock in the task_struct cause the process to be remoted from the runqueue? Would appreciate any pointers to appropriate code/reading or any explanation. Thanks, -- Amit Gupta
On Tue, Sep 18, 2012 at 9:32 AM, Amit Gupta <gupta.v.amit@gmail.com> wrote:
Hi All,
I had a question about manipulating process state information in the kernel and am curious about the right way to go about it. (I'm just messing around with some stuff to try and understand the kernel better). I had 2 questions:
1. I'm trying to create a process in the TASK_INTERRUPTIBLE state in the kernel. Since do_fork() creates a process/task that is ready to be scheduled, I was thinking what might be a good way to pull it off the runqueue/stop its execution after do_fork() returns?
Assuming you do the change in the do_fork() so that new process moves to sleep queue Whatever new process created made to TASK_INTERRUPTIBLE in the do fork, who will wakeup the new process. If you just type "ls" commnad also it does not work as ls command calls fork() + exec(). So your shell fork() and moves to sleep queue. Similarly lot of fork+exec activities happen in the system will all move to sleep queue. Many deamons running on the system may do fork() or fork + exec() will stop working.
2.I'm curious if someone can explain the correct way to use the "set_task_state()" macro. Its implementation just seems to boil down to an assignment to the appropriate member of the task_struct. The question I had in mind was, what if the process is already running? Is it safe to do it? Don't we need to acquire some sort of lock before we manipulate a task_struct ?
set_task_state() macro is used for portability reason. Earlier code shows direct manipulaation fo task_struct->state. When you execute wait_interruptile() family calls, it is the running process in kernel executes set_task_state() .
3. I would also be interested to read the correct way to use task_lock() that locks on alloc_lock field of the task_struct. What exactly is this lock for and does acquiring it/or any other lock in the task_struct cause the process to be remoted from the runqueue?
Would appreciate any pointers to appropriate code/reading or any explanation. Thanks, -- Amit Gupta
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Hi Kshemendra, I think I couldn't get my first question across clearly. My intent isn't to change do_fork()'s implementation. That wont work for precisely the reason you mentioned.(Infact everything after the init process would end up blocked). My question was more to explore if an existing running process can be explicitly taken off the runqueue once we have a pointer to its task_struct. Thanks for the info on the second question. (Although what family of calls were you referring to by wait_interruptile()?) Amit On Mon, Sep 17, 2012 at 11:24 PM, Kshemendra KP <kshemendra@suphalaam.com>wrote:
On Tue, Sep 18, 2012 at 9:32 AM, Amit Gupta <gupta.v.amit@gmail.com>wrote:
Hi All,
I had a question about manipulating process state information in the kernel and am curious about the right way to go about it. (I'm just messing around with some stuff to try and understand the kernel better). I had 2 questions:
1. I'm trying to create a process in the TASK_INTERRUPTIBLE state in the kernel. Since do_fork() creates a process/task that is ready to be scheduled, I was thinking what might be a good way to pull it off the runqueue/stop its execution after do_fork() returns?
Assuming you do the change in the do_fork() so that new process moves to sleep queue Whatever new process created made to TASK_INTERRUPTIBLE in the do fork, who will wakeup the new process. If you just type "ls" commnad also it does not work as ls command calls fork() + exec(). So your shell fork() and moves to sleep queue. Similarly lot of fork+exec activities happen in the system will all move to sleep queue. Many deamons running on the system may do fork() or fork + exec() will stop working.
2.I'm curious if someone can explain the correct way to use the "set_task_state()" macro. Its implementation just seems to boil down to an assignment to the appropriate member of the task_struct. The question I had in mind was, what if the process is already running? Is it safe to do it? Don't we need to acquire some sort of lock before we manipulate a task_struct ?
set_task_state() macro is used for portability reason. Earlier code shows direct manipulaation fo task_struct->state. When you execute wait_interruptile() family calls, it is the running process in kernel executes set_task_state() .
3. I would also be interested to read the correct way to use task_lock() that locks on alloc_lock field of the task_struct. What exactly is this lock for and does acquiring it/or any other lock in the task_struct cause the process to be remoted from the runqueue?
Would appreciate any pointers to appropriate code/reading or any explanation. Thanks, -- Amit Gupta
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-- Amit Gupta
Hi Amit On Wed, Sep 19, 2012 at 4:49 AM, Amit Gupta <gupta.v.amit@gmail.com> wrote:
Hi Kshemendra,
I think I couldn't get my first question across clearly. My intent isn't to change do_fork()'s implementation. That wont work for precisely the reason you mentioned.(Infact everything after the init process would end up blocked).
My question was more to explore if an existing running process can be explicitly taken off the runqueue once we have a pointer to its task_struct.
If you simply want to stop a running process and resume it at your will, you don't need to write any kernel code at all. Simply use the cgroup freezer functionality from userspace. You can find more details in Documentation/cgroups/freezer-subsystem.txt in the kernel sources. Regards, Srivatsa S. Bhat
Hi Srivatsa, (Thats an interesting pointer. I didnt know about cgroups freeze. Thanks.) However, I'm trying to figure out how the kernel would go about doing it. i.e How the kernel, having a pointer to a task struct, goes about removing something from the runqueue. or bringing something from a TASK_INTERRUPTIBLE/STOPPED state back onto the runqueue. I'm trying to figure this out from looking at the code, but am sort of getting lost. I guess I can rephrase the question as, I dont really need to do it for any other purpose other than understanding how the kernel mechanisms will accomplish it. i.e Doing it from userspace using "kill" or cgroups freeze wont "uncover" this for me. Hope my question is clearer, Thanks for replies guys, Amit On Wed, Sep 19, 2012 at 3:09 AM, Srivatsa Bhat <bhat.srivatsa@gmail.com>wrote:
Hi Amit
On Wed, Sep 19, 2012 at 4:49 AM, Amit Gupta <gupta.v.amit@gmail.com>wrote:
Hi Kshemendra,
I think I couldn't get my first question across clearly. My intent isn't to change do_fork()'s implementation. That wont work for precisely the reason you mentioned.(Infact everything after the init process would end up blocked).
My question was more to explore if an existing running process can be explicitly taken off the runqueue once we have a pointer to its task_struct.
If you simply want to stop a running process and resume it at your will, you don't need to write any kernel code at all. Simply use the cgroup freezer functionality from userspace. You can find more details in Documentation/cgroups/freezer-subsystem.txt in the kernel sources.
Regards, Srivatsa S. Bhat
-- Amit Gupta
Hi Amit, An executin task can be is interrupted by interrupts Timer interrupt updates all the time related things in the sytem. One of the path where scheduler is invoked is Timer Softirq. Scheduler verifies whether the current executing tasks time slice is over, or any other task that has higher priority than this task is eligible to run. If any of them is true scheduler selects the other task to run. Regards Kshemendra On Thu, Sep 20, 2012 at 4:40 AM, Amit Gupta <gupta.v.amit@gmail.com> wrote:
Hi Srivatsa,
(Thats an interesting pointer. I didnt know about cgroups freeze. Thanks.)
However, I'm trying to figure out how the kernel would go about doing it. i.e How the kernel, having a pointer to a task struct, goes about removing something from the runqueue. or bringing something from a TASK_INTERRUPTIBLE/STOPPED state back onto the runqueue.
I'm trying to figure this out from looking at the code, but am sort of getting lost.
I guess I can rephrase the question as, I dont really need to do it for any other purpose other than understanding how the kernel mechanisms will accomplish it. i.e Doing it from userspace using "kill" or cgroups freeze wont "uncover" this for me.
Hope my question is clearer,
Thanks for replies guys, Amit
On Wed, Sep 19, 2012 at 3:09 AM, Srivatsa Bhat <bhat.srivatsa@gmail.com>wrote:
Hi Amit
On Wed, Sep 19, 2012 at 4:49 AM, Amit Gupta <gupta.v.amit@gmail.com>wrote:
Hi Kshemendra,
I think I couldn't get my first question across clearly. My intent isn't to change do_fork()'s implementation. That wont work for precisely the reason you mentioned.(Infact everything after the init process would end up blocked).
My question was more to explore if an existing running process can be explicitly taken off the runqueue once we have a pointer to its task_struct.
If you simply want to stop a running process and resume it at your will, you don't need to write any kernel code at all. Simply use the cgroup freezer functionality from userspace. You can find more details in Documentation/cgroups/freezer-subsystem.txt in the kernel sources.
Regards, Srivatsa S. Bhat
-- Amit Gupta
On Thu, Sep 20, 2012 at 10:45 AM, Kshemendra KP <kshemendra@suphalaam.com>wrote:
Hi Amit,
An executin task can be is interrupted by interrupts Timer interrupt updates all the time related things in the sytem. One of the path where scheduler is invoked is Timer Softirq. Scheduler verifies whether the current executing tasks time slice is over, or any other task that has higher priority than this task is eligible to run. If any of them is true scheduler selects the other task to run.
Regards
Kshemendra
On Thu, Sep 20, 2012 at 4:40 AM, Amit Gupta <gupta.v.amit@gmail.com>wrote:
Hi Srivatsa,
(Thats an interesting pointer. I didnt know about cgroups freeze. Thanks.)
However, I'm trying to figure out how the kernel would go about doing it. i.e How the kernel, having a pointer to a task struct, goes about removing something from the runqueue. or bringing something from a TASK_INTERRUPTIBLE/STOPPED state back onto the runqueue.
I'm trying to figure this out from looking at the code, but am sort of getting lost.
I guess I can rephrase the question as, I dont really need to do it for any other purpose other than understanding how the kernel mechanisms will accomplish it. i.e Doing it from userspace using "kill" or cgroups freeze wont "uncover" this for me.
Hope my question is clearer,
Thanks for replies guys, Amit
On Wed, Sep 19, 2012 at 3:09 AM, Srivatsa Bhat <bhat.srivatsa@gmail.com>wrote:
Hi Amit
On Wed, Sep 19, 2012 at 4:49 AM, Amit Gupta <gupta.v.amit@gmail.com>wrote:
Hi Kshemendra,
I think I couldn't get my first question across clearly. My intent isn't to change do_fork()'s implementation. That wont work for precisely the reason you mentioned.(Infact everything after the init process would end up blocked).
My question was more to explore if an existing running process can be explicitly taken off the runqueue once we have a pointer to its task_struct.
If you simply want to stop a running process and resume it at your will, you don't need to write any kernel code at all. Simply use the cgroup freezer functionality from userspace. You can find more details in Documentation/cgroups/freezer-subsystem.txt in the kernel sources.
Regards, Srivatsa S. Bhat
-- Amit Gupta
kernel/sched/core.c -> __schedule() has the implemetnation
participants (3)
-
Amit Gupta -
Kshemendra KP -
Srivatsa Bhat