/[lkdp]/lkdp/pm/process.tex
ViewVC logotype

Diff of /lkdp/pm/process.tex

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by kdlinux2001, Thu Nov 21 13:08:15 2002 UTC revision 1.3 by kdlinux2001, Wed Feb 26 06:38:23 2003 UTC
# Line 1  Line 1 
1  \chapter{Process Management}  \chapter{Process Management}
2          \section{Process 0 swapper}          \section{Process 0 swapper}
3                When the CPU switches from real mode to protected mode, it initializes segmentation and paging. Then, it sets up execution environment for the process 0\index{swapper} [swapper]. The assembly code to create the startup swapper proces is in the file \url{arch/i386/kernel/head.S}.                \textbf{\Large W}hen the CPU switches from real mode to protected mode, it initializes segmentation and paging. Then, it sets up execution environment for the process 0\index{swapper} [swapper]. The assembly code to create the startup swapper process is in the file \url{arch/i386/kernel/head.S}.
4  % TODO startup_32 \index {startup\_32}  % TODO startup_32 \index {startup\_32}
5  % TODO init_idle  
6            \section{Process 1 init} \index{init}
7          \section{Process 1 init} \index{init}               After the initialization of paging, memory and timers in the \textit{start\_kernel} function, kernel threads are created. The function \textit{kernel\_thread()} is defined in \url{arch/i386/kernel/process.c} and called from the initialization routine start\_kernel (Refer to section~\ref{init:sk}).
8               After the initialization of paging, memory and timers in the \textit{start\_kernel} function, kernel threads \index{kernel\_thread} are created. The function \textit{kernel\_thread()} is defined in \url{arch/i386/kernel/process.c} and called from the initialization routine start\_kernel (Refer to section~\ref{init:sk}).  
9            \subsection{kernel\_thread} \label{proc:kt} \index{kernel\_thread}
10          \subsection{kernel\_thread} \label{proc:kt} \index{kernel\_thread}          A Kernel\_thread is a cloned thread. Some of the properties of a kernel\_thread are listed below:
11  % TODO kernel_thread          \begin{enumerate}
12            \item A kernel\_thread usually runs in the background, releasing its memory map,and the files struct and becoming one with "init" by calling daemonize() function defined in \url{kernel/sched.c}.
13           \par The init function (fn parameter to kernel\_thread) locks the kernel and performs the basic setup related to foll. items.          \item Kernel thread run in kernel address space and do not interact with user. They are generally created during sytem bootup and run until sytem shutdown.
14            \item A running kernel thread blocks till someone calls schedule\_task by putting itself into its wait\_queue,calling schedule,thereby waiting for someone to wake it up through a call to schedule\_task. The schedule\_task queues up the tq\_struct and then wakes up the keventd process,blocking in its wait\_queue,for someone to wake it up,in order to consume the tq\_context queue.
15          \newline \textbf{Function : do\_basic\_setup} \newline          \end{enumerate}
16          The function do\_basic\_setup starts a migration thread, context thread and performs socket initialization.          \par The famous process 0 and 1 are created using kernel\_thread. Another good example of a Kernel Thread is "keventd" which is started as a kernel\_thread using start\_context\_thread(context\_thread,NULL,CLONE\_FILES | CLONE\_FS) in \url{kernel/context.c} which has the operations for the kernel thread keventd.
17            \par The kernel\_thread is created as follows:
18          \begin{description}          \begin{verbatim}
19          \item[migration thread] \index{migration\_thread} A migration thread (kernel\_thread) is started by calling \textit{migration\_init} function [\url{kernel/sched.c} ] for all cpus. Refer to section ~\ref{smp:all} for SMP initialization details.          int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
20            {
21          \subsection{migration\_thread} \label{proc:mt} \index{migration\_thread}              long retval, d0;
22  % TODO migration _thread  
23          \begin{verbatim}              __asm__ __volatile__(
24                    "movl %%esp,%%esi\n\t"   /*  [1]. */
25              /* Note, smp_num_cpus is configured during smp boot process                  "int $0x80\n\t"         /* Linux/i386 system call */
26                 in smp_boot_cpu function in arch/i386/kernel/smpboot.c                  "cmpl %%esp,%%esi\n\t"  /* child or parent?  [2]. */
27               */                  "je 1f\n\t"             /* parent - jump */
28              for (cpu = 0; cpu < smp\_num\_cpus; cpu++) {                  "movl %4,%%eax\n\t"
29                  if (kernel\_thread(migration\_thread, (void *) (long) cpu,                  "pushl %%eax\n\t"
30                          CLONE\_FS | CLONE\_FILES | CLONE\_SIGNAL) < 0)                  "call *%5\n\t"          /* call fn */  /*  [3]. */
31                  BUG();                  "movl %3,%0\n\t"        /* exit */
32              }                  "int $0x80\n"           /* [4]. */
33                    "1:\t"
34          \end{verbatim}                  :"=&a" (retval), "=&S" (d0)
35          \item[Sockets] Performs initialization related to sockets. The function sock\_init is defined in \url{net/socket.c}.                  :"0" (__NR_clone), "i" (__NR_exit),
36          % TODO kern_mount NFS mount                   "r" (arg), "r" (fn),
37          \item[context\_thread] The function start\_context\_thread creates a kernel\_thread named context\_thread. The function is defined in \url{kernel/context.c}                   "b" (flags | CLONE_VM)
38          \begin{verbatim}                  : "memory");
39                    return retval;
40              kernel_thread(context_thread, NULL, CLONE_FS | CLONE_FILES);          }
41            \end{verbatim}
42          \end{verbatim}          \begin{enumerate}
43            \item The kernel thread invokes \textit{"clone"} system call to create new kernel process, with the parent proces 0 (Init). [\textit{ clone(0, flags | CLONE\_VM); }]
44          \item[init\_calls] The function do\_init\_call flushes the pending tasks in the init queue, if any.          \item If checks, whether the return value of clone function is parent or child. For parent process, it makes a far jump to return from ther function.
45          \end{description}          \item For child process, it invokes the function passed as argument
46            \item It also invokes another system call to exit from the function. Thus, the kernel thread starts executing independantly.
47          \par The init function opens a console (viz. /dev/console) and finally, executes the "/sbin/init" or "/etc/init" or "/bin/init" or "/bin/sh" program (in this priority order).          \end{enumerate}
48    
49          \newline \par The code is explained below.          \\ \par The init function (fn parameter to kernel\_thread) locks the kernel and performs the basic setup related to following items.
50    
51          \begin{verbatim}          \\ \textbf{Function : do\_basic\_setup} \\
52            The function do\_basic\_setup starts a migration thread, context thread and performs socket initialization.
53              lock_kernel();  
54              do_basic_setup();          \begin{description}
55            \item[migration thread] \index{migration\_thread} A migration thread (kernel\_thread) is started by calling \textit{migration\_init} function [\url{kernel/sched.c} ] for all cpus. Refer to section ~\ref{smp:all} for SMP initialization details.
56              prepare_namespace();  
57              free_initmem();          \subsection{migration\_thread} \label{proc:mt} \index{migration\_thread}
58              unlock_kernel();              The migration\_thread is a SMP specific process and is started by calling the \textit{migration\_init} function defined in \url{kernel/sched.c}. The function is executed only on the boot (first) processor and other CPUs use the scheduler to run the migration\_thread.  This thread is a part of the system runqueue along with the \textit{migration\_queue}. Migration is used to lock multiple runqueues running on different CPUs using a semaphore. This is how migration works.\footnote{Migration steps are explained in \url{kernel/sched.c}.}
59    
60              if (open("/dev/console", O_RDWR, 0) < 0)          \begin{enumerate}
61                      printk("Warning: unable to open an initial console.\n");          \item Queue a \textit{migration\_req\_t} structure in the source CPU's runqueue and wake up that CPU's migration thread.
62            \item down() the locked semaphore, hence the thread blocks.
63              (void) dup(0);          \item Migration thread wakes up (implicitly it forces the migrated thread off the CPU)
64              (void) dup(0);          \item It gets the migration request and checks whether the migrated task is still in the wrong runqueue.
65              if (execute_command)          \item If it's in the wrong runqueue then the migration thread removes it and puts it into the right queue.
66                      execve(execute_command,argv_init,envp_init);          \item Migration thread up()s the semaphore.
67              execve("/sbin/init",argv_init,envp_init);          \item The process wakes up and the migration is done.
68              execve("/etc/init",argv_init,envp_init);          \end{enumerate}
69              execve("/bin/init",argv_init,envp_init);  
70              execve("/bin/sh",argv_sh,envp_init);          The migration\_thread function is described below:
71              panic("No init found.  Try passing init= option to kernel.");          \begin{verbatim}
72    
73          \end{verbatim}              /* Note, smp_num_cpus is configured during smp boot process
74                   in smp_boot_cpu function in arch/i386/kernel/smpboot.c
75          \subsection{Namespaces} \index{prepare\_namespace}               */
76  % TODO prepare_namespace, dup              for (cpu = 0; cpu < smp\_num\_cpus; cpu++) {
77          The function calls prepare\_namespace.                  if (kernel\_thread(migration\_thread, (void *) (long) cpu,
78                            CLONE\_FS | CLONE\_FILES | CLONE\_SIGNAL) < 0)
79          \subsection{Function init()} \index{init}                  BUG();
80          \newline \par The \textit{init} program is the first process run after the kernel is up. It is configured with the "/etc/inittab" file. It contains following system configuration.              }
81    
82          \begin{description}          \end{verbatim}
83          \item[Runlevel] Start up system run level.  % TODO migration _thread function
84          \item[Startup-process] Processes to be executed during system boot.          \item[Sockets] Performs initialization related to sockets. The function sock\_init is defined in \url{net/socket.c}. The reason behind network initialization at this point is related to file system mounting. In order to mount the file system from NFS, the network should be up and running . Hence, the VFS file system is mounted using the \textit{kern\_mount} function invoked from the sock\_init function which takes care of network booting.
85          \item[Runlevel-processes] Processes to be run when the specified runlevel is entered.          \item[context\_thread] The function start\_context\_thread creates a kernel\_thread named context\_thread. The function is defined in \url{kernel/context.c}
86          \item[Action-processes] Processes to be run on certain runlevels with actions like respawn so the process is restarted any time it terminates.          \begin{verbatim}
87          \item[Other prcesses] Certain actions or processes to be run if certain signals or user actions are indicated.              kernel_thread(context_thread, NULL, CLONE_FS | CLONE_FILES);
88          \end{description}          \end{verbatim}
89    
90          \section{Structures}          \item[init\_calls] The function do\_init\_call flushes the pending tasks in the init queue, if any.
91               Within the linux kernel, every process is associated with a process descriptor defined by struct \textit{task\_struct} \footnote{defined in \url{include/linux/sched.h}}. The structure contains various information related to process state, process threads, executable domain, process priority, signals, parent child relationships,filesystems and various limits. All the elements of these structure are initialized when a new process is created and destroyed when the process terminates. In order to understand process scheduling, it is necessary to understand how these scheduling information is initialized. This is explained in the do\_fork ~\ref{proc:do_fork} function. First we shall describe the \textit{task\_struct} in detail.          \end{description}
92    
93          \subsection{The process [task\_struct] structure} \index{task\_struct}          \\ \par The code is explained below.
94          % TODO task_struct and others  
95            \begin{verbatim}
96          \section{Creating New process}  
97                lock_kernel();
98          % TODO dup resource , copy on write , __clone LWP , _syscall              do_basic_setup();
99                  Linux kernel 2.4 supports 3 types of processes.  
100          \begin{description}              prepare_namespace();
101                  \item[\large{1. idle threads}]              free_initmem();
102                  \par The idle thread is created after initialization for the first CPU while for others, it is created by calling fork\_by\_hand() in \url{arch/i386/kernel/smpboot.c}. Idle tasks are unique per cpu with a pid of 0.              unlock_kernel();
103                  \item[\large{2. kernel threads}]  
104          \par Kernel threads are created using kernel\_thread() function. The "fn" argument is the function which starts executing in daemon mode using the daemonize() function.              if (open("/dev/console", O_RDWR, 0) < 0)
105                        printk("Warning: unable to open an initial console.\n");
106          \begin{minipage}{0.90\textwidth}  
107          Example of a kernel\_thread :              (void) dup(0);
108                   In order to create a migration\_thread, kernel\_thread is created in the function migration\_init. Refer to \url{kernel/sched.c} for each cpu.              (void) dup(0);
109          \begin{verbatim}              if (execute_command)
110                        execve(execute_command,argv_init,envp_init);
111          for (cpu = 0; cpu < smp\_num\_cpus; cpu++) {              execve("/sbin/init",argv_init,envp_init);
112               if (kernel\_thread(migration\_thread, (void *) (long) cpu,              execve("/etc/init",argv_init,envp_init);
113                      CLONE\_FS | CLONE\_FILES | CLONE\_SIGNAL) < 0)              execve("/bin/init",argv_init,envp_init);
114               BUG();              execve("/bin/sh",argv_sh,envp_init);
115          }              panic("No init found.  Try passing init= option to kernel.");
116    
117          \end{verbatim}          \end{verbatim}
118                  The function migration\_init daemonizes itself.            Before starting the init program, the basic setup related to migration, init calls, context thread is done as explained above. The function \textit{prepare\_namespace} is related namespace explained in the Next section. The bootup command line parameters to lilo (or other boot program) are also invoked. The init function opens a console (viz. /dev/console) and finally, executes the "/sbin/init" or "/etc/init" or "/bin/init" or "/bin/sh" program (in this priority order) and the init process is started from the available location.
119          \begin{verbatim}  
120    %       \subsection{Namespaces} \index{prepare\_namespace}
121          static int migration\_thread(void * bind\_cpu) {  % software_resume in kernel/suspend.c
122              int ret;  % mount_devfs : mounts /dev ;  do_mount ("none", "/dev", "devfs", 0, "");
123          \end{verbatim}  % TODO prepare_namespace, dup
124              \textbf{          daemonize();}  %       The function calls prepare\_namespace.
125          \begin{verbatim}  
126              sigfillset(&current->blocked);          \subsection{Function init()} \index{init}
127              set\_fs(KERNEL\_DS);          \\ \par The \textit{init} program is the first process run after the kernel is up. It is configured with the "/etc/inittab" file. It contains following system configuration.
128          }  
129            \begin{description}
130          \end{verbatim}          \item[Runlevel] Start up system run level.
131          \end{minipage} \end{center}          \item[Startup-process] Processes to be executed during system boot.
132            \item[Runlevel-processes] Processes to be run when the specified runlevel is entered.
133                  \item[\large{3. user tasks}]          \item[Action-processes] Processes to be run on certain runlevels with actions like respawn so the process is restarted any time it terminates.
134          \par user tasks are generally created by user applications using fork() or clone() function calls.          \item[Other prcesses] Certain actions or processes to be run if certain signals or user actions are indicated.
135          \end{description}          \end{description}
136    
137          \section{fork, clone system calls}          \section{Structures}
138              New processes are created by using fork, clone, vfork system calls. When a user mode program invokes a system call, the libc library transfers control to kernel mode using software interrupt 0x80 registered during IRQ initialization and the kernel executes the system call related function. The system call within the kernel is its counterpart in user space prefixed by sys. So, when user calls fork/clone/vfork, kernel executes sys\_fork/sys\_clone/sys\_vfork function.               Within the linux kernel, every process is associated with a process descriptor defined by struct \textit{task\_struct} \footnote{defined in \url{include/linux/sched.h}}. The structure contains various information related to process state, process threads, executable domain, process priority, signals, parent child relationships, filesystems and various limits. All the elements of these structure are initialized when a new process is created and destroyed when the process terminates. In order to understand process scheduling, it is necessary to understand how these scheduling information is initialized. This is explained in the do\_fork ~\ref{proc:do_fork} function. First we shall describe the \textit{task\_struct} in detail.
139          \par These functions are defined in \url{arch/i386/kernel/process.c} while the system call numbers are defined in \url{include/asm-i386/unistd.h}  
140            \subsection{The process [task\_struct] structure} \index{task\_struct} \label{taskstruct}
141          \par Example of fork system call : \index{fork}          The complete process structure is discussed below. The scheduler related members of the process structure are explained in detail in the scheduling chapter ~\ref{sched:structs}.
142    
143          \begin{enumerate}          \begin{verbatim}
144           \item  User calls fork();          struct task_struct {
145           \item  The libc library generates software interrupt [0x80] and tansfers control to kernel mode.              volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
146           \item  Kernel executes system\_call() and saves kernel mode stack registers.              struct thread_info *thread_info;
147           \item  Kernel invokes function sys\_fork();              atomic_t usage;
148           \item  Kernel exits the handler by calling ret\_from\_sys\_call();              unsigned long flags;    /* per process flags, defined below */
149          \end{enumerate}              unsigned long ptrace;
150    
151          \par When a new process is created using fork/clone/vfork system call, kernel executes sys\_fork/sys\_clone/sys\_vfork function respectively, defined in \url{arch/i386/kernel/process.c}. These functions are architecture specific which call the generic function do\_fork to create the new process. The first "flags" parameter is properly substituted and the function do\_fork is invoked.              int lock_depth;         /* Lock depth */
152    
153          \newline \par Example of sys\_clone function :              int prio, static_prio;
154                list_t run_list;
155          \begin{verbatim}              prio_array_t *array;
156    
157          asmlinkage int sys_clone(struct pt_regs regs)              unsigned long sleep_avg;
158          {              unsigned long sleep_timestamp;
159              struct task_struct *p;  
160              unsigned long clone_flags;              unsigned long policy;
161              unsigned long newsp;              unsigned long cpus_allowed;
162              clone_flags = regs.ebx;              unsigned int time_slice;
163              newsp = regs.ecx;  
164              if (!newsp)              struct list_head tasks;
165                      newsp = regs.esp;  
166              p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0);              struct mm_struct *mm, *active_mm;
167              return IS_ERR(p) ? PTR_ERR(p) : p->pid;              struct list_head local_pages;
168          }  
169                unsigned int allocation_order, nr_local_pages;
170          \end{verbatim}  
171                struct linux_binfmt *binfmt;
172          \subsection{do\_fork function} \index{do\_fork}              int exit_code, exit_signal;
173          Function do\_fork() \label{proc:do_fork}              int pdeath_signal;  /*  The signal sent when the parent dies  */
174          \textit{File: }\url{kernel/fork.c}\\ \newline              unsigned long personality;
175                int did_exec:1;
176          \par Following paragraph explains the steps taken by the kernel do\_fork function in order to create a new process. The steps are more relevant from process scheduling point of view.              pid_t pid;
177                                pid_t pgrp;
178          \begin{verbatim}              pid_t tty_old_pgrp;
179                  struct task_struct *do_fork(unsigned long clone_flags,              pid_t session;
180                              unsigned long stack_start,              pid_t tgid;
181                              struct pt_regs *regs,              /* boolean value for session group leader */
182                              unsigned long stack_size)              int leader;
183          \end{verbatim}              struct task_struct *real_parent; /* real parent process (when being debugged) */
184                struct task_struct *parent;     /* parent process */
185               The do\_fork function takes foll. arguments.              struct list_head children;      /* list of my children */
186          \begin{description}              struct list_head sibling;       /* linkage in my parent's children list */
187          \item[clone\_flags] : Flags to create process. This is different for fork/clone/vfork calls.              struct list_head thread_group;
188          \item[stack\_start] : top of stack required for copy\_routine.  
189          \item[regs] : The register structure defined in \url{include/asm-i386/ptrace.h}              /* PID hash table linkage. */
190          \item[stack\_size] : Size of stack, usually 0.              struct task_struct *pidhash_next;
191          \item[] \&              struct task_struct **pidhash_pprev;
192          \item[return value] : (pointer to) Newly created task.  
193          \end{description}              wait_queue_head_t wait_chldexit;        /* for wait4() */
194                struct completion *vfork_done;          /* for vfork() */
195          \par The code is explained below in parts.  
196                unsigned long rt_priority;
197          \begin{verbatim}              unsigned long it_real_value, it_prof_value, it_virt_value;
198                unsigned long it_real_incr, it_prof_incr, it_virt_incr;
199          /*** Vaildity checks ***/              struct timer_list real_timer;
200                struct tms times;
201          if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))              unsigned long start_time;
202               return ERR_PTR(-EINVAL);              long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];
203                unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
204          retval = -ENOMEM;              int swappable:1;
205          p = dup_task_struct(current);              uid_t uid,euid,suid,fsuid;
206          if (!p)              gid_t gid,egid,sgid,fsgid;
207                goto fork_out;              int ngroups;
208                gid_t   groups[NGROUPS];
209          retval = -EAGAIN;              kernel_cap_t   cap_effective, cap_inheritable, cap_permitted;
210          if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur) {              int keep_capabilities:1;
211              if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))              struct user_struct *user;
212                    goto bad_fork_free;          /* limits */
213          }              struct rlimit rlim[RLIM_NLIMITS];
214                unsigned short used_math;
215          atomic_inc(&p->user->__count);              char comm[16];
216          atomic_inc(&p->user->processes);          /* file system info */
217                int link_count, total_link_count;
218          if (nr_threads >= max_threads)              struct tty_struct *tty; /* NULL if no tty */
219                goto bad_fork_cleanup_count;              unsigned int locks; /* How many file locks are being held */
220            /* ipc stuff */
221          \end{verbatim}              struct sysv_sem sysvsem;
222              Initially, the kernel checks for validity for clone\_flags. If the process is part of New Namespace Group (CLONE\_NEWNS) AND fs sharing flag (CLONE\_FS) are set,simoultaneously,  it retuns an error. Then it creates a new task by duplicating the currently running task(current).          /* CPU-specific state of this task */
223          \newline \par The kernel limits the number of user processes owned by a process.\footnote{Refer to \url{include/asm-i386/resource.h} for the resource constants.} If this value, is greater or equal to current resource limit of number of processes, it returns an error. Else, it updates the user struct\footnote{defined in \url{linux/sched.h}} for that process. The function \textit{"capable()"} checks for a particular capability. The file \url{include/linux/capability.h} enumerates the list of capabilities e.g. CAP\_SYS\_ADMIN. Then, the kernel checks if the number of threads exceed the limit max\_therads.\footnote{limit set up in fork\_init function of start\_kernel code}.              struct thread_struct thread;
224          % TODO dup_task_struct          /* filesystem information */
225                struct fs_struct *fs;
226          \begin{verbatim}          /* open file information */
227                struct files_struct *files;
228          /*** Initialize task data variables and flags ***/          /* namepaces */
229                struct namespace *namespace;
230          get_exec_domain(p->thread_info->exec_domain);          /* signal handlers */
231                spinlock_t sigmask_lock;        /* Protects signal and blocked */
232          if (p->binfmt && p->binfmt->module)              struct signal_struct *sig;
233                __MOD_INC_USE_COUNT(p->binfmt->module);  
234                sigset_t blocked;
235          p->did_exec = 0;              struct sigpending pending;
236          p->swappable = 0;  
237          p->state = TASK_UNINTERRUPTIBLE;              unsigned long sas_ss_sp;
238                size_t sas_ss_size;
239          copy_flags(clone_flags, p);              int (*notifier)(void *priv);
240          p->pid = get_pid(clone_flags);              void *notifier_data;
241          p->proc_dentry = NULL;              sigset_t *notifier_mask;
242    
243          \end{verbatim}          /* Thread group tracking */
244                u32 parent_exec_id;
245             Linux kernel has the ability to execute the binaries compiled for other operating systems (assuming kernel compatible machine code). The execution domain for the running thread is specified by the structure exec\_domain defined in \url{include/linux/personality.h} \footnote{map\_segment TODO }. The structure defines varioous personlities of the target execution environment supported by the kernel. e.g. PER\_LINUX for linux systems, PER\_BSD for bsd uix. The personality value is set by \textit{personality()} system call. the macro \textit{get\_exec\_domain} is used to increament the module count of the module associated with the \textit{exec\_domain} while its counterpart \textit{put\_exec\_domain} is used to decreament it.              u32 self_exec_id;
246            /* Protection of (de-)allocation: mm, files, fs, tty */
247          % TODO map_segment              spinlock_t alloc_lock;
248            \par Then, the kernel increments the module's reference count only for modularised binary format. Then, it resets executed, swappable flags ans sets task state to TASK\_UNINTERRUPTIBLE. The new flags are set for the process p, especially in case of \textit{sys\_clone} call.  
249            /* journalling filesystem info */
250          \begin{verbatim}              void *journal_info;
251                struct dentry *proc_dentry;
252          /*** Initialize task wait queue, lists and pointers ***/          \end{verbatim}
253    
254          INIT_LIST_HEAD(&p->run_list);            \\ These task structure elements are grouped for specific purposes and used for that particular reason. They are stated below in short:
255    
256          INIT_LIST_HEAD(&p->children);          \begin{itemize}
257          INIT_LIST_HEAD(&p->sibling);  
258          init_waitqueue_head(&p->wait_chldexit);          \item state :  The process state defined as per process life cycle.
259          p->vfork_done = NULL;          \item thread\_info : The thread information associated with a process.
260          if (clone_flags & CLONE_VFORK) {          \item usage : The usage usually associated with loadable modules.
261                p->vfork_done = &vfork;          \item flags : Process flags related to fork, core dump, start execution, signaled, free pages , I/O as defined in \url{include/linux/sched.h}
262                init_completion(&vfork);          \item ptrace : Whether the process under execution is being traced or NOT.
263          }          \item lock\_depth : Initialized to -1 and used as thread preemption counter while switching tasks with spinlocks held.
264          spin_lock_init(&p->alloc_lock);          \item prio, static\_prio, run\_list, array : These fields are related to process scheduling and are explained in the chapter ~\ref{sched:all}.
265            \item sleep\_avg, sleep\_timestamp : The sleep times of the process are used for priority calculation. The more time a task spends sleeping, it gets higher average and higher priority boost as well.
266          clear_tsk_thread_flag(p,TIF_SIGPENDING);          \item policy : Either of SCHED\_FIFO, SCHED\_RR, SCHED\_OTHER predefined values.
267          init_sigpending(&p->pending);          \item cpus\_allowed, time\_slice : The number of cpus allowed are set using the cpu\_logical\_map. While time\_slice is used as a measure for which the cpu is alloted to the process. The deault value is Hz.
268            \item list\_head tasks : The list fo tasks to which the current task is going to get linked.
269          p->it_real_value = p->it_virt_value = p->it_prof_value = 0;          \item mm, active\_mm, local\_pages, allocation order, nr\_local\_pages : These fields are related to the memory associated with the process.
270          p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;          \item binfmt : The binary format used by the process.
271            \item exit\_code, exit\_signal, pdeath\_signal : These fields are updated when the process terminates. The pdeath\_signal is updated when the parent of the process dies.
272          /*** some initialization related to timer ***/          \item personality : The personality is set as some value related to the operating system. Linux kernel setups the default value as PER\_LINUX personality.
273            \item did\_exec : The executable flag set up when the process is created.
274          init_timer(&p->real_timer);          \item pid, pgrp, tty\_old\_pgrp, session, tgid, leader : The session credetials related with the process. The process id, group characters, session properties and leadership.
275          p->real_timer.data = (unsigned long) p;          \item real\_parent, parent, children , sibling : The pointers to original parent and real parent, children and other silblings.
276            \item pidhash\_next, pidhash\_pprev : The process ids are obtained using the hash function. These fields are used to keep track of the hashing accountings. Refer to section ~\ref{hashpid} for details.
277          p->leader = 0;          /* session leadership doesn't inherit */          \item wait\_chldexit : This field is related to wait queue of processes. This field is initialized with \textit{WAIT\_QUEUE\_HEAD\_INITIALIZER} macro and updated when the process exits. At the exit time, the parent and all the others in its thread\_group are waken up by calling \textit{send\_siginfo}. The waiting processes are kept blocking on its wait\_chldexit wait\_queue.
278          p->tty_old_pgrp = 0;          \item vfork\_done : This field is of struct completion type, which contains a waitqueue pointer along with a done flag. This struct is dedicated to vfork system call.
279          p->times.tms_utime = p->times.tms_stime = 0;          \item rt\_priority : The real time priority associated with the process. This is used for process scheduling of \textit{SCHED\_OTHER} policy.
280          p->times.tms_cutime = p->times.tms_cstime = 0;          \item it\_real\_value, it\_prof\_value, it\_virt\_value, it\_real\_incr, it\_prof\_incr, it\_virt\_incr : These fields are related to virtual and profile timer clock and SIGVTALRM, SIGPROF signals.
281            \item real\_timer, start\_time : The timer list associated with the process and updated with every timer interrupt.
282          \end{verbatim}          \item times : The time accountings related to times system call.
283            \item per\_cpu\_utime, per\_cpu\_stime : The per processor time spent in user and system space.
284                The \textit{INIT\_LIST\_HEAD} macro is used to initialize the next and prev pointers of a linked list. Both the pointers are set to the macro argument, representing a circular linked list of a single element \footnote{Linked lists are described \url{include/linux/list.h}} while \textit{init\_waitqueue\_head} initializes the waitqueue header node which contains the spinlock along with the linked list.          \item min\_flt, maj\_flt,nswap, cmin\_fltcmaj\_flt, cnswap : These are resource control/accounting fields similar to struct usage in \url{include/linux/resource.h}. They are used to store memory and paging information like page faults, reclaims.
285           \par The inline function \textit{clear\_tsk\_thread\_flag} (defined in \url{include/linux/sched.h}) calls \textit{clear\_ti\_thread\_flag} (defined in \url{include/linux/thread_info.h}) to clear the flag information of the thread within the task structure.          \item swappable : The flag indicating whether the process is swappable or not.
286            \item uid, euid, suid, fsuid, gid, egid, sgid, fsgid : The unix system ids assoicated with the process.
287          \index{bitops} \index{btrl}          \item ngroups, groups[NGROUPS] : The groups is an array of size 32, of type gid\_t. The numer of valid groups is set to ngroups.
288          \begin{verbatim}          \item cap\_effective, cap\_inheritable, cap\_permitted, keep\_capabilities : The kernel capability structure associated with the process, also part of linux binary format structure in \url{include/linux/binfmt.h}.
289            \item user\_struct user : The user struct contain user space information like the refrence count, user processes, open files , hashing information and uid.
290          /*** File : {include/asm-i386/bitops.h}  ***/          \item rlim, used\_math : rlim is process usage limits structure used to setup the RLIMIT\_CPU, RLIMIT\_FSIZE (file size), RLIMIT\_DATA (heap size), RLIMIT\_AS (address size), RLIMIT\_RSS (page frames).
291          static __inline__ void clear_bit(int nr, volatile unsigned long * addr)          \item link\_count, total\_link\_count : These fields are used in pathname lookup mechanisms. Currently the recursive symlink is limited to 8, while consecutive symlinks are limited to 40. Refer to \url{fs/namei.c} for more details.
292          {          \item tty : The terminal information if the process is associated with a tty device.
293               __asm__ __volatile__( LOCK_PREFIX          \item locks : The number of file locks being held by the process.
294                      "btrl %1,%0"          \item sysvsem : The IPC realted information within the process.
295                      :"=m" (ADDR)          \item thread, fs, files : The file system and open files information for the process.
296                      :"Ir" (nr));          \item sigmask, sig, blocked, pending : The signal related structures. Refer to section ~\ref{signalstruct} for details.
297          }          \item sas\_ss\_sp, sas\_ss\_size : These fields are used while switching stacks during execution of signal handlers.
298            \item notifier, notifier\_data, notifier\_mask : Used to notify the system that a driver wants to block all signals for this process, and wants to be notified if any signals at all were to be sent/acted upon.
299          \end{verbatim}          \item parent\_exec\_id, self\_exec\_id : The exec ids setup during startup of processes. If the parent exec id doesn't match the exec id, saved when we the process started then it is notied that the parent has changed security domain.
300          % TODO explain code          \item alloc\_lock : The spin lock used for task\_lock and task\_unlock purposes.
301               \textit{init\_completion} is wrapper inline function to initialize the wait queue header specially used during \textit{vfork()} system call. The function \textit{init\_sigpending} initializes the signal structure containing struct sigqueue\footnote{defined in \url{include/linux/signal.h}} and sigset\_t\footnote{defined in \url{include/asm-i386/signal.h}} structure. Refer to section ~\ref{sig:structs} for more details. The head and tail pointers of sigqueue are set to NULL to initialize the circular linked list of single element while the number of words per signal [\_NSIG\_WORDS] of sigset\_t structure are set to zero.          \item journal\_info, proc\_dentry : The journaling information stored for journling filesystems like ext3.
302          \par  The dynamic timer associated with the task structure is \textit{real\_timer}. When, a new task is created, the timer is initialized using \textit{init\_timer} and the data is field set to the newly created process p. Thus, the whole process structure is available to the function which is called when the timer expires.          \end{itemize}
303          \begin{verbatim}  
304            \section{Creating New process}
305          #ifdef CONFIG_SMP  
306          {          % TODO dup resource , copy on write , __clone LWP , _syscall
307               int i;                  Linux kernel 2.4 supports 3 types of processes.
308            \begin{description}
309               /* ?? should we just memset this ?? */                  \item[\large{1. idle threads}]
310               for(i = 0; i < smp_num_cpus; i++)                  \par The idle thread is created after initialization for the first CPU while for others, it is created by calling fork\_by\_hand() in \url{arch/i386/kernel/smpboot.c}. Idle tasks are unique per cpu with a pid of 0.
311                     p->per_cpu_utime[cpu_logical_map(i)] =                  \item[\large{2. kernel threads}]
312                        p->per_cpu_stime[cpu_logical_map(i)] = 0;          \par Kernel threads are created using kernel\_thread() function. The "fn" argument is the function which starts executing in daemon mode using the daemonize() function.
313               spin_lock_init(&p->sigmask_lock);  
314          }          Example of a kernel\_thread :
315          #endif                   In order to create a migration\_thread, kernel\_thread is created in the function migration\_init. Refer to \url{kernel/sched.c} for each cpu.
316            \begin{verbatim}
317          \end{verbatim}  
318              This part of code is SMP specific. It resets the values of user timer (utime) and system time (stime) for all cpus for the current process. It also initializes the \textit{sigmask\_lock} used to block the signals by the process. Refer to ~\ref{sig:structs} for more details.          for (cpu = 0; cpu < smp\_num\_cpus; cpu++) {
319                 if (kernel\_thread(migration\_thread, (void *) (long) cpu,
320          \begin{verbatim}                      CLONE\_FS | CLONE\_FILES | CLONE\_SIGNAL) < 0)
321                 BUG();
322          p->array = NULL;          }
323          p->lock_depth = -1;             /* -1 = no lock */  
324          p->start_time = jiffies;          \end{verbatim}
325                    The function migration\_init daemonizes itself.
326          INIT_LIST_HEAD(&p->local_pages);          \begin{verbatim}
327    
328          retval = -ENOMEM;          static int migration\_thread(void * bind\_cpu) {
329                int ret;
330          /*** copying all process resources ***/          \end{verbatim}
331                \textbf{          daemonize();}
332          /* copy all the process information */          \begin{verbatim}
333          if (copy_semundo(clone_flags, p))              sigfillset(&current->blocked);
334                goto bad_fork_cleanup;              set\_fs(KERNEL\_DS);
335          if (copy_files(clone_flags, p))          }
336                goto bad_fork_cleanup_semundo;  
337          if (copy_fs(clone_flags, p))          \end{verbatim}
338                goto bad_fork_cleanup_files;  
339          if (copy_sighand(clone_flags, p))                  \item[\large{3. user tasks}]
340                goto bad_fork_cleanup_fs;          \par user tasks are generally created by user applications using fork() or clone() function calls.
341          if (copy_mm(clone_flags, p))          \end{description}
342                goto bad_fork_cleanup_sighand;  
343          if (copy_namespace(clone_flags, p))          \section{fork, clone system calls}
344                goto bad_fork_cleanup_mm;              New processes are created by using fork, clone, vfork system calls. When a user mode program invokes a system call, the libc library transfers control to kernel mode using software interrupt 0x80 registered during IRQ initialization and the kernel executes the system call related function. The system call within the kernel is its counterpart in user space prefixed by sys. So, when user calls fork/clone/vfork, kernel executes sys\_fork/sys\_clone/sys\_vfork function.
345          retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);          \par These functions are defined in \url{arch/i386/kernel/process.c} while the system call numbers are defined in \url{include/asm-i386/unistd.h}
346    
347          \end{verbatim}          \par Example of fork system call : \index{fork}
348                The initial part of code sets the task starting time to jiffies.\footnote{jiffies contains the time right from the system startup and the value is increamented during every timer interrupt}. The final process execution time is updated during process accounting [do\_acct\_process function in \url{kernel/acct.c}].  
349          \par   Then, various system resources are copied to the newly created process. The following explains the the functions in short.          \begin{enumerate}
350          \begin{itemize}           \item  User calls fork();
351          \item copy\_semundo    :    This copies the sem\_undo\_list object from parent task to child. This object is required to avoid deadlock, when tasks are spawned with the semundo locks. Please refer to \url{ipc/sem.c} for details.           \item  The libc library generates software interrupt [0x80] and tansfers control to kernel mode.
352          \item copy\_files      :    This function [defined in \url{kernel/fork.c}] determines the number of open files by the parent process and copies those file descriptors to the child process.           \item  Kernel executes system\_call() and saves kernel mode stack registers.
353          \item copy\_fs         :    This function [defined in \url{kernel/fork.c}] copies the file system information associated with the process [struct fs\_struct]. It contains elements like root, umask, pwd etc.           \item  Kernel invokes function sys\_fork();
354          \item copy\_sighand    :    This function copies all signal handlers actions from the parent to child process. Thus, all signals are inherited to child depending on clone\_flags.           \item  Kernel exits the handler by calling ret\_from\_sys\_call();
355          \item copy\_mm         :    This function [defined in \url{kernel/fork.c}] copies the memory resources form parent process to child [struct mm\_struct]. It is done by allocating new kmem\_cache for child process.          \end{enumerate}
356          \item copy\_namespace  :    This function [defined in \url{fs/namespace.c}] copies the namespace resources form parent process to child [struct namespace]. It is done by allocating new namespace in kernel to accomodate the new child task.  
357          \item copy\_thread     :    This function [defined in \url{arch/i386/kernel/process.c}] copies the thread information form parent process to child [struct thread\_struct]. This contains the stack pointer, instruction pointer. This thread structure contains the CPU specific state of the task.          \par When a new process is created using fork/clone/vfork system call, kernel executes sys\_fork/sys\_clone/sys\_vfork function respectively, defined in \url{arch/i386/kernel/process.c}. These functions are architecture specific which call the generic function do\_fork to create the new process. The first "flags" parameter is properly substituted and the function do\_fork is invoked.
358          \end{itemize}  
359          \begin{verbatim}          \\ \par Example of sys\_clone function :
360    
361          /*** Now, setup other process attributes ***/          \begin{verbatim}
362    
363          p->parent_exec_id = p->self_exec_id;          asmlinkage int sys_clone(struct pt_regs regs)
364            {
365          /* ok, now we should be set up.. */              struct task_struct *p;
366          p->swappable = 1;              unsigned long clone_flags;
367          p->exit_signal = clone_flags & CSIGNAL;              unsigned long newsp;
368          p->pdeath_signal = 0;              clone_flags = regs.ebx;
369                newsp = regs.ecx;
370          \end{verbatim}              if (!newsp)
371              The \textit{self\_exec\_id} and \textit{parent\_exec\_id} are set to same value after a fork. When the execution domain of a process changes, its self\_exec\_id is increamented. These values are checked while existing the process, only. The death\_signal [cause of death of a process] is reset to 0. The signal value 0 is unused. Signals are listed in \url{include/asm-i386/signal.h}.                      newsp = regs.esp;
372                p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0);
373          \begin{verbatim}              return IS_ERR(p) ? PTR_ERR(p) : p->pid;
374            }
375          /*** Sharing timeslice between child and parent ***/  
376            \end{verbatim}
377          __save_flags(flags);  
378          __cli();          \subsection{do\_fork function} \index{do\_fork}
379          p->time_slice = (current->time_slice + 1) >> 1;          Function do\_fork() \label{proc:do_fork}
380          current->time_slice >>= 1;          \textit{File: }\url{kernel/fork.c}\\ \newline
381          if (!current->time_slice) {  
382              current->time_slice = 1;          \par Following paragraph explains the steps taken by the kernel do\_fork function in order to create a new process. The steps are more relevant from process scheduling point of view.
383              scheduler_tick(0, 0);                  
384          }          \begin{verbatim}
385          p->sleep_timestamp = jiffies;                  struct task_struct *do_fork(unsigned long clone_flags,
386          __restore_flags(flags);                              unsigned long stack_start,
387                                struct pt_regs *regs,
388          \end{verbatim}                              unsigned long stack_size)
389                Since the code updates the process time\_slice, the interrupts should be disabled during this operation. The macros \_\_save\_flags, \_\_cli are used to clear interrupts on the current CPU while \_\_restore\_flgs enables it again.          \end{verbatim}
390          \par   When new child process is created, the \textit{time\_slice}\footnote{Renamed counter field of kernel version 2.2 to time\_slice in kernel 2.4} of the parent process is split into two halves, one for the parent process and the other for child process. This is done to prevent an unlimited access to CPU by a single process. If the parent process is created recently in terms of time\_slice (time\_slice == 0 or 1), then the scheduler is called to reschedule the processes with the user and system time parameters as zero. These parameter are used by the \textit{scheduler\_tick()} function to update the kernel statisticks.  
391                 The do\_fork function takes following arguments.
392          \begin{verbatim}          \begin{description}
393            \item[clone\_flags] : Flags to create process. This is different for fork/clone/vfork calls.
394          /*** Adding process info to Runqueue ***/          \item[stack\_start] : top of stack required for copy\_routine.
395            \item[regs] : The register structure defined in \url{include/asm-i386/ptrace.h}
396          p->tgid = p->pid;          \item[stack\_size] : Size of stack, usually 0.
397          INIT_LIST_HEAD(&p->thread_group);          \item[] \&
398            \item[return value] : (pointer to) Newly created task.
399          /* Need tasklist lock for parent etc handling! */          \end{description}
400          write_lock_irq(&tasklist_lock);  
401            \par The code is explained below in parts.
402          /* CLONE_PARENT re-uses the old parent */  
403          p->real_parent = current->real_parent;          \begin{verbatim}
404          p->parent = current->parent;  
405          if (!(clone_flags & CLONE_PARENT)) {          /*** Vaildity checks ***/
406              p->real_parent = current;  
407              if (!(p->ptrace & PT_PTRACED))          if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
408                  p->parent = current;               return ERR_PTR(-EINVAL);
409          }  
410            retval = -ENOMEM;
411          if (clone_flags & CLONE_THREAD) {          p = dup_task_struct(current);
412              p->tgid = current->tgid;          if (!p)
413              list_add(&p->thread_group, &current->thread_group);                goto fork_out;
414          }  
415            retval = -EAGAIN;
416          SET_LINKS(p);          if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur) {
417          hash_pid(p);              if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
418          nr_threads++;                    goto bad_fork_free;
419          write_unlock_irq(&tasklist_lock);          }
420    
421          \end{verbatim}          atomic_inc(&p->user->__count);
422               At this point of time, all the resources required by the process are available. So, the process can get a chance to execute on the CPU and Hence, it needs to be added to list of runqueues. The newly created process acts as the leader of thread group and initializes itself. But if the flags contain CLONE\_THREAD, [i.e. new process is derived from some other process] then the thread leadership is retained to the thread leader of the calling process and newly created process is added to the linked list of its parents' thread [i.e. calling process's thread].          atomic_inc(&p->user->processes);
423               \par To set the parent child relationship for the newly created process, we need to access parent process also, Hence an irq lock is obtained. This lock will disable pre-eption on the SMP architecure. This lock is released when the process is added to runqueue. The macro SET\_LINKS inserts the new process in the linked list of process lists. Refer to list management in \url{include/linux/list.h}.  
424          \par \textbf{          if (nr_threads >= max_threads)
425          \newline                goto bad_fork_cleanup_count;
426                Hashing Process Ids } \index{hash\_pid}  
427          \newline          \end{verbatim}
428          \par All the process ids (pids) are hashed in a hashing table pidhash[PIDHASH\_SZ] defined in \url{include/linux/sched.h}. This is an array of pointers to task\_struct of size PIDHASH\_SZ\footnote{This value is currently hardcoded to [4096/4], but should be dynamic and should be set to [NR\_TASKS/4]}. This hashed pids avoid sequencial scanning of the process list and thus, improves performance. The \textit{hash\_pid} function adds the new task to the hash table using process pid as key and pid\_fashfn as hashing function.              Initially, the kernel checks for validity for clone\_flags. If the process is part of New Namespace Group (CLONE\_NEWNS) and fs sharing flag (CLONE\_FS) are set, simultaneously,  it returns an error. Then it creates a new task by duplicating the currently running task(current).
429            \\ \par The kernel limits the number of user processes owned by a process.\footnote{Refer to \url{include/asm-i386/resource.h} for the resource constants.} If this value, is greater or equal to current resource limit of number of processes, it returns an error. Else, it updates the user struct accountings [defined in \url{linux/sched.h}] for that process. The function \textit{"capable()"} checks for a particular capability. The file \url{include/linux/capability.h} enumerates the list of capabilities e.g. CAP\_SYS\_ADMIN. Then, the kernel checks if the number of threads exceed the limit max\_therads.\footnote{limit set up in fork\_init function of start\_kernel code}.
430          \begin{verbatim}            \par The function \textit{dup\_task\_struct} is used to create new kernel slab (memory) for the new task using \textit{kmem\_cache\_alloc()}. The thread information of the process is copied to the new task at this point of time.
431          #define pid_hashfn(x)   ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))  
432          \end{verbatim}          \begin{verbatim}
433    
434              The nr\_threads value (total number of processes) is increamented. This value should not exceed max\_threads limit. And the irq lock is returned will re-enables the process pre-emption.          /*** Initialize task data variables and flags ***/
435    
436          \begin{verbatim}          get_exec_domain(p->thread_info->exec_domain);
437    
438          wake_up_forked_process(p);          if (p->binfmt && p->binfmt->module)
439          ++total_forks;                __MOD_INC_USE_COUNT(p->binfmt->module);
440          if (clone_flags & CLONE_VFORK)  
441              wait_for_completion(&vfork);          p->did_exec = 0;
442          else          p->swappable = 0;
443              set_need_resched();          p->state = TASK_UNINTERRUPTIBLE;
444    
445          \end{verbatim}          copy_flags(clone_flags, p);
446              The \textit{wake\_up\_forked\_process} adds the newly created process to the runqueue and activates it.In order to activate task, it is queued at the tail of the runqueue using enqueue\_task function and the priority bitmap of the task is also updated. Refer to \url{kernel/sched.c} for detail functions. The exclusive operations related to runqueues are performed within the \textit{rq\_lock} and \textit{rq\_unlcok} function block. These functions enable and disable interrupts(irqs) on local cpu [cpu corresponding to the runqueue, usually refered by using \textit{smp\_processor\_id()} macro.] in addition to using spin\_lock.          p->pid = get_pid(clone_flags);
447            p->proc_dentry = NULL;
448          \subsection{ABI: Application binary interface}  
449          % TODO ABI          \end{verbatim}
450    
451          \section{Destroying process}             Linux kernel has the ability to execute the binaries compiled for other operating systems (assuming kernel compatible machine code). The execution domain for the running thread is specified by the structure exec\_domain defined in \url{include/linux/personality.h} \footnote{map\_segment TODO }. The structure defines various personalities of the target execution environment supported by the kernel. e.g. PER\_LINUX for linux systems, PER\_BSD for bsd unix. The personality value is set by \textit{personality()} system call. the macro \textit{get\_exec\_domain} is used to increament the module count of the module associated with the \textit{exec\_domain} while its counterpart \textit{put\_exec\_domain} is used to decrement it.
452              There are several reasons for tasks to terminate:  
453            % TODO map_segment
454          \begin{enumerate}            \par Then, the kernel increaments the module's reference count only for modularised binary format. Then, it resets executed, swappable flags and sets task state to TASK\_UNINTERRUPTIBLE. The new flags are set for the process p, especially in case of \textit{sys\_clone} call.
455           \item  exit() system call or end of program.  
456           \item  sending a signal with default disposition to die.          \begin{verbatim}
457           \item  forcing a task to die when kernel receives exception running on behalf of process.  
458          \end{enumerate}          /*** Initialize task wait queue, lists and pointers ***/
459    
460              The sys\_exit function is defined in \url{kernel/exit.c} which calls function do\_exit(). The do\_exit function releases all the resources such as memory, open files, semaphores owned by the process. Following code explains the step by step process.          INIT_LIST_HEAD(&p->run_list);
461    
462          \subsection{do\_exit function}          INIT_LIST_HEAD(&p->children);
463              \newline \par The code is explained below in parts.          INIT_LIST_HEAD(&p->sibling);
464            init_waitqueue_head(&p->wait_chldexit);
465          \begin{verbatim}          p->vfork_done = NULL;
466            if (clone_flags & CLONE_VFORK) {
467          struct task_struct *tsk = current;                p->vfork_done = &vfork;
468                  init_completion(&vfork);
469          if (in_interrupt())          }
470               panic("Aiee, killing interrupt handler!");          spin_lock_init(&p->alloc_lock);
471          if (!tsk->pid)  
472               panic("Attempted to kill the idle task!");          clear_tsk_thread_flag(p,TIF_SIGPENDING);
473          if (tsk->pid == 1)          init_sigpending(&p->pending);
474               panic("Attempted to kill init!");  
475          tsk->flags |= PF_EXITING;          p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
476          del_timer_sync(&tsk->real_timer);          p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
477    
478          if (unlikely(preempt_get_count()))          /*** some initialization related to timer ***/
479              printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",  
480                  current->comm, current->pid,          init_timer(&p->real_timer);
481                  preempt_get_count());          p->real_timer.data = (unsigned long) p;
482    
483          \end{verbatim}          p->leader = 0;          /* session leadership doesn't inherit */
484              The \textit{"current"} task global variable always points to the current task running. The process can not be destroyed while executing an interrupt handler. The processes 0 (idle), 1 (init) can not be destroyed. The macro "unlikely" is GNU compiler version specific\footnote{defined in \url{include/linux/compiler.h}} and gets reduced to macro argument while the macro \textit{"preempt\_get\_count"} is SMP PRE-EMPTION specific and returns the preemption count. This value should be 0 while exiting the system call.          p->tty_old_pgrp = 0;
485            p->times.tms_utime = p->times.tms_stime = 0;
486          \begin{verbatim}          p->times.tms_cutime = p->times.tms_cstime = 0;
487    
488          acct_process(code);          \end{verbatim}
489          __exit_mm(tsk);  
490                  The \textit{INIT\_LIST\_HEAD} macro is used to initialize the next and prev pointers of a linked list. Both the pointers are set to the macro argument, representing a circular linked list of a single element \footnote{Linked lists are described \url{include/linux/list.h}} while \textit{init\_waitqueue\_head} initializes the waitqueue header node which contains the spinlock along with the linked list.
491          sem_exit();           \par The inline function \textit{clear\_tsk\_thread\_flag} (defined in \url{include/linux/sched.h}) calls \textit{clear\_ti\_thread\_flag} (defined in \url{include/linux/thread_info.h}) to clear the flag information of the thread within the task structure.
492          __exit_files(tsk);  
493          __exit_fs(tsk);          \index{bitops} \index{btrl}
494          exit_namespace(tsk);          \begin{verbatim}
495          exit_sighand(tsk);  
496          exit_thread();          /*** File : {include/asm-i386/bitops.h}  ***/
497            static __inline__ void clear_bit(int nr, volatile unsigned long * addr)
498          if (current->leader)          {
499                  disassociate_ctty(1);               __asm__ __volatile__( LOCK_PREFIX
500                        "btrl %1,%0"
501          put_exec_domain(tsk->thread_info->exec_domain);                      :"=m" (ADDR)
502          if (tsk->binfmt && tsk->binfmt->module)                      :"Ir" (nr));
503                  __MOD_DEC_USE_COUNT(tsk->binfmt->module);          }
504    
505          tsk->exit_code = code;          \end{verbatim}
506          exit_notify();           The assembly instruction \textit{"btrl"} tests a particular bit from a long word and then resets it. Thus, the bit number "nr" of the "addr" is cleared after this instruction with changes to ADDR. The \textit{LOCK\_PREFIX} is smp specific and used as \textit{"lock"} instruction for interprocessor locking.
507             \par   The function \textit{init\_completion} is wrapper inline function to initialize the wait queue header specially used during \textit{vfork()} system call. The function \textit{init\_sigpending} initializes the signal structure containing struct sigqueue\footnote{defined in \url{include/linux/signal.h}} and sigset\_t\footnote{defined in \url{include/asm-i386/signal.h}} structure. Refer to section ~\ref{sig:structs} for more details. The head and tail pointers of sigqueue are set to NULL to initialize the circular linked list of single element while the number of words per signal [\_NSIG\_WORDS] of sigset\_t structure are set to zero.
508          \end{verbatim}          \par  The dynamic timer associated with the task structure is \textit{real\_timer}. When, a new task is created, the timer is initialized using \textit{init\_timer} and the data is field set to the newly created process p. Thus, the whole process structure is available to the function which is called when the timer expires.
509            \begin{verbatim}
510                 The code removes memory, files, filesystem resources. All these steps are exactly opposite to those performed while creating the process (only in reverse order).  
511          \par    Before exiting a process, the file information changed by the process should be updated. These task of process accounting is performrd by the "acct\_process" function \footnote{refer to \url{kernel/acct.c} for detail accounting}.          #ifdef CONFIG_SMP
512          % TODO details exit_namespace , exit_sighand, exit_thread          {
513                 int i;
514          \begin{verbatim}  
515                 /* ?? should we just memset this ?? */
516          schedule();               for(i = 0; i < smp_num_cpus; i++)
517          BUG();                     p->per_cpu_utime[cpu_logical_map(i)] =
518                          p->per_cpu_stime[cpu_logical_map(i)] = 0;
519          \end{verbatim}               spin_lock_init(&p->sigmask_lock);
520                  Finally, it calls the schedule() function and does not return. The function prototype in \url{include/linux/kernel.h} indicates it, too. Thus, a process deletion leads to rescheduling of all the processes.          }
521          \begin{verbatim}          #endif
522          NORET\_TYPE void do\_exit(long code) ATTRIB_NORET;  
523          /* # define NORET_TYPE    /**/          \end{verbatim}
524             # define ATTRIB_NORET  __attribute__((noreturn))              This part of code is SMP specific. It resets the values of user timer (utime) and system time (stime) for all cpus for the current process. It also initializes the \textit{sigmask\_lock} used to block the signals by the process. Refer to ~\ref{sig:structs} for more details.
525           */  
526          \end{verbatim}          \begin{verbatim}
527    
528            p->array = NULL;
529            p->lock_depth = -1;             /* -1 = no lock */
530            p->start_time = jiffies;
531    
532            INIT_LIST_HEAD(&p->local_pages);
533    
534            retval = -ENOMEM;
535    
536            /*** copying all process resources ***/
537    
538            /* copy all the process information */
539            if (copy_semundo(clone_flags, p))
540                  goto bad_fork_cleanup;
541            if (copy_files(clone_flags, p))
542                  goto bad_fork_cleanup_semundo;
543            if (copy_fs(clone_flags, p))
544                  goto bad_fork_cleanup_files;
545            if (copy_sighand(clone_flags, p))
546                  goto bad_fork_cleanup_fs;
547            if (copy_mm(clone_flags, p))
548                  goto bad_fork_cleanup_sighand;
549            if (copy_namespace(clone_flags, p))
550                  goto bad_fork_cleanup_mm;
551            retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
552    
553            \end{verbatim}
554                  The initial part of code sets the task starting time to jiffies.\footnote{jiffies contains the time right from the system startup and the value is incremented during every timer interrupt}. The final process execution time is updated during process accounting [do\_acct\_process function in \url{kernel/acct.c}].
555            \par   Then, various system resources are copied to the newly created process. The following explains the the functions in short.
556            \begin{itemize}
557            \item copy\_semundo    :    This copies the sem\_undo\_list object from parent task to child. This object is required to avoid deadlock, when tasks are spawned with the semundo locks. Please refer to \url{ipc/sem.c} for details.
558            \item copy\_files      :    This function [defined in \url{kernel/fork.c}] determines the number of open files by the parent process and copies those file descriptors to the child process.
559            \item copy\_fs         :    This function [defined in \url{kernel/fork.c}] copies the file system information associated with the process [struct fs\_struct]. It contains elements like root, umask, pwd etc.
560            \item copy\_sighand    :    This function copies all signal handlers actions from the parent to child process. Thus, all signals are inherited to child depending on clone\_flags.
561            \item copy\_mm         :    This function [defined in \url{kernel/fork.c}] copies the memory resources form parent process to child [struct mm\_struct]. It is done by allocating new kmem\_cache for child process.
562            \item copy\_namespace  :    This function [defined in \url{fs/namespace.c}] copies the namespace resources form parent process to child [struct namespace]. It is done by allocating new namespace in kernel to accomodate the new child task.
563            \item copy\_thread     :    This function [defined in \url{arch/i386/kernel/process.c}] copies the thread information form parent process to child [struct thread\_struct]. This contains the stack pointer, instruction pointer. This thread structure contains the CPU specific state of the task. Refer to section ~\ref{sched:thread} for details about process thread.
564            \end{itemize}
565            \begin{verbatim}
566    
567            /*** Now, setup other process attributes ***/
568    
569            p->parent_exec_id = p->self_exec_id;
570    
571            /* ok, now we should be set up.. */
572            p->swappable = 1;
573            p->exit_signal = clone_flags & CSIGNAL;
574            p->pdeath_signal = 0;
575    
576            \end{verbatim}
577                The \textit{self\_exec\_id} and \textit{parent\_exec\_id} are set to same value after a fork. When the execution domain of a process changes, its self\_exec\_id is incremented. These values are checked while existing the process, only. The death\_signal [cause of death of a process] is reset to 0. The signal value 0 is unused. Signals are listed in \url{include/asm-i386/signal.h}.
578    
579            \begin{verbatim}
580    
581            /*** Sharing timeslice between child and parent ***/
582    
583            __save_flags(flags);
584            __cli();
585            p->time_slice = (current->time_slice + 1) >> 1;
586            current->time_slice >>= 1;
587            if (!current->time_slice) {
588                current->time_slice = 1;
589                scheduler_tick(0, 0);
590            }
591            p->sleep_timestamp = jiffies;
592            __restore_flags(flags);
593    
594            \end{verbatim}
595                  Since the code updates the process time\_slice, the interrupts should be disabled during this operation. The macros \_\_save\_flags, \_\_cli are used to clear interrupts on the current CPU while \_\_restore\_flgs enables it again.
596            \par   When new child process is created, the \textit{time\_slice}\footnote{Renamed counter field of kernel version 2.2 to time\_slice in kernel 2.4} of the parent process is split into two halves, one for the parent process and the other for child process. This is done to prevent an unlimited access to CPU by a single process. If the parent process is created recently in terms of time\_slice (time\_slice == 0 or 1), then the scheduler is called to reschedule the processes with the user and system time parameters as zero. These parameter are used by the \textit{scheduler\_tick()} function to update the kernel statistics.
597    
598            \begin{verbatim}
599    
600            /*** Adding process info to Runqueue ***/
601    
602            p->tgid = p->pid;
603            INIT_LIST_HEAD(&p->thread_group);
604    
605            /* Need tasklist lock for parent etc handling! */
606            write_lock_irq(&tasklist_lock);
607    
608            /* CLONE_PARENT re-uses the old parent */
609            p->real_parent = current->real_parent;
610            p->parent = current->parent;
611            if (!(clone_flags & CLONE_PARENT)) {
612                p->real_parent = current;
613                if (!(p->ptrace & PT_PTRACED))
614                    p->parent = current;
615            }
616    
617            if (clone_flags & CLONE_THREAD) {
618                p->tgid = current->tgid;
619                list_add(&p->thread_group, &current->thread_group);
620            }
621    
622            SET_LINKS(p);
623            hash_pid(p);
624            nr_threads++;
625            write_unlock_irq(&tasklist_lock);
626    
627            \end{verbatim}
628                 At this point of time, all the resources required by the process are available. So, the process can get a chance to execute on the CPU and Hence, it needs to be added to list of runqueues. The newly created process acts as the leader of thread group and initializes itself. But if the flags contain CLONE\_THREAD, [i.e. new process is derived from some other process] then the thread leadership is retained to the thread leader of the calling process and newly created process is added to the linked list of its parents' thread [i.e. calling process's thread].
629                 \par To set the parent child relationship for the newly created process, we need to access parent process also, Hence an irq lock is obtained. This lock will disable pre-eption on the SMP architecture. This lock is released when the process is added to runqueue. The macro SET\_LINKS inserts the new process in the linked list of process lists. Refer to list management in \url{include/linux/list.h}.
630            \par \textbf{
631            \newline
632                  Hashing Process Ids } \index{hash\_pid} \label{hashpid}
633            \newline
634            \par All the process ids (pids) are hashed in a hashing table pidhash[PIDHASH\_SZ] defined in \url{include/linux/sched.h}. This is an array of pointers to task\_struct of size PIDHASH\_SZ\footnote{This value is currently hardcoded to [4096/4], but should be dynamic and should be set to [NR\_TASKS/4]}. This hashed pids avoid sequential scanning of the process list and thus, improves performance. The \textit{hash\_pid} function adds the new task to the hash table using process pid as key and pid\_fashfn as hashing function.
635    
636            \begin{verbatim}
637            #define pid_hashfn(x)   ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
638            \end{verbatim}
639    
640                The nr\_threads value (total number of processes) is incremented. This value should not exceed max\_threads limit. And the irq lock is returned will re-enables the process pre-emption.
641    
642            \begin{verbatim}
643    
644            wake_up_forked_process(p);
645            ++total_forks;
646            if (clone_flags & CLONE_VFORK)
647                wait_for_completion(&vfork);
648            else
649                set_need_resched();
650    
651            \end{verbatim}
652                The \textit{wake\_up\_forked\_process} adds the newly created process to the runqueue and activates it. In order to activate task, it is queued at the tail of the runqueue using enqueue\_task function and the priority bitmap of the task is also updated. Refer to \url{kernel/sched.c} for detail functions. The exclusive operations related to runqueues are performed within the \textit{rq\_lock} and \textit{rq\_unlcok} function block. These functions enable and disable interrupts(irqs) on local cpu [cpu corresponding to the runqueue, usually referred by using \textit{smp\_processor\_id()} macro.] in addition to using spin\_lock.
653    
654            % \subsection{ABI: Application binary interface}
655            % TODO ABI
656    
657            \section{Destroying process}
658                There are several reasons for tasks to terminate:
659    
660            \begin{enumerate}
661             \item  exit() system call or end of program.
662             \item  sending a signal with default disposition to die.
663             \item  forcing a task to die when kernel receives exception running on behalf of process.
664            \end{enumerate}
665    
666                The sys\_exit function is defined in \url{kernel/exit.c} which calls function do\_exit(). The do\_exit function releases all the resources such as memory, open files, semaphores owned by the process. Following code explains the step by step process.
667    
668            \subsection{do\_exit function}
669                \\ \par The code is explained below in parts.
670    
671            \begin{verbatim}
672    
673            struct task_struct *tsk = current;
674    
675            if (in_interrupt())
676                 panic("Aiee, killing interrupt handler!");
677            if (!tsk->pid)
678                 panic("Attempted to kill the idle task!");
679            if (tsk->pid == 1)
680                 panic("Attempted to kill init!");
681            tsk->flags |= PF_EXITING;
682            del_timer_sync(&tsk->real_timer);
683    
684            if (unlikely(preempt_get_count()))
685                printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
686                    current->comm, current->pid,
687                    preempt_get_count());
688    
689            \end{verbatim}
690                The \textit{"current"} task global variable always points to the current task running. The process can not be destroyed while executing an interrupt handler. The processes 0 (idle), 1 (init) can not be destroyed. The macro "unlikely" is GNU compiler version specific\footnote{defined in \url{include/linux/compiler.h}} and gets reduced to macro argument while the macro \textit{"preempt\_get\_count"} is SMP PRE-EMPTION specific and returns the preemption count. This value should be 0 while exiting the system call.
691    
692            \begin{verbatim}
693    
694            acct_process(code);
695            __exit_mm(tsk);
696    
697            sem_exit();
698            __exit_files(tsk);
699            __exit_fs(tsk);
700            exit_namespace(tsk);
701            exit_sighand(tsk);
702            exit_thread();
703    
704            if (current->leader)
705                    disassociate_ctty(1);
706    
707            put_exec_domain(tsk->thread_info->exec_domain);
708            if (tsk->binfmt && tsk->binfmt->module)
709                    __MOD_DEC_USE_COUNT(tsk->binfmt->module);
710    
711            tsk->exit_code = code;
712            exit_notify();
713    
714            \end{verbatim}
715    
716                   The code removes memory, files, filesystem resources. All these steps are exactly opposite to those performed while creating the process (only in reverse order).
717            \par    Before exiting a process, the file information changed by the process should be updated. These task of process accounting is performed by the "acct\_process" function \footnote{Refer to \url{kernel/acct.c} for detail accounting}.
718            \par   The \textit{exit\_files} and \textit{exit\_fs} clean up the file system information associated with the process. They close the files opened by the process, free the fd and fdset arrays and also clear the kernel memory using \textit{kem\_cache\_free}.
719            % TODO details exit_namespace ,put_exec_domain
720            \par   The \textit{exit\_sighand} function in \url{kernel/signal.c} set the process signal structure to NULL and free its allocated memory. The signal queue is flushed at this point of time, hence no pending signals remain for the process to be deleted.
721            \par   The \textit{exit\_thread} function clears the I/O permission bitmap\footnote{The I/O permission bitmap is a part of Task State Segment.(TSS) It is used as a priviledge check for I/O instructions like IN, OUT. The bit map is 8KB in size for i386 architecture, one bit for each of the addresses of 64 KB.} for the process.Please refer to section ~\ref{sched:thread} for details about process thread.
722            \par   The \textit{exit\_notify} function indicates others that the current process is exiting. All process, group, session related properties are updated in this function. Following chekcs are performed to maintain proper parent child relationship.
723            \begin{itemize}
724            \item  Re-parent all the children of the exiting process, by trying to give them to another thread in thread group, and if no such member exists, give it to the global child reaper process (ie "init process".)
725            \item Check to see if any process groups have become orphan as a result of exiting.
726            \item If process groups have any stopped jobs, send them a SIGHUP and then a SIGCONT.
727            \end{itemize}
728            \begin{verbatim}
729    
730            schedule();
731            BUG();
732    
733            \end{verbatim}
734                    Finally, it calls the schedule() function and does not return. The function prototype in \url{include/linux/kernel.h} indicates it, too. Thus, a process deletion leads to rescheduling of all the processes.
735            \begin{verbatim}
736            NORET\_TYPE void do\_exit(long code) ATTRIB_NORET;
737            /* # define NORET_TYPE    /**/
738               # define ATTRIB_NORET  __attribute__((noreturn))
739             */
740            \end{verbatim}
741    

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26