- Stack Overflow Public questions & answers
- Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
- Talent Build your employer brand
- Advertising Reach developers & technologists worldwide
- Labs The future of collective knowledge sharing
- About the company

Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Linux kernel, where is the task_struct (process) initialization
I have a homework where I must add some entries to the task_struct and do some things with them. Also, I must initialize an entry to a specific int when the task_struct initialize.
Where is the file/code that task_struct does its first initialization?
I found INIT_TASK.h but there is the first process of the task_struct table. I want to find where each task_struct initializes and defines it's starting values in order to define some numbers to the new entries I inserted.
- linux-kernel

- 2 As this is your homework, we can only give you a bunch of hints. Which system call is used for creating new processes? Where it's defined in kernel sources? Once you know its location, you can look at how task_struct is being initialized (in code). Also, when you know that system call name, you can use Google to find an explanation on how task_struct is initialized in it. You can use LXR to navigate the kernel code. Good luck. – Sam Protsenko Dec 3, 2016 at 18:04
- I do not know which system call is used. I tried fork, do_fork, init_task but I could not find something except init_task.h as I said in my first post. Could you please just tell me either the syscall either the file that I can find the code for task_struct initialization? This is the only thing that I miss in my assignment as I have finished all others. – tzegian Dec 3, 2016 at 19:15
- That is correct. fork() system call is used for creating processes, as can be seen from man 2 fork . Now, using grep tool, find where fork syscall is defined in kernel. Hint: look for SYSCALL_DEFINE0 macro, as fork() takes 0 arguments. Kernel sources can be obtained either from kernel.org (use mainline kernel), or you can use LXR, as suggested earlier. Hint #2 (as discussed above): use fork and task_struct keywords to google for explanation; then search for task_struct in found pages. – Sam Protsenko Dec 3, 2016 at 19:30
I tried fork, do_fork, init_task but I could not find something except init_task.h as I said in my first post. Could you please just tell me either the syscall either the file that I can find the code for task_struct initialization?
You were already on the right track. Now do_fork() as well as the function behind the SYSCALL_DEFINE0(fork) calls _do_fork() , which calls copy_process() , where the new struct task_struct *p is created by p = dup_task_struct(current, node); - thereafter, copy_process() would be a good place for your additions. All this is in the file kernel/fork.c .

Your Answer
Sign up or log in, post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct .
Not the answer you're looking for? Browse other questions tagged linux process linux-kernel kernel or ask your own question .
- The Overflow Blog
- If you want to address tech debt, quantify it first
- Fighting comment spam at Facebook scale (Ep. 602)
- Featured on Meta
- Moderation strike: Results of negotiations
- Our Design Vision for Stack Overflow and the Stack Exchange network
- Call for volunteer reviewers for an updated search experience: OverflowAI Search
- Temporary policy: Generative AI (e.g., ChatGPT) is banned
- Discussions experiment launching on NLP Collective
Hot Network Questions
- How to transfer the scaling to instances?
- Probability approximation and computation given Compound Poisson random variable
- Is there a (proposed) name for Coatlicue's progenitor?
- Are high-starch potatoes hard (low-starch soft)?
- The complexity of checking for short cycles in a graph
- LaTeX macro for summing numbers
- Why are stars made from hydrogen and helium and not other elements?
- Placement of surd with unicode-math is incorrect
- What type of security measure/contingent conditions could make jumping into a portal impossible inside a laboratory?
- Create e virtual layer (points to line) refering to specific rows in attribute table
- Migrating Windows to a new internal drive, changing drive letters?
- Nested radical implementation
- Which airline is liable for compensation in case of missed connection?
- What determines an electret microphone voltage?
- Does Bayesianism give an out for pseudoscience that it shouldn’t deserve?
- Is naturalism the null hypothesis?
- Do interspecies couples exist in Zootopia?
- What do Americans say instead of “can’t be bothered”?
- How can a country force an ambassador to leave
- How did Martha and Jonathan Kent have the information needed to take care of Superman?
- RAID configuration on new server
- Is saturday considered weekday or weekend, or something else?
- Ask for a reduction in conference registration fees
- Drawing Asteroids DVG vector objects
Your privacy
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy .
Stack Exchange Network
Stack Exchange network consists of 183 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Where is the struct task_struct definition in the 2.6.30.5 Linux Kernel?
In the version 2.6.15 kernel, I got that I can rewrite the task_struct in the file (include/linux/sched.h),like:
But, unfortunately, when I upgraded to the version 2.6.30.5, I looked through the same file, I just find a declaration of the task_struct , like:
And I have no idea which file I should refer to for the purpose of specifying my own task_struct ? Can someone help me?
- linux-kernel
2 Answers 2
Use grep or any other search tool to look for the definition:
Or search online at LXR : http://lxr.linux.no/linux+v2.6.30.5/+search?search=task_struct
The structure is still defined in include/linux/sched.h . There's a forward declaration which is used in mutually recursive type definitions, and the definition is further down.

I'm using Debian squeeze. I see a definition in the headers corresponding to my current kernel, in /usr/src/linux-headers-2.6.32-5-common-vserver/include/linux/sched.h . The definition starts with
- So,am i using a unstable version?but do u have any idea where the defination switch to?any hint?thx – kaiwii ho Jan 30, 2012 at 5:44
- @kaiwiiho: Sorry, I'm not sure what you mean. – Faheem Mitha Jan 30, 2012 at 6:03
- i mean that whether version 2.6.15 is not stable.And,i think that the defination must exist in a .c file that delcrates the sched.h.But unfortunately,i have not think out a method to find oute c file.And can u give some hints for me? – kaiwii ho Jan 30, 2012 at 6:12
- @kaiwiiho: Not sure you mean by stable. 2.6.15 is a kernel release. The definition of the struct is in the header file, as far as I can see. What are you looking for? – Faheem Mitha Jan 30, 2012 at 6:36
You must log in to answer this question.
Not the answer you're looking for browse other questions tagged linux linux-kernel ..
- The Overflow Blog
- If you want to address tech debt, quantify it first
- Fighting comment spam at Facebook scale (Ep. 602)
- Featured on Meta
- Moderation strike: Results of negotiations
- Our Design Vision for Stack Overflow and the Stack Exchange network
Hot Network Questions
- Feminist linguistics?
- Was there a German embassy open in 1941 Lisbon?
- Is saturday considered weekday or weekend, or something else?
- Why do V_Na and V_K stay unchanged in Hodgkin-Huxley model?
- RAID configuration on new server
- Express a "not equal to A or B" criterion in Select
- What are the balance implications of removing spell lists?
- 13 puzzles I like
- Can analog bandwidth be modeled as an RC low-pass filter in this way?
- Why do people say 'topless' but not 'topful'?
- Using ParallelTable for assignment
- How to get rid of unwanted InDesign style settings in paragraph style options?
- How can I make Manipulate faster?
- Is quadrature still considered part of numerical analysis?
- The complexity of checking for short cycles in a graph
- What type of security measure/contingent conditions could make jumping into a portal impossible inside a laboratory?
- Is there a socially-optimal way to drive on a busy interstate?
- move the instance collection to the point of contact with the plane?
- Correcting how a student writes symbols
- A fantasy about a man selling his shadow to the Devil
- Nested radical implementation
- How to make physical character's combat become more tactical and interesting?
- What determines an electret microphone voltage?
- Coworker hiding/stealing lab material - advice?
Your privacy
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy .
- View page source
Processes ¶
View slides
Lecture objectives ¶
- Process and threads
- Context switching
- Blocking and waking up
- Process context
Processes and threads ¶
A process is an operating system abstraction that groups together multiple resources:
All this information is grouped in the Process Control Group (PCB). In Linux this is struct task_struct .
Overview of process resources ¶
A summary of the resources a process has can be obtain from the /proc/<pid> directory, where <pid> is the process id for the process we want to look at.
struct task_struct ¶
Lets take a close look at struct task_struct . For that we could just look at the source code, but here we will use a tool called pahole (part of the dwarves install package) in order to get some insights about this structure:
As you can see it is a pretty large data structure: almost 8KB in size and 155 fields.
Inspecting task_struct ¶
The following screencast is going to demonstrate how we can inspect the process control block ( struct task_struct ) by connecting the debugger to the running virtual machine. We are going to use a helper gdb command lx-ps to list the processes and the address of the task_struct for each process.
Quiz: Inspect a task to determine opened files ¶
Use the debugger to inspect the process named syslogd.
- What command should we use to list the opened file descriptors?
- How many file descriptors are opened?
- What command should we use the determine the file name for opened file descriptor 3?
- What is the filename for file descriptor 3?
A thread is the basic unit that the kernel process scheduler uses to allow applications to run the CPU. A thread has the following characteristics:
- Each thread has its own stack and together with the register values it determines the thread execution state
- A thread runs in the context of a process and all threads in the same process share the resources
- The kernel schedules threads not processes and user-level threads (e.g. fibers, coroutines, etc.) are not visible at the kernel level
The typical thread implementation is one where the threads is implemented as a separate data structure which is then linked to the process data structure. For example, the Windows kernel uses such an implementation:

Linux uses a different implementation for threads. The basic unit is called a task (hence the struct task_struct ) and it is used for both tasks and processes. Instead of embedding resources in the task structure it has pointers to these resources.
Thus, if two threads are the same process will point to the same resource structure instance. If two threads are in different processes they will point to different resource structure instances.


The clone system call ¶
In Linux a new thread or process is create with the clone() system call. Both the fork() system call and the pthread_create() function uses the clone() implementation.
It allows the caller to decide what resources should be shared with the parent and which should be copied or isolated:
- CLONE_FILES - shares the file descriptor table with the parent
- CLONE_VM - shares the address space with the parent
- CLONE_FS - shares the filesystem information (root directory, current directory) with the parent
- CLONE_NEWNS - does not share the mount namespace with the parent
- CLONE_NEWIPC - does not share the IPC namespace (System V IPC objects, POSIX message queues) with the parent
- CLONE_NEWNET - does not share the networking namespaces (network interfaces, routing table) with the parent
For example, if CLONE_FILES | CLONE_VM | CLONE_FS is used by the caller than effectively a new thread is created. If these flags are not used than a new process is created.
Namespaces and "containers" ¶
"Containers" are a form of lightweight virtual machines that share the same kernel instance, as opposed to normal virtualization where a hypervisor runs multiple VMs, each with its one kernel instance.
Examples of container technologies are LXC - that allows running lightweight "VM" and docker - a specialized container for running a single application.
Containers are built on top of a few kernel features, one of which is namespaces. They allow isolation of different resources that would otherwise be globally visible. For example, without containers, all processes would be visible in /proc. With containers, processes in one container will not be visible (in /proc or be killable) to other containers.
To achieve this partitioning, the struct nsproxy structure is used to group types of resources that we want to partition. It currently supports IPC, networking, cgroup, mount, networking, PID, time namespaces. For example, instead of having a global list for networking interfaces, the list is part of a struct net . The system initializes with a default namespace ( init_net ) and by default all processes will share this namespace. When a new namespace is created a new net namespace is created and then new processes can point to that new namespace instead of the default one.
Accessing the current process ¶
Accessing the current process is a frequent operation:
- opening a file needs access to struct task_struct 's file field
- mapping a new file needs access to struct task_struct 's mm field
- Over 90% of the system calls needs to access the current process structure so it needs to be fast
- The current macro is available to access to current process's struct task_struct
In order to support fast access in multi processor configurations a per CPU variable is used to store and retrieve the pointer to the current struct task_struct :

Previously the following sequence was used as the implementation for the current macro:
Quiz: previous implementation for current (x86) ¶
What is the size of struct thread_info ?
Which of the following are potential valid sizes for struct thread_info : 4095, 4096, 4097?
Context switching ¶
The following diagram shows an overview of the Linux kernel context switch process:

Note that before a context switch can occur we must do a kernel transition, either with a system call or with an interrupt. At that point the user space registers are saved on the kernel stack. At some point the schedule() function will be called which can decide that a context switch must occur from T0 to T1 (e.g. because the current thread is blocking waiting for an I/O operation to complete or because it's allocated time slice has expired).
At that point context_switch() will perform architecture specific operations and will switch the address space if needed:
Then it will call the architecture specific switch_to implementation to switch the registers state and kernel stack. Note that registers are saved on stack and that the stack pointer is saved in the task structure:
You can notice that the instruction pointer is not explicitly saved. It is not needed because:
a task will always resume in this function the schedule() ( context_switch() is always inlined) caller's return address is saved on the kernel stack a jmp is used to execute __switch_to() which is a function and when it returns it will pop the original (next task) return address from the stack
The following screencast uses the debugger to setup a breaking in __switch_to_asm and examine the stack during the context switch:
Quiz: context switch ¶
We are executing a context switch. Select all of the statements that are true.
- the ESP register is saved in the task structure
- the EIP register is saved in the task structure
- general registers are saved in the task structure
- the ESP register is saved on the stack
- the EIP register is saved on the stack
- general registers are saved on the stack
Blocking and waking up tasks ¶
Task states ¶.
The following diagram shows to the task (threads) states and the possible transitions between them:

Blocking the current thread ¶
Blocking the current thread is an important operation we need to perform to implement efficient task scheduling - we want to run other threads while I/O operations complete.
In order to accomplish this the following operations take place:
- Set the current thread state to TASK_UINTERRUPTIBLE or TASK_INTERRUPTIBLE
- Add the task to a waiting queue
- Call the scheduler which will pick up a new task from the READY queue
- Do the context switch to the new task
Below are some snippets for the wait_event implementation. Note that the waiting queue is a list with some extra information like a pointer to the task struct.
Also note that a lot of effort is put into making sure no deadlock can occur between wait_event and wake_up : the task is added to the list before checking condition , signals are checked before calling schedule() .
Waking up a task ¶
We can wake-up tasks by using the wake_up primitive. The following high level operations are performed to wake up a task:
- Select a task from the waiting queue
- Set the task state to TASK_READY
- Insert the task into the scheduler's READY queue
- On SMP system this is a complex operation: each processor has its own queue, queues need to be balanced, CPUs needs to be signaled
Preempting tasks ¶
Up until this point we look at how context switches occurs voluntary between threads. Next we will look at how preemption is handled. We will start wight the simpler case where the kernel is configured as non preemptive and then we will move to the preemptive kernel case.
Non preemptive kernel ¶
- At every tick the kernel checks to see if the current process has its time slice consumed
- If that happens a flag is set in interrupt context
- Before returning to userspace the kernel checks this flag and calls schedule() if needed
- In this case tasks are not preempted while running in kernel mode (e.g. system call) so there are no synchronization issues
Preemptive kernel ¶
In this case the current task can be preempted even if we are running in kernel mode and executing a system call. This requires using a special synchronization primitives: preempt_disable and preempt_enable .
In order to simplify handling for preemptive kernels and since synchronization primitives are needed for the SMP case anyway, preemption is disabled automatically when a spinlock is used.
As before, if we run into a condition that requires the preemption of the current task (its time slices has expired) a flag is set. This flag is checked whenever the preemption is reactivated, e.g. when exiting a critical section through a spin_unlock() and if needed the scheduler is called to select a new task.
Process context ¶
Now that we have examined the implementation of processes and threads (tasks), how context switching occurs, how we can block, wake-up and preempt tasks, we can finally define what the process context is what are its properties:
The kernel is executing in process context when it is running a system call.
In process context there is a well defined context and we can access the current process data with current
In process context we can sleep (wait on a condition).
In process context we can access the user-space (unless we are running in a kernel thread context).
Kernel threads ¶
Sometimes the kernel core or device drivers need to perform blocking operations and thus they need to run in process context.
Kernel threads are used exactly for this and are a special class of tasks that don't "userspace" resources (e.g. no address space or opened files).
The following screencast takes a closer look at kernel threads:
Using gdb scripts for kernel inspection ¶
The Linux kernel comes with a predefined set of gdb extra commands we can use to inspect the kernel during debugging. They will automatically be loaded as long gdbinit is properly setup
All of the kernel specific commands are prefixed with lx-. You can use TAB in gdb to list all of them:
The implementation of the commands can be found at script/gdb/linux . Lets take a closer look at the lx-ps implementation:
Quiz: Kernel gdb scripts ¶
What is the following change of the lx-ps script trying to accomplish?
You are using an outdated browser. Please upgrade your browser to improve your experience and security.
Linux Audio
Check our new training course
Embedded Linux Audio
Elixir Cross Referencer
Defined in 5 files as a struct:, referenced in 1427 files:.

IMAGES
VIDEO
COMMENTS
If we talk specific to 0x86 architecture, then at the end of task kernel stack, we have thread_info struct which essentially stores/points the task_struct pointer. And task_struct has the kernel stack pointer which can be decreased by 8kb to get thread info struct.
Once you know its location, you can look at how task_struct is being initialized (in code). Also, when you know that system call name, you can use Google to find an explanation on how task_struct is initialized in it. You can use LXR to navigate the kernel code. Good luck. – Sam Protsenko.
Use grep or any other search tool to look for the definition: grep -r '^struct task_struct ' include. Or search online at LXR : http://lxr.linux.no/linux+v2.6.30.5/+search?search=task_struct. The structure is still defined in include/linux/sched.h.
Lets take a close look at struct task_struct. For that we could just look at the source code, but here we will use a tool called pahole (part of the dwarves install package) in order to get some insights about this structure:
task_struct identifier - Linux source code (v6.4.10) - Bootlin. with Creative Commons CC-BY-SA. , line 739 (as a struct) tools/perf/util/bpf_skel/vmlinux.h(as a struct) tools/testing/selftests/bpf/progs/strobemeta.h(as a struct) tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c(as a struct) tools/testing/selftests/bpf/progs/test_core ...