Fundamentals 10 min read

Inside Linux: How the Kernel Represents and Manages Processes with task_struct

This article explains how a user‑level program becomes a Linux process, how the kernel views it through ELF loading, the role of the task_struct data structure, its key fields, task state transitions, and how the kernel stores the descriptor in memory.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Inside Linux: How the Kernel Represents and Manages Processes with task_struct

From Program to Process in the Kernel

A program becomes a process when the ELF executable is handed to the Linux kernel; the kernel then creates a task_struct to represent that process.

Kernel Representation: task_struct

The kernel uses the task_struct structure to store all information about a process, including identifiers, state, scheduling policy, memory management, file descriptors, signals, and more.

struct task_struct {
    volatile long state;               // -1 unrunnable, 0 runnable, >0 stopped
    unsigned long flags;               // process flags, set at fork()
    int sigpending;                    // pending signals
    mm_segment_t addr_limit;           // address limit (user vs kernel)
    volatile long need_resched;        // need reschedule flag
    int lock_depth;                    // lock depth
    long nice;                         // nice value (time slice)
    unsigned long policy;              // scheduling policy (SCHED_FIFO, SCHED_RR, SCHED_OTHER)
    struct mm_struct *mm;              // memory management info
    int processor;                     // CPU the task is running on
    unsigned long cpus_runnable, cpus_allowed;
    struct list_head run_list;        // pointer to run queue
    unsigned long sleep_time;          // sleep time
    struct task_struct *next_task, *prev_task; // doubly linked list (init_task is root)
    struct mm_struct *active_mm;
    struct list_head local_pages;
    unsigned int allocation_order, nr_local_pages;
    struct linux_binfmt *binfmt;      // executable format
    int exit_code, exit_signal;
    int pdeath_signal;                // signal sent to children on parent exit
    unsigned long personality;
    int did_exec:1;
    pid_t pid;                         // process ID
    pid_t pgrp;                        // process group ID
    pid_t tty_old_pgrp;
    pid_t session;                     // session ID
    pid_t tgid;
    int leader;                        // session leader flag
    struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
    struct list_head thread_group;    // thread list
    struct task_struct *pidhash_next; // hash table linkage
    struct task_struct **pidhash_pprev;
    wait_queue_head_t wait_chldexit;   // for wait4()
    struct completion *vfork_done;    // for vfork()
    unsigned long rt_priority;         // real‑time priority
    struct timer_list real_timer;      // real‑time timer
    struct tms times;                  // CPU time accounting
    unsigned long start_time;          // creation time
    long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];
    int swappable:1;                  // can be swapped out?
    int ngroups;                       // number of groups
    gid_t groups[NGROUPS];
    kernel_cap_t cap_effective, cap_inheritable, cap_permitted;
    int keep_capabilities:1;
    struct user_struct *user;
    struct rlimit rlim[RLIM_NLIMITS];
    unsigned short used_math;          // uses FPU?
    char comm[16];                     // executable name
    int link_count, total_link_count;
    struct tty_struct *tty;            // controlling terminal
    unsigned int locks;
    struct sem_undo *semundo;         // semaphore undo info
    struct sem_queue *semsleeping;     // waiting semaphore queue
    struct thread_struct thread;       // CPU context
    struct fs_struct *fs;              // filesystem info
    struct files_struct *files;        // open files
    spinlock_t sigmask_lock;
    struct signal_struct *sig;          // signal handling
    sigset_t blocked;                  // blocked signals mask
    struct sigpending pending;          // pending signals
    /* ... many more fields omitted for brevity ... */
};

Key Information Categories in task_struct

1. Identifier – unique PID and group IDs. 2. State – current task state, exit code, exit signal. 3. Priority – scheduling priority relative to other tasks. 4. Program Counter – address of the next instruction to execute. 5. Memory Pointers – pointers to code, data, and shared memory. 6. Context Data – register contents saved during a context switch. 7. I/O Status – open file list and device information. 8. Accounting – CPU time, clock ticks, limits, and resource usage.

Task State Transitions

The state field uses negative values for non‑runnable, zero for runnable, and positive values for stopped. Common values include:

-1: unrunnable (blocked, sleeping)

0: runnable (ready to run)

>0: stopped (e.g., stopped by a signal)

How the Kernel Stores task_struct

Each process has a user stack and a kernel stack. To save space, Linux places the thread_info structure (which contains a pointer to the task_struct) immediately before the kernel stack, forming a thread_union.

union thread_union {
#ifndef CONFIG_THREAD_INFO_IN_TASK
    struct thread_info thread_info;
#endif
    unsigned long stack[THREAD_SIZE / sizeof(long)];
};

Conclusion

We have seen how a compiled program is transformed into a Linux process, how the kernel describes that process with the massive task_struct, how the structure is organized into logical categories, how task states change, and how the descriptor is stored alongside the kernel stack. Future articles will dive deeper into scheduling, memory management, and other aspects of process control.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Kernelprocess managementLinuxSystems Programmingtask_struct
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.