The proc Table For a process to exist (at least from the point of view of the kernel), a proc data structure must be placed in the system proc table. Prior to HP-UX 11i, the proc table was a static array, the kernel pointer *proc defined its beginning, and the size was tuned via the kernel parameter nproc. The proc table is one of the largest tables in the kernel (at HP-UX 11.00, each proc structure was 700 bytes), and tuning nproc could significantly alter the size of the kernel. This effect was amplified, since many additional kernel data structures were sized in proportion to nproc. With the release of HP-UX 11i, the proc table has become dynamic (see Figure 5-2). This means that individual proc structures are allocated from kernel memory arenas as they are needed. The beginning of this key system table is now pointed to by *proc_list, and linkage pointers have been added to the structure to create a dynamic linked list. At HP-UX 11i, a proc structure has grown to 828 bytes. Figure 5-2. Kernel Process Tables To date, not all kernel data structures have been converted from static to dynamic, which necessitates the maintenance of the nproc parameter to be used during the sizing of related tables. In addition, nproc acts as a tunable limit for the number of processes a kernel may be expected to manage. In the current implementation, structures allocated to the proc table are not returned to the kernel memory pool when their process is terminated. Instead, the proc structure's status is set to SUNUSED, and it is placed on a free list. The current thinking is that once a proc entry has been allocated, it represents a type of high-water mark for system activity, and the system will simply place it on a free list so that it will be available next time the process count is high. Let's explore some additional linkages and parameters stored there. q4 may be used to examine the process table on a live system. First, launch q4, passing the kernel image file, /stand/vmunix, and /dev/kmem as arguments (if you have not set q4 up on your system, refer to Chapter 16, "Tools Overview," for an explanation of the process). # q4 /stand/vmunix /dev/mem
Now you can examine the fields of the proc structure: q4> fields struct proc | more
To load the contents of the proc table on an HP-UX 11i system, q4> load struct proc from proc_list next p_global_proc max nproc (to load all entries)or q4> load struct proc from proc_list next p_factp_proc max nproc (to load active entries only) For an HP-UX 11.0 (or earlier) system, q4> load struct proc from proc max nproc
The following q4 fields listing (Listing 5.1) has been condensed and annotated for our discussion. (A q4 field listing produces six fields per line: byte-offset, bit-offset, size-in-whole-bytes, number of additional bits, field-type, and field-label.) Listing 5.1. q4> fields struct proc Forward and previous pointers linking all the active processes 0 0 4 0 * p_factp 4 0 4 0 * p_pactp Various pointers to the process's thread(s) 8 0 4 0 * p_firstthreadp 12 0 4 0 * p_lastthreadp 32 0 4 0 int p_created_threads Spinlock structures to protect access to proc and thread data 24 0 4 0 * thread_lock 28 0 4 0 * p_lock The process flags (see enum proc_flag and proc_flag2 in proc_private.h) The process states are: SUNUSED = 0 unused, proc available SWAIT = 1 abandoned SIDL = 2 in process creation( kernel routine new_proc() ) SZOMB = 3 in process termination ( waiting for signal from parent process) SSTOP = 4 process is currently stopped SINUSE = 5 proc entry in use 36 0 4 0 enum4 p_flag2 40 0 4 0 enum4 p_flag 44 0 4 0 enum4 p_stat A partitioned pointer to the process's file descriptor(s) 56 0 4 0 * p_ofilep This process's default priority and nice values and a reference count (used by the kernel to determine when to call freeproc() to cleanup the process) 72 0 2 0 u_short p_pri 74 0 1 0 char p_nice 76 0 4 0 int p_refcnt A forward link connecting all proc structures both active and free 92 0 4 0 * p_global_proc The process's credentials; user id, su id, process group id, process id, parent process id, maximum number of physical page frames (known at the resident set size), forward and reverse hash chain links (there is a hash table used to speed up location of a proc structure entry when the process id is known), forward and reverse links connecting all proc table entries belonging to the same user id, and a pointer to this process's virtual address space header (structure vas) 176 0 4 0 int p_uid 180 0 4 0 int p_suid 188 0 4 0 int p_pgrp 192 0 4 0 int p_pid 196 0 4 0 int p_ppid 200 0 4 0 u_long p_maxrss 204 0 4 0 * p_idhash 208 0 4 0 * p_ridhash 220 0 4 0 * p_uidlist 224 0 4 0 * p_ruidlist 248 0 4 0 * p_vas Memory and swap reserved for this process 252 0 2 0 short p_memresv 254 0 2 0 short p_swpresv Deactivation time for this process (if it has been deactivated) and a forward linkage connecting all deactivated processes 264 0 4 0 int p_deactime 304 0 4 0 * p_nextdeact Pointer to temporary vforkinfo data structure used during a vfork() call 320 0 4 0 * p_vforkbuf The type of scheduling policy for this process's threads 324 0 4 0 u_int p_schedpolicy Pointer to the process's command line arguments and the process's base name 456 0 4 0 * p_cmnd 460 0 15 0 char[15] p_comm Number of clock ticks charged to this process 504 0 4 0 int p_ticks In addition, there are many fields used by processor affinity calls, the signal system, System-V IPC services, and many more. We return to many of these parameters as we continue our exploration of the kernel. The next stop on our trip is the kthread structure. |