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.
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.
|