/[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.1 by nayaniabhishek, Tue Nov 5 19:35:42 2002 UTC revision 1.2 by kdlinux2001, Thu Nov 21 13:08:15 2002 UTC
# Line 1  Line 1 
1  \chapter{Process Creation}  \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}.                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}.
4                    % TODO startup_32 \index {startup\_32}
 % TODO startup_32  
5  % TODO init_idle  % TODO init_idle
6    
7          \section{Process 1 init}          \section{Process 1 init} \index{init}
8                  After the initialization of paging, memory and timers in the start\_kernel function, kernel threads \index{kernel\_thread}  are created. The function 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}).               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    
10            \subsection{kernel\_thread} \label{proc:kt} \index{kernel\_thread}
11  % TODO kernel_thread  % TODO kernel_thread
12    
13                  \par The init function (fn parameter to kernel\_thread) locks the kernel and performs the basic setup related to foll. items.           \par The init function (fn parameter to kernel\_thread) locks the kernel and performs the basic setup related to foll. items.
14    
15          Function : do\_basic\_setup          \newline \textbf{Function : do\_basic\_setup} \newline
16                  The function do\_basic\_setup starts a migration thread, context thread and performs socket initialization.          The function do\_basic\_setup starts a migration thread, context thread and performs socket initialization.
17    
18          \begin{description}          \begin{description}
19          \item[migration thread] \index{migration\_thread} A migration thread (kernel\_thread) is started by calling migration\_init function [ \url{kernel/sched.c} ] for all cpus. Refer to ~\ref{smp:boot} for SMP initialization details.          \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.
20  % migration _thread  
21            \subsection{migration\_thread} \label{proc:mt} \index{migration\_thread}
22    % TODO migration _thread
23          \begin{verbatim}          \begin{verbatim}
24    
25              /* Note, smp_num_cpus is configured during smp boot process              /* Note, smp_num_cpus is configured during smp boot process
26                 in smp_boot_cpu function in arch/i386/kernel/smpboot.c                 in smp_boot_cpu function in arch/i386/kernel/smpboot.c
27               */               */
# Line 27  Line 30 
30                          CLONE\_FS | CLONE\_FILES | CLONE\_SIGNAL) < 0)                          CLONE\_FS | CLONE\_FILES | CLONE\_SIGNAL) < 0)
31                  BUG();                  BUG();
32              }              }
33    
34          \end{verbatim}          \end{verbatim}
35          \item[Sockets] Performs initialization related to sockets. The function sock\_init is defined in \url{net/socket.c}.          \item[Sockets] Performs initialization related to sockets. The function sock\_init is defined in \url{net/socket.c}.
36          % TODO kern_mount NFS mount          % TODO kern_mount NFS mount
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}          \item[context\_thread] The function start\_context\_thread creates a kernel\_thread named context\_thread. The function is defined in \url{kernel/context.c}
38          \begin{verbatim}          \begin{verbatim}
39    
40              kernel_thread(context_thread, NULL, CLONE_FS | CLONE_FILES);              kernel_thread(context_thread, NULL, CLONE_FS | CLONE_FILES);
41    
42          \end{verbatim}          \end{verbatim}
43    
44          \item[init\_calls] The function do\_init\_call flushes the pending tasks in the init queue, if any.          \item[init\_calls] The function do\_init\_call flushes the pending tasks in the init queue, if any.
45          \end{description}          \end{description}
46    
47  % TODO prepare_namespace, dup          \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).
         \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" (in this order) program.  
48    
49                  \par The code is explained below.          \newline \par The code is explained below.
50    
51          \begin{verbatim}          \begin{verbatim}
52    
53              lock_kernel();              lock_kernel();
54              do_basic_setup();              do_basic_setup();
55    
# Line 63  Line 69 
69              execve("/bin/init",argv_init,envp_init);              execve("/bin/init",argv_init,envp_init);
70              execve("/bin/sh",argv_sh,envp_init);              execve("/bin/sh",argv_sh,envp_init);
71              panic("No init found.  Try passing init= option to kernel.");              panic("No init found.  Try passing init= option to kernel.");
72    
73          \end{verbatim}          \end{verbatim}
74    
75                  The 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.          \subsection{Namespaces} \index{prepare\_namespace}
76    % TODO prepare_namespace, dup
77            The function calls prepare\_namespace.
78    
79            \subsection{Function init()} \index{init}
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}          \begin{description}
83          \item[Runlevel] Start up system run level.          \item[Runlevel] Start up system run level.
# Line 75  Line 87 
87          \item[Other prcesses] Certain actions or processes to be run if certain signals or user actions are indicated.          \item[Other prcesses] Certain actions or processes to be run if certain signals or user actions are indicated.
88          \end{description}          \end{description}
89    
90                  \section{Structures}          \section{Structures}
91                  Within the linux kernel, every process is associated with a process descriptor defined by struct 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 \label{do_fork} do\_fork function. Following paragraph describes the task\_struct in detail.               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.
92    
93            \subsection{The process [task\_struct] structure} \index{task\_struct}
94          % TODO task_struct and others          % TODO task_struct and others
95    
96          \section{Creating New process}          \section{Creating New process}
97    
98          % TODO dup resource , copy on write , __clone LWP , _syscall          % TODO dup resource , copy on write , __clone LWP , _syscall
99                  Linux kernel 2.4 supports 3 types of processes.                  Linux kernel 2.4 supports 3 types of processes.
100          \begin{description}          \begin{description}
101                  \item[\large{1. idle threads}]                  \item[\large{1. idle threads}]
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.                  \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.
103                  \item[\large{2. kernel threads}]                  \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.          \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.
105    
106                          Example of a kernel\_thread :          \begin{minipage}{0.90\textwidth}
107                          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.          Example of a kernel\_thread :
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.
109          \begin{verbatim}          \begin{verbatim}
110    
111          for (cpu = 0; cpu < smp\_num\_cpus; cpu++) {          for (cpu = 0; cpu < smp\_num\_cpus; cpu++) {
112               if (kernel\_thread(migration\_thread, (void *) (long) cpu,               if (kernel\_thread(migration\_thread, (void *) (long) cpu,
113                      CLONE\_FS | CLONE\_FILES | CLONE\_SIGNAL) < 0)                      CLONE\_FS | CLONE\_FILES | CLONE\_SIGNAL) < 0)
114               BUG();               BUG();
115          }          }
116    
117          \end{verbatim}          \end{verbatim}
118                  The function migration\_init daemonizes itself.                  The function migration\_init daemonizes itself.
119          \begin{verbatim}          \begin{verbatim}
120    
121          static int migration\_thread(void * bind\_cpu) {          static int migration\_thread(void * bind\_cpu) {
122              int ret;              int ret;
123          \end{verbatim}          \end{verbatim}
# Line 106  Line 126 
126              sigfillset(&current->blocked);              sigfillset(&current->blocked);
127              set\_fs(KERNEL\_DS);              set\_fs(KERNEL\_DS);
128          }          }
129    
130          \end{verbatim}          \end{verbatim}
131            \end{minipage} \end{center}
132    
133                  \item[\large{3. user tasks}]                  \item[\large{3. user tasks}]
134                  \par user tasks are generally created by user applications using fork() or clone() function calls.          \par user tasks are generally created by user applications using fork() or clone() function calls.
135          \end{description}          \end{description}
136    
137          \section{fork, clone calls and the do\_fork function}          \section{fork, clone system calls}
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.              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.
139                  \par These functions are defined in \url{arch/i386/kernel/process.c}          \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}
 while the system call numbers are defined in \url{include/asm-i386/unistd.h}  
140    
141                  \par Example of fork system call :          \par Example of fork system call : \index{fork}
142    
143          \begin{enumerate}          \begin{enumerate}
144           \item  User calls fork();           \item  User calls fork();
# Line 127  while the system call numbers are define Line 148  while the system call numbers are define
148           \item  Kernel exits the handler by calling ret\_from\_sys\_call();           \item  Kernel exits the handler by calling ret\_from\_sys\_call();
149          \end{enumerate}          \end{enumerate}
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.          \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.
152    
153            \newline \par Example of sys\_clone function :
154    
                 \par Example of sys\_clone function :  
                   
155          \begin{verbatim}          \begin{verbatim}
156    
157          asmlinkage int sys_clone(struct pt_regs regs)          asmlinkage int sys_clone(struct pt_regs regs)
158          {          {
159              struct task_struct *p;              struct task_struct *p;
# Line 144  while the system call numbers are define Line 166  while the system call numbers are define
166              p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0);              p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0);
167              return IS_ERR(p) ? PTR_ERR(p) : p->pid;              return IS_ERR(p) ? PTR_ERR(p) : p->pid;
168          }          }
169    
170          \end{verbatim}          \end{verbatim}
171    
172                  Function do\_fork() \label{proc:do_fork}          \subsection{do\_fork function} \index{do\_fork}
173                  \textit{File: }\url{kernel/fork.c}\\          Function do\_fork() \label{proc:do_fork}
174            \textit{File: }\url{kernel/fork.c}\\ \newline
175    
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.          \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.
177                                    
178          \begin{verbatim}          \begin{verbatim}
179                  struct task_struct *do_fork(unsigned long clone_flags,                  struct task_struct *do_fork(unsigned long clone_flags,
180                              unsigned long stack_start,                              unsigned long stack_start,
181                              struct pt_regs *regs,                              struct pt_regs *regs,
182                              unsigned long stack_size)                              unsigned long stack_size)
183          \end{verbatim}          \end{verbatim}
184    
185                  The do\_fork function takes foll. arguments               The do\_fork function takes foll. arguments.
186          \begin{description}          \begin{description}
187          \item[clone\_flags] : Flags to create process. This is different for fork/clone/vfork calls.          \item[clone\_flags] : Flags to create process. This is different for fork/clone/vfork calls.
188          \item[stack\_start] : top of stack required for copy\_routine.          \item[stack\_start] : top of stack required for copy\_routine.
189          \item[regs] : The register structure defined in \url{include/asm-i386/ptrace.h}          \item[regs] : The register structure defined in \url{include/asm-i386/ptrace.h}
190          \item[stack\_size] : Size of stack, usually 0.          \item[stack\_size] : Size of stack, usually 0.
191          \item[]          \item[] \&
192          \item[return value] : (pointer to) Newly created task.          \item[return value] : (pointer to) Newly created task.
193          \end{description}          \end{description}
194    
195                  \par The code is explained below in parts.          \par The code is explained below in parts.
196    
197          \begin{verbatim}          \begin{verbatim}
198    
# Line 193  while the system call numbers are define Line 217  while the system call numbers are define
217    
218          if (nr_threads >= max_threads)          if (nr_threads >= max_threads)
219                goto bad_fork_cleanup_count;                goto bad_fork_cleanup_count;
220    
221          \end{verbatim}          \end{verbatim}
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).              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).
223                  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 "capable()"\footnote{defined in \url{linux/sched.h}} 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}.          \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}.
224          % dup_task_struct          % TODO dup_task_struct
225    
226          \begin{verbatim}          \begin{verbatim}
227    
# Line 214  while the system call numbers are define Line 239  while the system call numbers are define
239          copy_flags(clone_flags, p);          copy_flags(clone_flags, p);
240          p->pid = get_pid(clone_flags);          p->pid = get_pid(clone_flags);
241          p->proc_dentry = NULL;          p->proc_dentry = NULL;
242    
243          \end{verbatim}          \end{verbatim}
244                  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}. 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 personality() system call. the macro get\_exec\_domain is used to increament the module count of the module associated with the exec\_domain while its counterpart put\_exec\_domain is used to decreament it.  
245                  \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 sys\_clone call.             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.
246    
247            % TODO map_segment
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    
250          \begin{verbatim}          \begin{verbatim}
251    
# Line 249  while the system call numbers are define Line 278  while the system call numbers are define
278          p->tty_old_pgrp = 0;          p->tty_old_pgrp = 0;
279          p->times.tms_utime = p->times.tms_stime = 0;          p->times.tms_utime = p->times.tms_stime = 0;
280          p->times.tms_cutime = p->times.tms_cstime = 0;          p->times.tms_cutime = p->times.tms_cstime = 0;
281    
282          \end{verbatim}          \end{verbatim}
         \par    The 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 init\_waitqueue\_head initializes the waitqueue header node which contains the spinlock along with the linked list.  
                 The inline function clear\_tsk\_thread\_flag (defined in \url{include/linux/sched.h}) calls clear\_ti\_thread\_flag (defined in \url{include/linux/thread_info.h}) to clear the flag information of the thread within the task structure.  
283    
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.
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.
286    
287            \index{bitops} \index{btrl}
288          \begin{verbatim}          \begin{verbatim}
289    
290          /*** File : {include/asm-i386/bitops.h}  ***/          /*** File : {include/asm-i386/bitops.h}  ***/
291          static __inline__ void clear_bit(int nr, volatile unsigned long * addr)          static __inline__ void clear_bit(int nr, volatile unsigned long * addr)
292          {          {
# Line 262  while the system call numbers are define Line 295  while the system call numbers are define
295                      :"=m" (ADDR)                      :"=m" (ADDR)
296                      :"Ir" (nr));                      :"Ir" (nr));
297          }          }
         \end{verbatim}  
   
                 \textit{init\_completion} is wrapper inline function to initialize the wait queue header specially used during vfork() system call. The function 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. 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.  
                 The dynamic timer associated with the task structure is real\_timer. When, a new task is created, the timer is initialized using 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.  
298    
299            \end{verbatim}
300            % TODO explain code
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.
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.
303          \begin{verbatim}          \begin{verbatim}
304    
305          #ifdef CONFIG_SMP          #ifdef CONFIG_SMP
306          {          {
307               int i;               int i;
# Line 279  while the system call numbers are define Line 313  while the system call numbers are define
313               spin_lock_init(&p->sigmask_lock);               spin_lock_init(&p->sigmask_lock);
314          }          }
315          #endif          #endif
316    
317          \end{verbatim}          \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 sigmask\_lock used to block the signals by the process. Refer to ~\ref{signals} for more details.              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.
319    
320          \begin{verbatim}          \begin{verbatim}
321    
322          p->array = NULL;          p->array = NULL;
323          p->lock_depth = -1;             /* -1 = no lock */          p->lock_depth = -1;             /* -1 = no lock */
324          p->start_time = jiffies;          p->start_time = jiffies;
# Line 307  while the system call numbers are define Line 343  while the system call numbers are define
343          if (copy_namespace(clone_flags, p))          if (copy_namespace(clone_flags, p))
344                goto bad_fork_cleanup_mm;                goto bad_fork_cleanup_mm;
345          retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);          retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
346    
347          \end{verbatim}          \end{verbatim}
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}].                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                  Then, various system resources are copied to the newly created process.          \par   Then, various system resources are copied to the newly created process. The following explains the the functions in short.
350          copy\_sighand copies all signal handlers action          \begin{itemize}
351          memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action));          \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.
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.
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.
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.
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.
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.
358            \end{itemize}
359          \begin{verbatim}          \begin{verbatim}
360    
361          /*** Now, setup other process attributes ***/          /*** Now, setup other process attributes ***/
# Line 322  while the system call numbers are define Line 366  while the system call numbers are define
366          p->swappable = 1;          p->swappable = 1;
367          p->exit_signal = clone_flags & CSIGNAL;          p->exit_signal = clone_flags & CSIGNAL;
368          p->pdeath_signal = 0;          p->pdeath_signal = 0;
369    
370          \end{verbatim}          \end{verbatim}
371                  The self\_exec\_id and 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}.              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}.
372    
373          \begin{verbatim}          \begin{verbatim}
374    
# Line 339  while the system call numbers are define Line 384  while the system call numbers are define
384          }          }
385          p->sleep_timestamp = jiffies;          p->sleep_timestamp = jiffies;
386          __restore_flags(flags);          __restore_flags(flags);
387    
388          \end{verbatim}          \end{verbatim}
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.                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.
390                  When new child process is created, the 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 scheduler\_tick() function to update the kernel statisticks.          \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    
392          \begin{verbatim}          \begin{verbatim}
393    
# Line 371  while the system call numbers are define Line 417  while the system call numbers are define
417          hash_pid(p);          hash_pid(p);
418          nr_threads++;          nr_threads++;
419          write_unlock_irq(&tasklist_lock);          write_unlock_irq(&tasklist_lock);
         \end{verbatim}  
                 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].  
                 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}.  
                 \par \textbf{Hashing Process Ids }  
   
420    
421                  \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 hash\_pid function adds the new task to the hash table using process pid as key and pid\_fashfn as hashing function.          \end{verbatim}
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].
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{
425            \newline
426                  Hashing Process Ids } \index{hash\_pid}
427            \newline
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.
429    
430          \begin{verbatim}          \begin{verbatim}
431          #define pid_hashfn(x)   ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))          #define pid_hashfn(x)   ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
432          \end{verbatim}          \end{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.              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.
435    
436          \begin{verbatim}          \begin{verbatim}
437    
438          wake_up_forked_process(p);          wake_up_forked_process(p);
439          ++total_forks;          ++total_forks;
440          if (clone_flags & CLONE_VFORK)          if (clone_flags & CLONE_VFORK)
441              wait_for_completion(&vfork);              wait_for_completion(&vfork);
442          else          else
443              set_need_resched();              set_need_resched();
444    
445          \end{verbatim}          \end{verbatim}
446                  The 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 rq\_lock and rq\_unlcok function block. These functions enable and disable interrupts(irqs) on local cpu [cpu corresponding to the runqueue, usually refered by using smp\_processor\_id() macro.] in addition to using spin\_lock.              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.
447    
448            \subsection{ABI: Application binary interface}
449            % TODO ABI
450    
451          \section{Destroying process}          \section{Destroying process}
452                  There are several reasons for tasks to terminate:              There are several reasons for tasks to terminate:
453    
454          \begin{enumerate}          \begin{enumerate}
455           \item  exit() system call or end of program.           \item  exit() system call or end of program.
# Line 404  while the system call numbers are define Line 457  while the system call numbers are define
457           \item  forcing a task to die when kernel receives exception running on behalf of process.           \item  forcing a task to die when kernel receives exception running on behalf of process.
458          \end{enumerate}          \end{enumerate}
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.              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.
461    
462                  \par The code is explained below in parts.          \subsection{do\_exit function}
463                \newline \par The code is explained below in parts.
464    
465          \begin{verbatim}          \begin{verbatim}
466    
467          struct task_struct *tsk = current;          struct task_struct *tsk = current;
468    
469          if (in_interrupt())          if (in_interrupt())
# Line 424  while the system call numbers are define Line 479  while the system call numbers are define
479              printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",              printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
480                  current->comm, current->pid,                  current->comm, current->pid,
481                  preempt_get_count());                  preempt_get_count());
482    
483          \end{verbatim}          \end{verbatim}
484                  The "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 "preempt\_get\_count" is SMP PRE-EMPTION specific and returns the preemption count. This value should be 0 while exiting the system call.              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.
485    
486          \begin{verbatim}          \begin{verbatim}
487    
488          acct_process(code);          acct_process(code);
489          __exit_mm(tsk);          __exit_mm(tsk);
490    
# Line 447  while the system call numbers are define Line 504  while the system call numbers are define
504    
505          tsk->exit_code = code;          tsk->exit_code = code;
506          exit_notify();          exit_notify();
507    
508          \end{verbatim}          \end{verbatim}
509    
510                  \par The code removes memory, files, filesystem resources. All these steps are exactly opposite to those performed while creating the process (only in reverse order).                 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                  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}.          \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}.
512          % TODO details exit_namespace , exit_sighand, exit_thread          % TODO details exit_namespace , exit_sighand, exit_thread
513    
514          \begin{verbatim}          \begin{verbatim}
515    
516          schedule();          schedule();
517          BUG();          BUG();
518    
519          \end{verbatim}          \end{verbatim}
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.                  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}          \begin{verbatim}

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

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