Linux 3.0.6カーネルtask_structコメント


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

#ifdef CONFIG_SMP
	struct task_struct *wake_entry;
	int on_cpu;   //   CPU   
#endif
	int on_rq;  //on_rq denotes whether the entity is currently scheduled on a run queue or not.


	int prio, static_prio, normal_prio;  //     ,     
/*
the task structure employs three elements to denote the priority of a process: prio
and normal_prio indicate the dynamic priorities, static_prio the static priority of a process.
The static priority is the priority assigned to the process when it was started. It can be modified
with the nice and sched_setscheduler system calls, but remains otherwise constant during the
process’ run time.
normal_priority denotes a priority that is computed based on the static priority and the
scheduling policy of the process. Identical static priorities will therefore result in different
normal priorities depending on whether a process is a regular or a real-time process. When a
process forks, the child process will inherit the normal priority.
However, the priority considered by the scheduler is kept in prio. A third element is required
because situations can arise in which the kernel needs to temporarily boost the priority of a pro-
cess. Since these changes are not permanent, the static and normal priorities are unaffected by
this.
*/
	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;//         CPU   :Cpumasks provide a bitmap suitable 
                               //for representing the set of CPU's in a system, one bit position per CPU number. 
                               // In general, only nr_cpu_ids (<= NR_CPUS) bits are valid.

#ifdef CONFIG_PREEMPT_RCU
	int rcu_read_lock_nesting; //RCU               :http://blog.csdn.net/sunnybeike/article/details/6866473。
	char rcu_read_unlock_special;
#if defined(CONFIG_RCU_BOOST) && defined(CONFIG_TREE_PREEMPT_RCU)
	int rcu_boosted;
#endif /* #if defined(CONFIG_RCU_BOOST) && defined(CONFIG_TREE_PREEMPT_RCU) */
	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 */

#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
	struct sched_info sched_info;   //       ,  CPU      /          。
#endif

	struct list_head tasks;   //    
#ifdef CONFIG_SMP
	struct plist_node pushable_tasks;
#endif

	struct mm_struct *mm, *active_mm;   //mm          
/*  mm active_mm
lazy TLB                             ,     flush TLB;
kernel thread       ,  mm_struct  mm 0,         。 if (unlikely(!mm))             kernel thread,
   ,                 mm_struct  ,             (oldmm) mm_struct      
active_mm( next->active_mm = oldmm;),        anomymous user, atomic_inc(&oldmm->mm_count)           mm_count,
      enter_lazy_tlb    lazeTLB  (MP),  UP              ;
if (unlikely(!prev->mm))                 kernel thread,               mm_struct。
               kernel thread page table  ,    flush   page table    entry 。
       if    mm_struct   mm      ,        mm_struct   active_mm;
  MP  ,    CPU#1    flushTLB   ,     CPU     CPU  kernel thread,   CPU     lazyTLB  ,
   flush TLB,  lazyTLB       ,               PageTable,    flush TLB;   CPU          #1  ,
     flush TLB 

      mm active_mm        ;             ,               ,active_mm = oldmm(     mm), mm = NULL,
(        Linux   78 。)
     :http://www.linuxsir.org/bbs/thread166288.html
*/
#ifdef CONFIG_COMPAT_BRK
	unsigned brk_randomized:1;
#endif
#if defined(SPLIT_RSS_COUNTING)
	struct task_rss_stat	rss_stat;  //RSS is the total memory actually held in RAM for a process.
                                           //     :http://blog.csdn.net/sunnybeike/article/details/6867112
#endif
/* task state */
	int exit_state;  //        
	int exit_code, exit_signal; //          
	int pdeath_signal;  /*  The signal sent when the parent dies  */
	unsigned int group_stop;	/* GROUP_STOP_*, siglock protected */
	/* ??? */
	unsigned int personality;  //  Unix           ,           。
                                   //           ,         , personality.h          
	unsigned did_exec:1;	//  POSIX       ,did_exec                        execve       。
	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;
	unsigned sched_contributes_to_load:1;

	pid_t pid;  //  ID
	pid_t tgid; //   ID

#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;

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

	struct completion *vfork_done;		/* for vfork() */
/*

If the vfork mechanism was used (the kernel recognizes this by the fact that the CLONE_VFORK
flag is set), the completions mechanism of the child process must be enabled. The vfork_done
element of the child process task structure is used for this purpose. 


*/ 
        int __user *set_child_tid; /* CLONE_CHILD_SETTID */
        int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */c
        putime_t utime, stime, utimescaled, stimescaled;  // utime           ,stime           。                                                       
         //                 cputime_t gtime;   //??
        #ifndef CONFIG_VIRT_CPU_ACCOUNTING 
        cputime_t prev_utime, prev_stime;
        #endif
        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 */                    //   cred           

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 */
        char comm[TASK_COMM_LEN]; /* executable name excluding path - access with [gs]et_task_comm (which lock it with task_lock()) - initialized normally by setup_new_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; /*  task_stcut           ,   thread_struct              */
        /* filesystem information */
        struct fs_struct *fs;
        /* open file information */
        struct files_struct *files;
        /* namespaces */  //          ,    Professional Linux® Kernel Architecture  2.3.2 
                         //   http://book.51cto.com/art/201005/200881.htm
        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;
        /*Although signal handling takes place in the kernel, the installed signal handlers run in usermode — otherwise,
          it would be very easy to introduce malicious or faulty code into the kernel andundermine the system security mechanisms.
          Generally, signal handlers use the user mode stack ofthe process in question.
          However, POSIX mandates the option of running signal handlers on a stackset up specifically for this purpose (using the
          sigaltstack system call). The address and size of this additional stack (which must be explicitly allocated by the
          user application) are held in sas_ss_sp andsas_ss_size, respectively. (Professional Linux® Kernel Architecture Page384)*/
        int (*notifier)(void *priv);
        void *notifier_data;
        sigset_t *notifier_mask;
        struct audit_context *audit_context; //    Professional Linux® Kernel Architecture Page1100
        #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: */   //PI --> Priority Inheritanceraw_spinlock_t pi_lock;
        #ifdef CONFIG_RT_MUTEXES    //RT-->  RealTime Task     /* 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;
        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
        #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_list *bio_list; // IO   
        #ifdef CONFIG_BLOCK
        /* stack plugging */
        struct blk_plug *plug;
        #endif
        /* 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; //a structure which is used for recording a single task's IO statistics.
        #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 mems_allowed_change_disable;
        int cpuset_mem_spread_rotor;
        int cpuset_slab_spread_rotor;
        #endif
        #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_FUTEX
        struct robust_list_head __user *robust_list;
        #ifdef CONFIG_COMPAT
        struct compat_robust_list_head __user *compat_robust_list;
        #endifstruct list_head pi_state_list;
        struct futex_pi_state *pi_state_cache;
        #endif
        #ifdef CONFIG_PERF_EVENTS
        struct perf_event_context *perf_event_ctxp[perf_nr_task_contexts];
        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;
        short pref_node_fork;
        #endifatomic_t fs_excl; /* holding fs exclusive resources *///            。 0   。
        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 address 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 and counter of trace recursion */
        unsigned long trace_recursion;
        #endif /* CONFIG_TRACING */
        #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 nr_pages; /* uncharged usage */
        unsigned long memsw_nr_pages; /* uncharged mem+swap usage */
        } memcg_batch;
        #endif
        #ifdef CONFIG_HAVE_HW_BREAKPOINT
        atomic_t ptrace_bp_refcnt;
        #endif
     };