Task_struct is used for keeping necessary information about a process by kernel. Thanks to that structure kernel can suspend a process and after a while proceed with its implementation. But my question is: where is this task_struct stored in memory (I've read about kernel stack, is that one which is in kernel space of virtual address space?)? where does kernel keep a pointer to that structure and that structure after suspending process?
I would appreciate if you give some references to resources where it's described.
PS. I forgot to say the question is about Linux kernel.
In linux, the "process descriptor" is struct task_struct [and some others]. These are stored in kernel address space [above PAGE_OFFSET ] and not in userspace. This is more relevant to 32 bit kernels where PAGE_OFFSET is set to 0xc0000000. Also, the kernel has a single address space mapping of its own.
task_struct is a thingy which makes processes and threads possible. It is how they are made inside. But on a user level, there is no access to task_struct. If you writing your own kernel - then sure you would have to work with it, and with the scheduler.
The task_struct is a relatively large data structure, at around 1.7 kilobytes on a 32- bit machine.
Information about processes is stored under the /proc directory, also called the proc filesystem. In this directory, each process stores its data in a sub-directory named after its PID.
The Linux kernel allocates a task_struct via the kmem_cache facility. For instance in fork.c there is a piece of code responsible for allocating a task struct:
#define alloc_task_struct_node(node) \
kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node)
static struct kmem_cache *task_struct_cachep;
The place where the pointer to the current thread is stored is architecture-dependent. For instance, this is how it works for x86 (arch/x86/include/asm/current.h):
static __always_inline struct task_struct *get_current(void)
{
return percpu_read_stable(current_task);
}
and in PowerPC (arch/powerpc/include/asm/current.h):
static inline struct task_struct *get_current(void)
{
struct task_struct *task;
__asm__ __volatile__("ld %0,%1(13)"
: "=r" (task)
: "i" (offsetof(struct paca_struct, __current)));
return task;
}
You can use the Elixir Cross Reference in order to easily explore the kernel source.
task_struct is allocated with the help of slab allocator. Each task in kernel has kernel stack of either 8kb or 4kb which can never increase or decrease.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With