【Linux】窥探Linux内核task_struct结构体

我们知道,进程是程序的动态运行实例。且CPU会对这些进程进行调度,使得程序得以执行。那么如果有多个进程同时要求执行,CPU如何判断该执行哪一个,执行多长时间等等问题呢。学习过操作系统的话,应该能知道对于每一个进程,都有一个进程控制块(PCB),维护对应进程的一些信息。在Linux内核,这个PCB就是一个名为task_struct的结构体。本篇博客,主要就是介绍构成task_struct结构体的成员。

1.进程状态

volatile long state; 

表示进程运行时的状态,-1表示不可运行,0表示可运行,>0表示已经停止。
state的可能取值如下:
TASK_RUNNING:表示进程要么正在执行,要么正要准备执行(已经就绪),正在等待cpu时间片的调度。
TASK_INTERRUPTIBLE:表示进程因为等待一些条件而被挂起(阻塞)而所处的状态。这些条件主要包括:硬中断、资源、一些信号……,一旦等待的条件成立,进程就会从该状态(阻塞)迅速转化成为就绪状态TASK_RUNNING(执行或准备执行态)。
TASK_UNINTERRUPTIBLE:意义与上一个类似对于处于此状态的进程,即使传递一个信号或者有一个外部中断都不能唤醒他们。只有它所等待的资源可用的时候,它才会被唤醒。这个标志很少用,但是并不代表没有任何用处,其实他的作用非常大,特别是对于驱动刺探相关的硬件过程很重要,这个刺探过程不能被一些其他的东西给中断,否则就会让进程进入不可预测的状态。
TASK_STOPPED:表示进程被停止执行,当进程接收到SIGSTOP、SIGTTIN、SIGTSTP或者SIGTTOU信号之后就会进入该状态。
TASK_TRACED:表示进程被debugger等进程监视,进程执行被调试程序所停止,当一个进程被另外的进程所监视,每一个信号都会让进程进入该状态。

2.进程标志

unsigned long flags;

进程当前的标志状态,但不是运行状态,用于内核识别进程当前的状态,以备下一步操作。
flags可能取值如下:
PF_FORKNOEXEC 进程刚创建,但还没执行。
PF_SUPERPRIV 超级用户特权。
PF_DUMPCORE dumped core。
PF_SIGNALED 进程被信号(signal)杀出。
PF_EXITING 进程开始关闭。

3.进程优先级

int prio, static_prio, normal_prio; 
unsigned int rt_priority;

表示此进程的运行优先级

prio:表示动态优先级,根据static_prio和交互性奖罚算出。

static_prio:进程的静态优先级,在进程创建时确定,范围从-20到19,越小优先级越高。

normal_prio的优先级取决于静态优先级和调度策略。rt_priority用于保存实时优先级,范围是0到MAX_RT_PRIO-1(即99)。

4.进程标识符

pid_t pid;
pid_t tgid;

pid进程标识符,相当于每一个学生的学号一样,标识符唯一标识进程。
tpid是线程组号。

5.进程内核栈

void *stack;

进程内核栈。Linux内核通过thread_union联合体来表示进程的内核栈,其中THREAD_SIZE宏的大小为8192。 通过alloc_thread_info函数分配它的内核栈,通过free_thread_info函数释放所分配的内核栈。

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

6.进程的亲属关系

struct task_struct *real_parent; /* real parent process */
struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports */
/*
* children/sibling forms the list of my natural children
 */
struct list_head children;  /* list of my children */
struct list_head sibling;   /* linkage in my parent's children list */
struct task_struct *group_leader;   /* threadgroup leader */

real_parent——是进程的“亲生父亲”。如果创建进程的父进程不再存在,则指向PID为1的init进程
parent——是进程的父进程。进程终止时,必须向它的父进程发送信号。它的值通常与real_parent相同。
children——表示链表的头部,链表中的所有元素都是它的子进程。
sibling——用于把当前进程插入到兄弟链表中。
group_leader——指向其所在进程组的领头进程

7.ptrace系统调用

unsigned int ptrace;

ptrace 提供了一种父进程可以控制子进程运行,并可以检查和改变它的核心image。
它主要用于实现断点调试。一个被跟踪的进程运行中,直到发生一个信号,则进程被中止,并且通知其父进程。在进程中止的状态下,进程的内存空间可以被读写。父进程还可以使子进程继续执行,并选择是否是否忽略引起中止的信号。成员ptrace被设置为0时表示不需要被跟踪。

8.调度策略相关

const struct sched_class *sched_class;
struct sched_entity se;
struct sched_rt_entity rt;

sched_class:调度类
se:普通进程的调用实体,每个进程都有其中之一的实体
rt:实时进程的调用实体,每个进程都有其中之一的实体

9.进程地址空间

struct mm_struct *mm, *active_mm;

mm:进程所拥有的用户空间内存描述符,内核线程无的mm为NULL
active_mm:指向进程运行时所使用的内存描述符, 对于普通进程而言,这两个指针变量的值相同。但是内核线程kernel thread是没有进程地址空间的,所以内核线程的tsk->mm域是空(NULL)。但是内核必须知道用户空间包含了什么,因此它的active_mm成员被初始化为前一个运行进程的active_mm值。

10.判断标志

int exit_code, exit_signal;
int pdeath_signal;  /*  The signal sent when the parent dies  */
/* ??? */
unsigned int personality;
unsigned did_exec:1;
unsigned in_execve:1;   /* Tell the LSMs that the process is doing an
                 * execve */
unsigned in_iowait:1;

exit_code:用于设置进程的终止代号,这个值要么是_exit()或exit_group()系统调用参数(正常终止),要么是由内核提供的一个错误代号(异常终止)。
exit_signal:被置为-1时表示是某个线程组中的一员。只有当线程组的最后一个成员终止时,才会产生一个信号,以通知线程组的领头进程的父进程。
personality:用于处理不同的ABI,参见Linux-Man。
did_exec:用于记录进程代码是否被execve()函数所执行。
in_execve:用于通知LSM是否被do_execve()函数所调用。
in_iowait:用于判断是否进行iowait计数。
11.时间

cputime_t utime, stime, utimescaled, stimescaled;
cputime_t gtime;
cputime_t prev_utime, prev_stime;
unsigned long nvcsw, nivcsw; /* context switch counts */
struct timespec start_time;         /* monotonic time */
struct timespec real_start_time;    /* boot based time */
/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
unsigned long min_flt, maj_flt;

struct task_cputime cputime_expires;
struct list_head cpu_timers[3];

utime/stime:用于记录进程在用户态/内核态下所经过的节拍数(定时器)。
utimescaled/stimescaled:用于记录进程在用户态/内核态的运行时间,但它们以处理器的频率为刻度。
gtime:以节拍计数的虚拟机运行时间(guest time)。
prev_utime/prev_stime:是先前的运行时间,请参考补丁说明http://lkml.indiana.edu/hypermail/linux/kernel/1003.3/02431.html
nvcsw/nivcsw:自愿(voluntary)/非自愿(involuntary)上下文切换计数。
start_time、real_start_time:都是进程创建时间,real_start_time还包含了进程睡眠时间,常用于/proc/pid/stat,补丁说明请参考http://lkml.indiana.edu/hypermail/linux/kernel/0705.0/2094.html
cputime_expires:用来统计进程或进程组被跟踪的处理器时间,其中的三个成员对应着cpu_timers[3]的三个链表。
min_flt,maj_flt:缺页统计。

12.信号处理

struct signal_struct *signal;
struct sighand_struct *sighand;
sigset_t blocked, real_blocked;
sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */
struct sigpending pending;

unsigned long sas_ss_sp;
size_t sas_ss_size;
int (*notifier)(void *priv);
void *notifier_data;
sigset_t *notifier_mask;

signal:指向进程的信号描述符。
sighand:指向进程的信号处理程序描述符。
blocked:表示被阻塞信号的掩码,real_blocked表示临时掩码。
pending:存放私有挂起信号的数据结构。
sas_ss_sp:是信号处理程序备用堆栈的地址,sas_ss_size表示堆栈的大小。
notifier_data/notifier_mask:设备驱动程序常用notifier指向的函数来阻塞进程的某些信号(notifier_mask是这些信号的位掩码),notifier_data指的是notifier所指向的函数可能使用的数据。

13.其他

(1)用于保护资源分配或释放的自旋锁

/* Protection of (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed,
 * mempolicy */
spinlock_t alloc_lock;

(2)进程描述符使用计数,被置为2时,表示进程描述符正在被使用而且其相应的进程处于活动状态。

atomic_t usage;

(3)用于表示获取大内核锁的次数,如果进程未获得过锁,则置为-1。

int lock_depth;     /* BKL lock depth */

(4)在SMP上帮助实现无加锁的进程切换(unlocked context switches)

#ifdef CONFIG_SMP  
#ifdef __ARCH_WANT_UNLOCKED_CTXSW  
    int oncpu;  
#endif  
#endif

(5)preempt_notifier结构体链表

#ifdef CONFIG_PREEMPT_NOTIFIERS  
    /* list of struct preempt_notifier: */  
    struct hlist_head preempt_notifiers;  
#endif

(6)FPU使用计数

unsigned char fpu_counter; 

(7)、blktrace是一个针对Linux内核中块设备I/O层的跟踪工具。

#ifdef CONFIG_BLK_DEV_IO_TRACE  
    unsigned int btrace_seq;  
#endif 

(8)RCU同步原语

#ifdef CONFIG_PREEMPT_RCU  
    int rcu_read_lock_nesting;  
    char rcu_read_unlock_special;  
    struct list_head rcu_node_entry;  
#endif /* #ifdef CONFIG_PREEMPT_RCU */  
#ifdef CONFIG_TREE_PREEMPT_RCU  
    struct rcu_node *rcu_blocked_node;  
#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */  
#ifdef CONFIG_RCU_BOOST  
    struct rt_mutex *rcu_boost_mutex;  
#endif /* #ifdef CONFIG_RCU_BOOST */

(9)用于调度器统计进程的运行信息

#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)  
    struct sched_info sched_info;  
#endif 

(10)、用于构建进程链表

struct list_head tasks;  

(11)、防止内核堆栈溢出

#ifdef CONFIG_CC_STACKPROTECTOR  
    /* Canary value for the -fstack-protector gcc feature */  
    unsigned long stack_canary;  
#endif 

(12)PID散列表和链表

/* PID/PID hash table linkage. */  
struct pid_link pids[PIDTYPE_MAX];  
struct list_head thread_group; //线程组中所有进程的链表 

(13)do_fork函数

struct completion *vfork_done;      /* for vfork() */  
int __user *set_child_tid;      /* CLONE_CHILD_SETTID */  
int __user *clear_child_tid;        /* CLONE_CHILD_CLEARTID */

在执行do_fork()时,如果给定特别标志,则vfork_done会指向一个特殊地址。
如果copy_process函数的clone_flags参数的值被置为CLONE_CHILD_SETTID或CLONE_CHILD_CLEARTID,则会把child_tidptr参数的值分别复制到set_child_tid和clear_child_tid成员。这些标志说明必须改变子进程用户态地址空间的child_tidptr所指向的变量的值。

(14)进程权能

const struct cred __rcu *real_cred; /* objective and real subjective task 
                 * credentials (COW) */  
const struct cred __rcu *cred;  /* effective (overridable) subjective task 
                 * credentials (COW) */  
struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */

(15)相应的程序名

char comm[TASK_COMM_LEN]

(16)文件

/* file system info */  
    int link_count, total_link_count;  
/* filesystem information */  
    struct fs_struct *fs;  
/* open file information */  
    struct files_struct *files; 

fs:用来表示进程与文件系统的联系,包括当前目录和根目录。\
files:表示进程当前打开的文件。

(17)进程通信(SYSVIPC)

#ifdef CONFIG_SYSVIPC  
/* ipc stuff */  
    struct sysv_sem sysvsem;  
#endif 

(18)处理器特有数据

struct thread_struct thread;  

(19)命名空间

struct nsproxy *nsproxy; 

(20)进程审计

 struct audit_context *audit_context;  
#ifdef CONFIG_AUDITSYSCALL  
    uid_t loginuid;  
    unsigned int sessionid;  
#endif 

(21)secure computing

seccomp_t seccomp; 

(22)用于copy_process函数使用CLONE_PARENT 标记时

   /* Thread group tracking */  
       u32 parent_exec_id;  
       u32 self_exec_id;  

(23)中断

   #ifdef CONFIG_GENERIC_HARDIRQS  
       /* IRQ handler threads */  
       struct irqaction *irqaction;  
   #endif  
   #ifdef CONFIG_TRACE_IRQFLAGS  
       unsigned int irq_events;  
       unsigned long hardirq_enable_ip;  
       unsigned long hardirq_disable_ip;  
       unsigned int hardirq_enable_event;  
       unsigned int hardirq_disable_event;  
       int hardirqs_enabled;  
       int hardirq_context;  
       unsigned long softirq_disable_ip;  
       unsigned long softirq_enable_ip;  
       unsigned int softirq_disable_event;  
       unsigned int softirq_enable_event;  
       int softirqs_enabled;  
       int softirq_context;  
   #endif  

(24)task_rq_lock函数所使用的锁

  /* Protection of the PI data structures: */  
   raw_spinlock_t pi_lock;  

(25)基于PI协议的等待互斥锁,其中PI指的是priority inheritance(优先级继承)

   #ifdef CONFIG_RT_MUTEXES  
       /* PI waiters blocked on a rt_mutex held by this task */  
       struct plist_head pi_waiters;  
       /* Deadlock detection and priority inheritance handling */  
      struct rt_mutex_waiter *pi_blocked_on;  
  #endif  

(26)死锁检测

  #ifdef CONFIG_DEBUG_MUTEXES  
      /* mutex deadlock detection */  
     struct mutex_waiter *blocked_on;  
   #endif  

(27)lockdep,参见内核说明文档linux-2.6.38.8/Documentation/lockdep-design.txt

   #ifdef CONFIG_LOCKDEP  
   # define MAX_LOCK_DEPTH 48UL  
       u64 curr_chain_key;  
       int lockdep_depth;  
       unsigned int lockdep_recursion;  
       struct held_lock held_locks[MAX_LOCK_DEPTH];  
       gfp_t lockdep_reclaim_gfp;  
   #endif 

(28)JFS文件系统

  /* journalling filesystem info */  
       void *journal_info;  

(29)块设备链表

  /* stacked block device info */  
      struct bio_list *bio_list;  

(30)内存回收

   struct reclaim_state *reclaim_state; 

(31)存放块设备I/O数据流量信息

   struct backing_dev_info *backing_dev_info; 

(32)I/O调度器所使用的信息

   struct io_context *io_context;  

(33)CPUSET功能

   #ifdef CONFIG_CPUSETS  
       nodemask_t mems_allowed;    /* Protected by alloc_lock */  
       int mems_allowed_change_disable;  
       int cpuset_mem_spread_rotor;  
       int cpuset_slab_spread_rotor;  
   #endif 

(34)Control Groups

   #ifdef CONFIG_CGROUPS  
       /* Control Group info protected by css_set_lock */  
      struct css_set __rcu *cgroups;  
       /* cg_list protected by css_set_lock and tsk->alloc_lock */  
       struct list_head cg_list;  
   #endif  
   #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */  
      struct memcg_batch_info {  
      int do_batch;   /* incremented when batch uncharge started */  
      struct mem_cgroup *memcg; /* target memcg of uncharge */  
      unsigned long bytes;        /* uncharged usage */  
      unsigned long memsw_bytes; /* uncharged mem+swap usage */  
       } memcg_batch;  
   #endif  

(35)futex同步机制

   #ifdef CONFIG_FUTEX  
       struct robust_list_head __user *robust_list;  
   #ifdef CONFIG_COMPAT  
       struct compat_robust_list_head __user *compat_robust_list;  
   #endif  
       struct list_head pi_state_list;  
      struct futex_pi_state *pi_state_cache;  
  #endif  

(36)非一致内存访问(NUMA Non-Uniform Memory Access)

   #ifdef CONFIG_NUMA  
       struct mempolicy *mempolicy;    /* Protected by alloc_lock */  
       short il_next;  
   #endif  

(37)文件系统互斥资源

   atomic_t fs_excl;   /* holding fs exclusive resources */  

(38)RCU链表

  struct rcu_head rcu;  

(39)管道

  struct pipe_inode_info *splice_pipe; 

(40)延迟计数

  1. #ifdef  CONFIG_TASK_DELAY_ACCT  
  2.     struct task_delay_info *delays;  
  3. #endif 

(41)fault injection,参考内核说明文件linux-2.6.38.8/Documentation/fault-injection/fault-injection.txt

   #ifdef CONFIG_FAULT_INJECTION  
       int make_it_fail;  
   #endif  

以下是摘自Linux内核2.6.32版的task_struct源码。

struct task_struct {
    volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
    void *stack;
    atomic_t usage;
    unsigned int flags; /* per process flags, defined below */
    unsigned int ptrace;

    int lock_depth;     /* BKL lock depth */

#ifdef CONFIG_SMP
#ifdef __ARCH_WANT_UNLOCKED_CTXSW
    int oncpu;
#endif
#endif

    int prio, static_prio, normal_prio;
    unsigned int rt_priority;
    const struct sched_class *sched_class;
    struct sched_entity se;
    struct sched_rt_entity rt;

#ifdef CONFIG_PREEMPT_NOTIFIERS
    /* list of struct preempt_notifier: */
    struct hlist_head preempt_notifiers;
#endif

    /*
     * fpu_counter contains the number of consecutive context switches
     * that the FPU is used. If this is over a threshold, the lazy fpu
     * saving becomes unlazy to save the trap. This is an unsigned char
     * so that after 256 times the counter wraps and the behavior turns
     * lazy again; this to deal with bursty apps that only use FPU for
     * a short time
     */
    unsigned char fpu_counter;
#ifdef CONFIG_BLK_DEV_IO_TRACE
    unsigned int btrace_seq;
#endif

    unsigned int policy;
    cpumask_t cpus_allowed;

#ifdef CONFIG_TREE_PREEMPT_RCU
    int rcu_read_lock_nesting;
    char rcu_read_unlock_special;
    struct rcu_node *rcu_blocked_node;
    struct list_head rcu_node_entry;
#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */

#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
    struct sched_info sched_info;
#endif

    struct list_head tasks;
    struct plist_node pushable_tasks;

    struct mm_struct *mm, *active_mm;

/* task state */
    int exit_state;
    int exit_code, exit_signal;
    int pdeath_signal;  /*  The signal sent when the parent dies  */
    /* ??? */
    unsigned int personality;
    unsigned did_exec:1;
    unsigned in_execve:1;   /* Tell the LSMs that the process is doing an
                 * execve */
    unsigned in_iowait:1;


    /* Revert to default priority/policy when forking */
    unsigned sched_reset_on_fork:1;

    pid_t pid;
    pid_t tgid;

#ifdef CONFIG_CC_STACKPROTECTOR
    /* Canary value for the -fstack-protector gcc feature */
    unsigned long stack_canary;
#endif

    /* 
     * pointers to (original) parent process, youngest child, younger sibling,
     * older sibling, respectively.  (p->father can be replaced with 
     * p->real_parent->pid)
     */
    struct task_struct *real_parent; /* real parent process */
    struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports */
    /*
     * children/sibling forms the list of my natural children
     */
    struct list_head children;  /* list of my children */
    struct list_head sibling;   /* linkage in my parent's children list */
    struct task_struct *group_leader;   /* threadgroup leader */

    /*
     * ptraced is the list of tasks this task is using ptrace on.
     * This includes both natural children and PTRACE_ATTACH targets.
     * p->ptrace_entry is p's link on the p->parent->ptraced list.
     */
    struct list_head ptraced;
    struct list_head ptrace_entry;

    /*
     * This is the tracer handle for the ptrace BTS extension.
     * This field actually belongs to the ptracer task.
     */
    struct bts_context *bts;

    /* PID/PID hash table linkage. */
    struct pid_link pids[PIDTYPE_MAX];
    struct list_head thread_group;

    struct completion *vfork_done;      /* for vfork() */
    int __user *set_child_tid;      /* CLONE_CHILD_SETTID */
    int __user *clear_child_tid;        /* CLONE_CHILD_CLEARTID */

    cputime_t utime, stime, utimescaled, stimescaled;
    cputime_t gtime;
    cputime_t prev_utime, prev_stime;
    unsigned long nvcsw, nivcsw; /* context switch counts */
    struct timespec start_time;         /* monotonic time */
    struct timespec real_start_time;    /* boot based time */
/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
    unsigned long min_flt, maj_flt;

    struct task_cputime cputime_expires;
    struct list_head cpu_timers[3];

/* process credentials */
    const struct cred *real_cred;   /* objective and real subjective task
                     * credentials (COW) */
    const struct cred *cred;    /* effective (overridable) subjective task
                     * credentials (COW) */
    struct mutex cred_guard_mutex;  /* guard against foreign influences on
                     * credential calculations
                     * (notably. ptrace) */
    struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */

    char comm[TASK_COMM_LEN]; /* executable name excluding path
                     - access with [gs]et_task_comm (which lock
                       it with task_lock())
                     - initialized normally by flush_old_exec */
/* file system info */
    int link_count, total_link_count;
#ifdef CONFIG_SYSVIPC
/* ipc stuff */
    struct sysv_sem sysvsem;
#endif
#ifdef CONFIG_DETECT_HUNG_TASK
/* hung task detection */
    unsigned long last_switch_count;
#endif
/* CPU-specific state of this task */
    struct thread_struct thread;
/* filesystem information */
    struct fs_struct *fs;
/* open file information */
    struct files_struct *files;
/* namespaces */
    struct nsproxy *nsproxy;
/* signal handlers */
    struct signal_struct *signal;
    struct sighand_struct *sighand;

    sigset_t blocked, real_blocked;
    sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */
    struct sigpending pending;

    unsigned long sas_ss_sp;
    size_t sas_ss_size;
    int (*notifier)(void *priv);
    void *notifier_data;
    sigset_t *notifier_mask;
    struct audit_context *audit_context;
#ifdef CONFIG_AUDITSYSCALL
    uid_t loginuid;
    unsigned int sessionid;
#endif
    seccomp_t seccomp;

/* Thread group tracking */
    u32 parent_exec_id;
    u32 self_exec_id;
/* Protection of (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed,
 * mempolicy */
    spinlock_t alloc_lock;

#ifdef CONFIG_GENERIC_HARDIRQS
    /* IRQ handler threads */
    struct irqaction *irqaction;
#endif

    /* Protection of the PI data structures: */
    spinlock_t pi_lock;

#ifdef CONFIG_RT_MUTEXES
    /* PI waiters blocked on a rt_mutex held by this task */
    struct plist_head pi_waiters;
    /* Deadlock detection and priority inheritance handling */
    struct rt_mutex_waiter *pi_blocked_on;
#endif

#ifdef CONFIG_DEBUG_MUTEXES
    /* mutex deadlock detection */
    struct mutex_waiter *blocked_on;
#endif
#ifdef CONFIG_TRACE_IRQFLAGS
    unsigned int irq_events;
    int hardirqs_enabled;
    unsigned long hardirq_enable_ip;
    unsigned int hardirq_enable_event;
    unsigned long hardirq_disable_ip;
    unsigned int hardirq_disable_event;
    int softirqs_enabled;
    unsigned long softirq_disable_ip;
    unsigned int softirq_disable_event;
    unsigned long softirq_enable_ip;
    unsigned int softirq_enable_event;
    int hardirq_context;
    int softirq_context;
#endif
#ifdef CONFIG_LOCKDEP
# define MAX_LOCK_DEPTH 48UL
    u64 curr_chain_key;
    int lockdep_depth;
    unsigned int lockdep_recursion;
    struct held_lock held_locks[MAX_LOCK_DEPTH];
    gfp_t lockdep_reclaim_gfp;
#endif

/* journalling filesystem info */
    void *journal_info;

/* stacked block device info */
    struct bio *bio_list, **bio_tail;

/* VM state */
    struct reclaim_state *reclaim_state;

    struct backing_dev_info *backing_dev_info;

    struct io_context *io_context;

    unsigned long ptrace_message;
    siginfo_t *last_siginfo; /* For ptrace use.  */
    struct task_io_accounting ioac;
#if defined(CONFIG_TASK_XACCT)
    u64 acct_rss_mem1;  /* accumulated rss usage */
    u64 acct_vm_mem1;   /* accumulated virtual memory usage */
    cputime_t acct_timexpd; /* stime + utime since last update */
#endif
#ifdef CONFIG_CPUSETS
    nodemask_t mems_allowed;    /* Protected by alloc_lock */
    int cpuset_mem_spread_rotor;
#endif
#ifdef CONFIG_CGROUPS
    /* Control Group info protected by css_set_lock */
    struct css_set *cgroups;
    /* cg_list protected by css_set_lock and tsk->alloc_lock */
    struct list_head cg_list;
#endif
#ifdef CONFIG_FUTEX
    struct robust_list_head __user *robust_list;
#ifdef CONFIG_COMPAT
    struct compat_robust_list_head __user *compat_robust_list;
#endif
    struct list_head pi_state_list;
    struct futex_pi_state *pi_state_cache;
#endif
#ifdef CONFIG_PERF_EVENTS
    struct perf_event_context *perf_event_ctxp;
    struct mutex perf_event_mutex;
    struct list_head perf_event_list;
#endif
#ifdef CONFIG_NUMA
    struct mempolicy *mempolicy;    /* Protected by alloc_lock */
    short il_next;
#endif
    atomic_t fs_excl;   /* holding fs exclusive resources */
    struct rcu_head rcu;

    /*
     * cache last used pipe for splice
     */
    struct pipe_inode_info *splice_pipe;
#ifdef  CONFIG_TASK_DELAY_ACCT
    struct task_delay_info *delays;
#endif
#ifdef CONFIG_FAULT_INJECTION
    int make_it_fail;
#endif
    struct prop_local_single dirties;
#ifdef CONFIG_LATENCYTOP
    int latency_record_count;
    struct latency_record latency_record[LT_SAVECOUNT];
#endif
    /*
     * time slack values; these are used to round up poll() and
     * select() etc timeout values. These are in nanoseconds.
     */
    unsigned long timer_slack_ns;
    unsigned long default_timer_slack_ns;

    struct list_head    *scm_work_list;
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
    /* Index of current stored adress in ret_stack */
    int curr_ret_stack;
    /* Stack of return addresses for return function tracing */
    struct ftrace_ret_stack *ret_stack;
    /* time stamp for last schedule */
    unsigned long long ftrace_timestamp;
    /*
     * Number of functions that haven't been traced
     * because of depth overrun.
     */
    atomic_t trace_overrun;
    /* Pause for the tracing */
    atomic_t tracing_graph_pause;
#endif
#ifdef CONFIG_TRACING
    /* state flags for use by tracers */
    unsigned long trace;
    /* bitmask of trace recursion */
    unsigned long trace_recursion;
#endif /* CONFIG_TRACING */
    unsigned long stack_start;
};
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值