Download Linux Process Management: Task Struct, Process Switching, and Process Creation and more Study notes Operating Systems in PDF only on Docsity!
Processes
-^
Process descriptor (task_struct)– Static properties of processes– State, id, relationships, wait queue, limits
-^
Process switching (context switch)– Hardware context, TSS, switch_to()– Saving floating-point registers
-^
Creating processes– clone(), fork(), vfork()– Kernel threads (vs. user threads)
-^
Destroying processes– Termination vs. removal
Process Descriptor
-^
Process – dynamic, program in motion– Kernel data structures to maintain "state"– Descriptor, PCB (control block), task_struct– Larger than you think! (about 1K)– Complex struct with pointers to others
-^
Type of info in task_struct– Registers, state, id, priorities, locks, files, signals,
memory maps, locks, queues, list pointers, …
-^
Some details– Address of first few fields hardcoded in asm– Careful attention to cache line layout
Process Identity
• Users: pid; Kernel: address of descriptor
- Pids dynamically allocated, reused
- 16 bits – 32767, avoid immediate reuse
- Pid to address hash– 2.2: static task_array
•^
Statically limited # tasks
- This limitation removed in 2.
• current->pid (macro)
Descriptor Storage/Allocation
• Descriptors stored in kernel data segment
- Each process gets a 2 page (8K) "kernel
stack" used while in the kernel (security)
- task_struct stored here; rest for stack– Easy to derive descriptor from esp (stack ptr)– Implemented as union task_union { }
• Small (16) cache of free task_unions
- free_task_struct(), alloc_task_struct()
Process Relationships
• Processes are related
- Parent/child (fork()), siblings– Possible to "re-parent"
- Parent vs. original parent
- Parent can "wait" for child to terminate
• Process groups
- Possible to send signals to all members
• Sessions
- Processes related to login
Wait Queues
• Blocking implementation
- Change state to TASK_(UN)INTERRUPTIBLE– Add node to wait queue
- All processes waiting for specific "event"• Usually just one element• Used for timing, synch, device i/o, etc.• Structure is a bit optimized• struct wait_queue usually allocated on kernel stack
Process Limits
• Optional
resource
limits (accounting)
- getrlimit(), setrlimit() (user control)– Root can establish rlim_min, rlim_max
• Resources (RLIMIT_whatever)
- CPU, FSIZE (file size), DATA (heap), STACK,– CORE, RSS (frames), NPROC (# processes),– NOFILE (# open files), MEMLOCK, AS
Process Switching - Context
-^
Hardware context– Registers (including page table register)– Hardware support but Linux uses software
- About the same speed currently• Software might be optimized more• Better control over validity checking
- prev, next task_struct pointers -^
Linux TSS (thread_struct)– Base registers, floating-point, debug, etc.– I/O permissions bitmap
- Intel feature to allow userland access to i/o ports!• ioperm(), iopl() (Intel-specific)
Process Switching – FP Registers
-^
This is pretty weird
-^
Pentium – on chip FPU– Backwards compatibility, ESCAPE prefix– Not saved by default– MMX Instructions use FPU
-^
FP registers– Saved "on demand", reload "when needed" (lazily)
-^
TS Flag set on context switch– FP instructions cause exception (device unavailable)– Kernel intervenes by loading FP regs, clearing TS– unlazy_fpu(), math_state_retstore()
Creating Processes
•^
clone(), fork(), vfork()– Fork duplicates (most) parent resources– Exec tears down old address space and installs a new one
(corresponding to process image on disk)
- Most forks are part of a fork-exec sequence– Wasteful to copy resources that are then overwritten -^
Old solution (hack): vfork– Parent/child share; parent blocks until child ends
-^
New solution: COW copy-on-write– Share r/w pages r/o until write (fault), then copy
-^
Linux solution: clone()– Specify what resources to share/duplicate– CLONE_VM, _FS, _FILES, _SIGHAND, _PID
Benefits of Threading
• Lightweight context switch, blocking
- Increases CPU (quantum) utilization
• Logically structures concurrent activities
- Avoids uglier "async" code: e.g. sig handlers
• Possible to exploit parallelism (SMP)
kernel
threads!
- Kernel doesn't "know about" user threads– Kernel threads are "unit of scheduling"
Linux: Processes or Threads?
• Linux uses a neutral term: tasks• Traditional view
- Threads exist "inside" processes
• Linux view
- Threads: processes that share address space– Linux "threads" (tasks) are really "kernel
threads"
clone()
• fork() is implemented as a wrapper around
clone() with specific parameters
• __clone(fp, data, flags, stack)
- "_" means "don’t call this directly"– fp is thread start function, data is params– flags is or of CLONE flags– stack is address of user stack– clone() calls do_fork() to do the work
do_fork()
-^
Highlights– alloc_task_struct()– Copy current into new– find_empty_process()– get_pid()– Update ancestry– Copy components based on flags– copy_thread()– Link into task list, update nr_tasks– Set TASK_RUNNING– wake_up_process()