Implement getrusage in kernel pm vfs vm and libc

This commit is contained in:
Xiaoguang Sun 2013-06-11 16:33:34 +00:00
parent 4050190e78
commit d7efdde5a6
25 changed files with 270 additions and 11 deletions

View File

@ -1,4 +1,4 @@
#define NCALLS 118 /* number of system calls allowed */ #define NCALLS 124 /* number of system calls allowed */
/* In case it isn't obvious enough: this list is sorted numerically. */ /* In case it isn't obvious enough: this list is sorted numerically. */
#define EXIT 1 #define EXIT 1
@ -113,3 +113,5 @@
* really a standalone call. * really a standalone call.
*/ */
#define MAPDRIVER 122 /* to VFS, map a device */ #define MAPDRIVER 122 /* to VFS, map a device */
#define GETRUSAGE 123 /* to PM, VFS */

View File

@ -352,9 +352,10 @@
# define SYS_STATECTL (KERNEL_CALL + 55) /* sys_statectl() */ # define SYS_STATECTL (KERNEL_CALL + 55) /* sys_statectl() */
# define SYS_SAFEMEMSET (KERNEL_CALL + 56) /* sys_safememset() */ # define SYS_SAFEMEMSET (KERNEL_CALL + 56) /* sys_safememset() */
# define SYS_GETRUSAGE (KERNEL_CALL + 57) /* sys_getrusage() */
/* Total */ /* Total */
#define NR_SYS_CALLS 57 /* number of kernel calls */ #define NR_SYS_CALLS 58 /* number of kernel calls */
#define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS) #define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS)
@ -1078,8 +1079,10 @@
#define VM_VFS_MMAP (VM_RQ_BASE+46) #define VM_VFS_MMAP (VM_RQ_BASE+46)
#define VM_GETRUSAGE (VM_RQ_BASE+47)
/* Total. */ /* Total. */
#define NR_VM_CALLS 47 #define NR_VM_CALLS 48
#define VM_CALL_MASK_SIZE BITMAP_CHUNKS(NR_VM_CALLS) #define VM_CALL_MASK_SIZE BITMAP_CHUNKS(NR_VM_CALLS)
/* not handled as a normal VM call, thus at the end of the reserved rage */ /* not handled as a normal VM call, thus at the end of the reserved rage */
@ -1294,4 +1297,9 @@
# define BDEV_NOFLAGS 0x00 /* no flags are set */ # define BDEV_NOFLAGS 0x00 /* no flags are set */
# define BDEV_FORCEWRITE 0x01 /* force write to disk immediately */ # define BDEV_FORCEWRITE 0x01 /* force write to disk immediately */
/* Field names for GETRUSAGE related calls */
#define RU_ENDPT m1_i1 /* indicates a process for sys_getrusage */
#define RU_WHO m1_i1 /* who argument in getrusage call */
#define RU_RUSAGE_ADDR m1_p1 /* pointer to struct rusage */
/* _MINIX_COM_H */ /* _MINIX_COM_H */

View File

@ -17,6 +17,7 @@
/* Forward declaration */ /* Forward declaration */
struct reg86u; struct reg86u;
struct rs_pci; struct rs_pci;
struct rusage;
#define SYSTASK SYSTEM #define SYSTASK SYSTEM
@ -249,5 +250,8 @@ int sys_setmcontext(endpoint_t proc, mcontext_t *mcp);
/* input */ /* input */
int tty_input_inject(int type, int code, int val); int tty_input_inject(int type, int code, int val);
/* resource */
int sys_getrusage(endpoint_t proc, struct rusage *r_usage);
#endif /* _SYSLIB_H */ #endif /* _SYSLIB_H */

View File

@ -263,6 +263,8 @@ void system_init(void)
map(SYS_SCHEDULE, do_schedule); /* reschedule a process */ map(SYS_SCHEDULE, do_schedule); /* reschedule a process */
map(SYS_SCHEDCTL, do_schedctl); /* change process scheduler */ map(SYS_SCHEDCTL, do_schedctl); /* change process scheduler */
/* getrusage */
map(SYS_GETRUSAGE, do_getrusage); /* getrusage */
} }
/*===========================================================================* /*===========================================================================*
* get_priv * * get_priv *

View File

@ -208,5 +208,7 @@ int do_statectl(struct proc * caller, message *m_ptr);
#define do_statectl NULL #define do_statectl NULL
#endif #endif
int do_getrusage(struct proc * caller, message *m_ptr);
#endif /* SYSTEM_H */ #endif /* SYSTEM_H */

View File

@ -38,7 +38,8 @@ SRCS+= \
do_vmctl.c \ do_vmctl.c \
do_schedule.c \ do_schedule.c \
do_schedctl.c \ do_schedctl.c \
do_statectl.c do_statectl.c \
do_getrusage.c
.if ${MACHINE_ARCH} == "i386" .if ${MACHINE_ARCH} == "i386"
SRCS+= \ SRCS+= \

View File

@ -0,0 +1,51 @@
/* The kernel call implemented in this file:
* m_type: SYS_GETRUSAGE
*
* The parameters for this kernel call are:
* m1_i1: RU_ENDPT (process to get rusage)
* m1_p1: RU_RUSAGE_PTR (pointer to struct rusage)
*/
#include "kernel/system.h"
#include "kernel/proc.h"
#include <minix/endpoint.h>
#include <sys/resource.h>
/*===========================================================================*
* do_getrusage *
*===========================================================================*/
int do_getrusage(struct proc * caller, message * msg)
{
struct proc *target = NULL;
int target_slot = 0;
struct rusage r_usage;
u64_t usec;
if (!isokendpt(msg->RU_ENDPT, &target_slot))
return EINVAL;
target = proc_addr(target_slot);
if (isemptyp(target))
return EINVAL;
if (data_copy(msg->m_source, (vir_bytes) msg->RU_RUSAGE_ADDR, KERNEL,
(vir_bytes) &r_usage, (vir_bytes) sizeof(struct rusage)) != OK)
return EFAULT;
usec = target->p_user_time * 1000000 / system_hz;
r_usage.ru_utime.tv_sec = usec / 1000000;
r_usage.ru_utime.tv_usec = usec % 100000;
usec = target->p_sys_time * 1000000 / system_hz;
r_usage.ru_stime.tv_sec = usec / 1000000;
r_usage.ru_stime.tv_usec = usec % 100000;
r_usage.ru_msgsnd = target->p_message_sent;
r_usage.ru_msgrcv = target->p_message_received;
r_usage.ru_nsignals = target->p_signal_received;
r_usage.ru_nvcsw = target->p_voluntary_context_switch;
r_usage.ru_nivcsw = target->p_involuntary_context_switch;
/* Get the mcontext structure into our address space. */
return data_copy(KERNEL, (vir_bytes) &r_usage, msg->m_source,
(vir_bytes) msg->RU_RUSAGE_ADDR,
(vir_bytes) sizeof(struct rusage));
}

View File

@ -18,7 +18,8 @@ SRCS+= accept.c access.c adjtime.c bind.c brk.c sbrk.c m_closefrom.c getsid.c \
sigprocmask.c socket.c socketpair.c stat.c statvfs.c symlink.c \ sigprocmask.c socket.c socketpair.c stat.c statvfs.c symlink.c \
sync.c syscall.c sysuname.c truncate.c umask.c unlink.c write.c \ sync.c syscall.c sysuname.c truncate.c umask.c unlink.c write.c \
utimensat.c utimes.c futimes.c lutimes.c futimens.c \ utimensat.c utimes.c futimes.c lutimes.c futimens.c \
_exit.c _ucontext.c environ.c __getcwd.c vfork.c sizeup.c init.c _exit.c _ucontext.c environ.c __getcwd.c vfork.c sizeup.c init.c \
getrusage.c
# Minix specific syscalls. # Minix specific syscalls.
SRCS+= cprofile.c lseek64.c sprofile.c _mcontext.c SRCS+= cprofile.c lseek64.c sprofile.c _mcontext.c

View File

@ -0,0 +1,23 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <unistd.h>
#include <sys/resource.h>
int getrusage(int who, struct rusage *r_usage)
{
int rc;
message m;
m.RU_WHO = who;
m.RU_RUSAGE_ADDR = r_usage;
memset(r_usage, 0, sizeof(struct rusage));
if ((rc = _syscall(PM_PROC_NR, GETRUSAGE, &m)) < 0)
return rc;
m.m1_p1 = r_usage;
if ((rc = _syscall(VFS_PROC_NR, GETRUSAGE, &m)) < 0)
return rc;
m.m1_p1 = r_usage;
return _syscall(VM_PROC_NR, VM_GETRUSAGE, &m);
}

View File

@ -228,7 +228,7 @@ MAN+= accept.2 access.2 acct.2 bind.2 brk.2 chdir.2 \
flock.2 fork.2 fsync.2 getcontext.2 getdents.2 \ flock.2 fork.2 fsync.2 getcontext.2 getdents.2 \
getfh.2 getvfsstat.2 getgid.2 getgroups.2 \ getfh.2 getvfsstat.2 getgid.2 getgroups.2 \
getitimer.2 getlogin.2 getpeername.2 getpgrp.2 getpid.2 \ getitimer.2 getlogin.2 getpeername.2 getpgrp.2 getpid.2 \
getpriority.2 getrlimit.2 getrusage.2 getsid.2 getsockname.2 \ getpriority.2 getrlimit.2 getsid.2 getsockname.2 \
getsockopt.2 gettimeofday.2 getuid.2 intro.2 ioctl.2 issetugid.2 \ getsockopt.2 gettimeofday.2 getuid.2 intro.2 ioctl.2 issetugid.2 \
kill.2 kqueue.2 ktrace.2 \ kill.2 kqueue.2 ktrace.2 \
lfs_bmapv.2 lfs_markv.2 lfs_segclean.2 lfs_segwait.2 \ lfs_bmapv.2 lfs_markv.2 lfs_segclean.2 lfs_segwait.2 \
@ -244,7 +244,7 @@ MAN+= accept.2 access.2 acct.2 bind.2 brk.2 chdir.2 \
mprotect.2 mremap.2 msgctl.2 msgget.2 msgrcv.2 msgsnd.2 msync.2 \ mprotect.2 mremap.2 msgctl.2 msgget.2 msgrcv.2 msgsnd.2 msync.2 \
munmap.2 nanosleep.2 nfssvc.2 ntp_adjtime.2 open.2 pathconf.2 pipe.2 munmap.2 nanosleep.2 nfssvc.2 ntp_adjtime.2 open.2 pathconf.2 pipe.2
.else .else
MAN+= adjtime.2 clock_settime.2 pipe.2 MAN+= adjtime.2 clock_settime.2 pipe.2 getrusage.2
.endif # !defined(__MINIX) .endif # !defined(__MINIX)
.if !defined(__MINIX) .if !defined(__MINIX)
MAN+= pmc_control.2 poll.2 posix_fadvise.2 profil.2 ptrace.2 __quotactl.2 \ MAN+= pmc_control.2 poll.2 posix_fadvise.2 profil.2 ptrace.2 __quotactl.2 \

View File

@ -88,7 +88,8 @@ SRCS+= \
vm_notify_sig.c \ vm_notify_sig.c \
vm_umap.c \ vm_umap.c \
vm_procctl.c \ vm_procctl.c \
vprintf.c vprintf.c \
sys_getrusage.c
.if ${MKPCI} != "no" .if ${MKPCI} != "no"
SRCS+= pci_attr_r16.c \ SRCS+= pci_attr_r16.c \

View File

@ -0,0 +1,14 @@
#include "syslib.h"
#include <sys/resource.h>
int sys_getrusage(endpoint_t proc, struct rusage *r_usage)
{
/* Fetch the resource usage for a process. */
message m;
int r;
m.RU_ENDPT = proc;
m.RU_RUSAGE_ADDR = r_usage;
r = _kernel_call(SYS_GETRUSAGE, &m);
return(r);
}

View File

@ -4,7 +4,7 @@
PROG= pm PROG= pm
SRCS= main.c forkexit.c break.c exec.c time.c alarm.c \ SRCS= main.c forkexit.c break.c exec.c time.c alarm.c \
signal.c utility.c table.c getset.c misc.c \ signal.c utility.c table.c getset.c misc.c \
profile.c schedule.c profile.c schedule.c getrusage.c
.if ${USE_MCONTEXT} != "no" .if ${USE_MCONTEXT} != "no"
SRCS+= mcontext.c SRCS+= mcontext.c

37
servers/pm/getrusage.c Normal file
View File

@ -0,0 +1,37 @@
#include "pm.h"
#include <sys/resource.h>
#include <minix/callnr.h>
#include <minix/endpoint.h>
#include <minix/syslib.h>
#include "mproc.h"
#include "param.h"
/*===========================================================================*
* do_getrusage *
*===========================================================================*/
int do_getrusage()
{
int res = 0;
clock_t user_time = 0;
clock_t sys_time = 0;
struct rusage r_usage;
u64_t usec;
if ((res = sys_datacopy(who_e, (vir_bytes) m_in.RU_RUSAGE_ADDR, SELF,
(vir_bytes) &r_usage, (vir_bytes) sizeof(r_usage))) < 0)
return res;
if ((res = sys_getrusage(who_e, &r_usage)) < 0)
return res;
if (m_in.RU_WHO == RUSAGE_CHILDREN) {
usec = mp->mp_child_utime * 1000000 / sys_hz();
r_usage.ru_utime.tv_sec = usec / 1000000;
r_usage.ru_utime.tv_usec = usec % 1000000;
usec = mp->mp_child_stime * 1000000 / sys_hz();
r_usage.ru_stime.tv_sec = usec / 1000000;
r_usage.ru_stime.tv_usec = usec % 1000000;
}
return sys_datacopy(SELF, &r_usage, who_e,
(vir_bytes) m_in.RU_RUSAGE_ADDR, (vir_bytes) sizeof(r_usage));
}

View File

@ -106,3 +106,6 @@ struct mproc *find_proc(pid_t lpid);
int nice_to_priority(int nice, unsigned *new_q); int nice_to_priority(int nice, unsigned *new_q);
int pm_isokendpt(int ep, int *proc); int pm_isokendpt(int ep, int *proc);
void tell_vfs(struct mproc *rmp, message *m_ptr); void tell_vfs(struct mproc *rmp, message *m_ptr);
/* getrusage.c */
int do_getrusage(void);

View File

@ -129,6 +129,12 @@ int (*call_vec[])(void) = {
do_gettime, /* 115 = clock_gettime */ do_gettime, /* 115 = clock_gettime */
do_settime, /* 116 = clock_settime */ do_settime, /* 116 = clock_settime */
no_sys, /* 117 = (vmcall) */ no_sys, /* 117 = (vmcall) */
no_sys, /* 118 = unsused */
no_sys, /* 119 = unsused */
no_sys, /* 120 = unsused */
no_sys, /* 121 = (task reply) */
no_sys, /* 122 = (map driver ) */
do_getrusage, /* 123 = getrusage */
}; };
/* This should not fail with "array size is negative": */ /* This should not fail with "array size is negative": */
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1]; extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];

View File

@ -7,7 +7,7 @@ SRCS= main.c open.c read.c write.c pipe.c dmap.c \
filedes.c stadir.c protect.c time.c \ filedes.c stadir.c protect.c time.c \
lock.c misc.c utility.c select.c table.c \ lock.c misc.c utility.c select.c table.c \
vnode.c vmnt.c request.c \ vnode.c vmnt.c request.c \
tll.c comm.c worker.c coredump.c tll.c comm.c worker.c coredump.c getrusage.c
.if ${MKCOVERAGE} != "no" .if ${MKCOVERAGE} != "no"
SRCS+= gcov.c SRCS+= gcov.c

31
servers/vfs/getrusage.c Normal file
View File

@ -0,0 +1,31 @@
/* This file takes care of GETRUSAGE system call
*/
#include "fs.h"
#include "fproc.h"
#include "glo.h"
#include <minix/callnr.h>
#include <minix/com.h>
#include <sys/resource.h>
/*===========================================================================*
* do_getrusage *
*===========================================================================*/
int do_getrusage(message *UNUSED(m_out))
{
int res;
struct rusage r_usage;
if ((res = sys_datacopy(who_e, (vir_bytes) m_in.RU_RUSAGE_ADDR, SELF,
(vir_bytes) &r_usage, (vir_bytes) sizeof(r_usage))) < 0)
return res;
r_usage.ru_inblock = fp->in_blocks;
r_usage.ru_oublock = fp->out_blocks;
r_usage.ru_ixrss = fp->text_size;
r_usage.ru_idrss = fp->data_size;
r_usage.ru_isrss = DEFAULT_STACK_LIMIT;
return sys_datacopy(SELF, (vir_bytes) &r_usage, who_e,
(vir_bytes) m_in.RU_RUSAGE_ADDR, (phys_bytes) sizeof(r_usage));
}

View File

@ -376,4 +376,7 @@ void worker_stop_by_endpt(endpoint_t proc_e);
void worker_wait(void); void worker_wait(void);
void sys_worker_start(void *(*func)(void *arg)); void sys_worker_start(void *(*func)(void *arg));
void dl_worker_start(void *(*func)(void *arg)); void dl_worker_start(void *(*func)(void *arg));
/* getrusage.c */
int do_getrusage(message *m_out);
#endif #endif

View File

@ -133,6 +133,12 @@ int (*call_vec[])(message *m_out) = {
no_sys, /* 115 = (clock_gettime) */ no_sys, /* 115 = (clock_gettime) */
no_sys, /* 116 = (clock_settime) */ no_sys, /* 116 = (clock_settime) */
do_vm_call, /* 117 = call from vm */ do_vm_call, /* 117 = call from vm */
no_sys, /* 118 = unsused */
no_sys, /* 119 = unsused */
no_sys, /* 120 = unsused */
no_sys, /* 121 = (task reply) */
no_sys, /* 122 = (map driver ) */
do_getrusage, /* 123 = getrusage */
}; };
/* This should not fail with "array size is negative": */ /* This should not fail with "array size is negative": */
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1]; extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];

View File

@ -6,7 +6,7 @@ SRCS= main.c alloc.c utility.c exit.c fork.c break.c \
mmap.c slaballoc.c region.c pagefaults.c \ mmap.c slaballoc.c region.c pagefaults.c \
rs.c queryexit.c pb.c regionavl.c \ rs.c queryexit.c pb.c regionavl.c \
mem_anon.c mem_directphys.c mem_anon_contig.c mem_shared.c \ mem_anon.c mem_directphys.c mem_anon_contig.c mem_shared.c \
mem_cache.c cache.c vfs.c mem_file.c fdref.c mem_cache.c cache.c vfs.c mem_file.c fdref.c getrusage.c
.if ${MACHINE_ARCH} == "earm" .if ${MACHINE_ARCH} == "earm"
LDFLAGS+= -T ${.CURDIR}/arch/${MACHINE_ARCH}/vm.lds LDFLAGS+= -T ${.CURDIR}/arch/${MACHINE_ARCH}/vm.lds

29
servers/vm/getrusage.c Normal file
View File

@ -0,0 +1,29 @@
#include <sys/resource.h>
#include "proto.h"
#include "vmproc.h"
#include "glo.h"
/*===========================================================================*
* do_getrusage *
*===========================================================================*/
int do_getrusage(message *m)
{
int res, slot;
struct vmproc *vmp;
struct rusage r_usage;
if ((res = vm_isokendpt(m->m_source, &slot)) != OK)
return ESRCH;
vmp = &vmproc[slot];
if ((res = sys_datacopy(m->m_source, (vir_bytes) m->RU_RUSAGE_ADDR,
SELF, (vir_bytes) &r_usage, (vir_bytes) sizeof(r_usage))) < 0)
return res;
r_usage.ru_maxrss = vmp->vm_total_max;
r_usage.ru_minflt = vmp->vm_minor_page_fault;
r_usage.ru_majflt = vmp->vm_major_page_fault;
return sys_datacopy(SELF, &r_usage, m->m_source,
(vir_bytes) m->RU_RUSAGE_ADDR, (vir_bytes) sizeof(r_usage));
}

View File

@ -443,6 +443,9 @@ void init_vm(void)
CALLMAP(VM_MAPCACHEPAGE, do_mapcache); CALLMAP(VM_MAPCACHEPAGE, do_mapcache);
CALLMAP(VM_SETCACHEPAGE, do_setcache); CALLMAP(VM_SETCACHEPAGE, do_setcache);
/* getrusage */
CALLMAP(VM_GETRUSAGE, do_getrusage);
/* Initialize the structures for queryexit */ /* Initialize the structures for queryexit */
init_query_exit(); init_query_exit();

View File

@ -240,3 +240,6 @@ struct fdref *fdref_dedup_or_new(struct vmproc *owner, ino_t ino, dev_t dev,
void fdref_ref(struct fdref *ref, struct vir_region *region); void fdref_ref(struct fdref *ref, struct vir_region *region);
void fdref_deref(struct vir_region *region); void fdref_deref(struct vir_region *region);
void fdref_sanitycheck(void); void fdref_sanitycheck(void);
/* getrusage.c */
int do_getrusage(message *m);

View File

@ -47,6 +47,34 @@
#define PRIO_PGRP 1 #define PRIO_PGRP 1
#define PRIO_USER 2 #define PRIO_USER 2
/*
* Resource utilization information.
*/
#define RUSAGE_SELF 0
#define RUSAGE_CHILDREN -1
struct rusage {
struct timeval ru_utime; /* user time used */
struct timeval ru_stime; /* system time used */
long ru_maxrss; /* max resident set size */
#define ru_first ru_ixrss
long ru_ixrss; /* integral shared memory size */
long ru_idrss; /* integral unshared data " */
long ru_isrss; /* integral unshared stack " */
long ru_minflt; /* page reclaims */
long ru_majflt; /* page faults */
long ru_nswap; /* swaps */
long ru_inblock; /* block input operations */
long ru_oublock; /* block output operations */
long ru_msgsnd; /* messages sent */
long ru_msgrcv; /* messages received */
long ru_nsignals; /* signals received */
long ru_nvcsw; /* voluntary context switches */
long ru_nivcsw; /* involuntary " */
#define ru_last ru_nivcsw
};
/* /*
* Resource limits * Resource limits
*/ */
@ -78,6 +106,7 @@ struct rlimit
__BEGIN_DECLS __BEGIN_DECLS
int getpriority(int, int); int getpriority(int, int);
int getrlimit(int, struct rlimit *); int getrlimit(int, struct rlimit *);
int getrusage(int, struct rusage *);
int setpriority(int, int, int); int setpriority(int, int, int);
__END_DECLS __END_DECLS