From: David van Moolenbroek Date: Sun, 8 Nov 2015 12:39:45 +0000 (+0000) Subject: MIB: slim process tables to reduce memory usage X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/already%20found%20%2A/doxygen.log?a=commitdiff_plain;h=refs%2Fchanges%2F56%2F3256%2F2;p=minix.git MIB: slim process tables to reduce memory usage - About 80% of PM's process table consisted of per-signal sigaction structures. This is information not used by the MIB service, and can safely be stored outside the main process table. - The MIB service does not need most of the VFS process table, so VFS now generates a "light" version of its table upon request, with just the fields used by the MIB service. The result is a size reduction of the MIB service of about 700KB. Change-Id: I79fe7239361fbfb45286af8e86a10aed4c2d2be7 --- diff --git a/minix/include/minix/sysinfo.h b/minix/include/minix/sysinfo.h index 1e4e2bbf9..edb5643c5 100644 --- a/minix/include/minix/sysinfo.h +++ b/minix/include/minix/sysinfo.h @@ -14,6 +14,7 @@ int getsysinfo(endpoint_t who, int what, void *where, size_t size); #define SI_CALL_STATS 9 /* system call statistics */ #define SI_PROCPUB_TAB 11 /* copy of public entries of process table */ #define SI_PROCALL_TAB 12 /* copy of both private and public entries */ +#define SI_PROCLIGHT_TAB 13 /* copy of light version of process table */ #endif diff --git a/minix/servers/mib/proc.c b/minix/servers/mib/proc.c index 277497ff0..f103b483a 100644 --- a/minix/servers/mib/proc.c +++ b/minix/servers/mib/proc.c @@ -14,11 +14,10 @@ typedef struct proc ixfer_proc_t; typedef struct mproc ixfer_mproc_t; -typedef struct fproc ixfer_fproc_t; static ixfer_proc_t proc_tab[NR_TASKS + NR_PROCS]; static ixfer_mproc_t mproc_tab[NR_PROCS]; -static ixfer_fproc_t fproc_tab[NR_PROCS]; +static struct fproc_light fproc_tab[NR_PROCS]; /* * The number of processes added to the current number of processes when doing @@ -103,8 +102,9 @@ update_tables(void) } } - /* Retrieve the VFS process table, which has no magic number. */ - r = getsysinfo(VFS_PROC_NR, SI_PROC_TAB, fproc_tab, sizeof(fproc_tab)); + /* Retrieve an extract of the VFS process table. */ + r = getsysinfo(VFS_PROC_NR, SI_PROCLIGHT_TAB, fproc_tab, + sizeof(fproc_tab)); if (r != OK) { printf("MIB: unable to obtain VFS process table (%d)\n", r); @@ -226,7 +226,7 @@ get_lwp_stat(int mslot, uint64_t * wcptr, char * wmptr, size_t wmsz, int32_t * flag) { struct mproc *mp; - struct fproc *fp; + struct fproc_light *fp; struct proc *kp; const char *wmesg; uint64_t wchan; @@ -290,9 +290,9 @@ get_lwp_stat(int mslot, uint64_t * wcptr, char * wmptr, size_t wmsz, } else if (mp->mp_flags & SIGSUSPENDED) { wchan = 0x202; wmesg = "pause"; - } else if (fp->fp_blocked_on != FP_BLOCKED_ON_NONE) { - wchan = (fp->fp_blocked_on << 8) | 0x03; - switch (fp->fp_blocked_on) { + } else if (fp->fpl_blocked_on != FP_BLOCKED_ON_NONE) { + wchan = (fp->fpl_blocked_on << 8) | 0x03; + switch (fp->fpl_blocked_on) { case FP_BLOCKED_ON_PIPE: wmesg = "pipe"; break; @@ -311,8 +311,8 @@ get_lwp_stat(int mslot, uint64_t * wcptr, char * wmptr, size_t wmsz, * wchan value, and use the driver's process name, * without parentheses, as wmesg text. */ - wchan |= (uint64_t)fp->fp_task << 16; - fill_wmesg(wmptr, wmsz, fp->fp_task, FALSE /*ipc*/); + wchan |= (uint64_t)fp->fpl_task << 16; + fill_wmesg(wmptr, wmsz, fp->fpl_task, FALSE /*ipc*/); break; default: /* A newly added flag we don't yet know about? */ @@ -687,7 +687,7 @@ static void fill_proc2_user(struct kinfo_proc2 * p, int mslot) { struct mproc *mp; - struct fproc *fp; + struct fproc_light *fp; time_t boottime; dev_t tty; struct timeval tv; @@ -703,7 +703,7 @@ fill_proc2_user(struct kinfo_proc2 * p, int mslot) fp = &fproc_tab[mslot]; zombie = (mp->mp_flags & (TRACE_ZOMBIE | ZOMBIE)); - tty = (!zombie) ? fp->fp_tty : NO_DEV; + tty = (!zombie) ? fp->fpl_tty : NO_DEV; p->p_eflag = 0; if (tty != NO_DEV) @@ -869,7 +869,7 @@ mib_kern_proc2(struct mib_call * call, struct mib_node * node __unused, continue; /* TODO: revoke(2) support */ /* Do not access the fproc_tab slot of zombies. */ zombie = (mp->mp_flags & (TRACE_ZOMBIE | ZOMBIE)); - tty = (zombie) ? fproc_tab[mslot].fp_tty : NO_DEV; + tty = (zombie) ? fproc_tab[mslot].fpl_tty : NO_DEV; if ((dev_t)arg == KERN_PROC_TTY_NODEV) { if (tty != NO_DEV) continue; diff --git a/minix/servers/pm/forkexit.c b/minix/servers/pm/forkexit.c index bacff3510..30dfb5a3d 100644 --- a/minix/servers/pm/forkexit.c +++ b/minix/servers/pm/forkexit.c @@ -84,6 +84,8 @@ int do_fork() /* Set up the child and its memory map; copy its 'mproc' slot from parent. */ procs_in_use++; *rmc = *rmp; /* copy parent's process slot to child's */ + rmc->mp_sigact = mpsigact[next_child]; /* restore mp_sigact ptr */ + memcpy(rmc->mp_sigact, rmp->mp_sigact, sizeof(mpsigact[next_child])); rmc->mp_parent = who_p; /* record child's parent */ if (!(rmc->mp_trace_flags & TO_TRACEFORK)) { rmc->mp_tracer = NO_TRACER; /* no tracer attached */ @@ -182,6 +184,8 @@ int do_srv_fork() /* Set up the child and its memory map; copy its 'mproc' slot from parent. */ procs_in_use++; *rmc = *rmp; /* copy parent's process slot to child's */ + rmc->mp_sigact = mpsigact[next_child]; /* restore mp_sigact ptr */ + memcpy(rmc->mp_sigact, rmp->mp_sigact, sizeof(mpsigact[next_child])); rmc->mp_parent = who_p; /* record child's parent */ if (!(rmc->mp_trace_flags & TO_TRACEFORK)) { rmc->mp_tracer = NO_TRACER; /* no tracer attached */ diff --git a/minix/servers/pm/main.c b/minix/servers/pm/main.c index af86de54a..86dee877a 100644 --- a/minix/servers/pm/main.c +++ b/minix/servers/pm/main.c @@ -145,6 +145,7 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) for (rmp=&mproc[0]; rmp<&mproc[NR_PROCS]; rmp++) { init_timer(&rmp->mp_timer); rmp->mp_magic = MP_MAGIC; + rmp->mp_sigact = mpsigact[rmp - mproc]; } /* Build the set of signals which cause core dumps, and the set of signals diff --git a/minix/servers/pm/mproc.h b/minix/servers/pm/mproc.h index f88944470..02069fab9 100644 --- a/minix/servers/pm/mproc.h +++ b/minix/servers/pm/mproc.h @@ -13,7 +13,13 @@ /* Needs to be included here, for 'ps' etc */ #include "const.h" +/* + * The per-process sigaction structures are stored outside of the mproc table, + * so that the MIB service can avoid pulling them in, as they account for + * roughly 80% of the per-process state. + */ typedef struct sigaction ixfer_sigaction; +EXTERN ixfer_sigaction mpsigact[NR_PROCS][_NSIG]; EXTERN struct mproc { char mp_exitstatus; /* storage for status when process exits */ @@ -48,10 +54,7 @@ EXTERN struct mproc { sigset_t mp_sigpending; /* pending signals to be handled */ sigset_t mp_ksigpending; /* bitmap for pending signals from the kernel */ sigset_t mp_sigtrace; /* signals to hand to tracer first */ - ixfer_sigaction mp_sigact[_NSIG]; /* as in sigaction(2) */ -#ifdef __ACK__ - char mp_padding[60]; /* align structure with new libc */ -#endif + ixfer_sigaction *mp_sigact; /* as in sigaction(2), pointer into mpsigact */ vir_bytes mp_sigreturn; /* address of C library __sigreturn function */ minix_timer_t mp_timer; /* watchdog timer for alarm(2), setitimer(2) */ clock_t mp_interval[NR_ITIMERS]; /* setitimer(2) repetition intervals */ diff --git a/minix/servers/vfs/fproc.h b/minix/servers/vfs/fproc.h index 8d74292e9..28bc56d3c 100644 --- a/minix/servers/vfs/fproc.h +++ b/minix/servers/vfs/fproc.h @@ -71,4 +71,16 @@ EXTERN struct fproc { #define REVIVING 0xDEEAD /* process is being revived from suspension */ #define PID_FREE 0 /* process slot free */ +/* + * Upon request from the MIB service, this table is filled with a relatively + * small subset of per-process fields, so that the MIB service can avoid + * pulling in the entire fproc table. Other fields may be added to this + * structure as required by the MIB service. + */ +EXTERN struct fproc_light { + dev_t fpl_tty; /* copy of fproc.fp_tty */ + int fpl_blocked_on; /* copy of fproc.fp_blocked_on */ + endpoint_t fpl_task; /* copy of fproc.fp_task */ +} fproc_light[NR_PROCS]; + #endif /* __VFS_FPROC_H__ */ diff --git a/minix/servers/vfs/misc.c b/minix/servers/vfs/misc.c index dcaa53588..29a97fb49 100644 --- a/minix/servers/vfs/misc.c +++ b/minix/servers/vfs/misc.c @@ -51,6 +51,8 @@ static void free_proc(int flags); *===========================================================================*/ int do_getsysinfo(void) { + struct fproc *rfp; + struct fproc_light *rfpl; vir_bytes src_addr, dst_addr; size_t len, buf_size; int what; @@ -75,6 +77,17 @@ int do_getsysinfo(void) src_addr = (vir_bytes) dmap; len = sizeof(struct dmap) * NR_DEVICES; break; + case SI_PROCLIGHT_TAB: + /* Fill the light process table for the MIB service upon request. */ + rfpl = &fproc_light[0]; + for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++, rfpl++) { + rfpl->fpl_tty = rfp->fp_tty; + rfpl->fpl_blocked_on = rfp->fp_blocked_on; + rfpl->fpl_task = rfp->fp_task; + } + src_addr = (vir_bytes) fproc_light; + len = sizeof(fproc_light); + break; #if ENABLE_SYSCALL_STATS case SI_CALL_STATS: src_addr = (vir_bytes) calls_stats;