Keep track of various statistics related to IPC and SYSTEM.

This commit is contained in:
Philip Homburg 2008-02-22 12:36:46 +00:00
parent 5996d1de58
commit 992edfd558
2 changed files with 90 additions and 18 deletions

View file

@ -41,6 +41,32 @@ EXTERN irq_hook_t irq_hooks[NR_IRQ_HOOKS]; /* hooks for general use */
EXTERN int irq_actids[NR_IRQ_VECTORS]; /* IRQ ID bits active */ EXTERN int irq_actids[NR_IRQ_VECTORS]; /* IRQ ID bits active */
EXTERN int irq_use; /* map of all in-use irq's */ EXTERN int irq_use; /* map of all in-use irq's */
EXTERN struct ipc_stats
{
unsigned long deadproc;
unsigned long bad_endpoint;
unsigned long dst_not_allowed;
unsigned long bad_call;
unsigned long call_not_allowed;
unsigned long bad_buffer;
unsigned long deadlock;
unsigned long not_ready;
unsigned long src_died;
unsigned long dst_died;
unsigned long no_priv;
unsigned long bad_size;
unsigned long bad_senda;
u64_t total;
} ipc_stats;
extern endpoint_t ipc_stats_target;
EXTERN struct system_stats
{
unsigned long bad_req;
unsigned long not_allowed;
u64_t total;
} sys_stats;
/* Miscellaneous. */ /* Miscellaneous. */
EXTERN reg_t mon_ss, mon_sp; /* boot monitor stack */ EXTERN reg_t mon_ss, mon_sp; /* boot monitor stack */
EXTERN int mon_return; /* true if we can return to monitor */ EXTERN int mon_return; /* true if we can return to monitor */

View file

@ -45,6 +45,7 @@
#include <stddef.h> #include <stddef.h>
#include <signal.h> #include <signal.h>
#include <minix/portio.h> #include <minix/portio.h>
#include <minix/u64.h>
/* Scheduling and message passing functions. The functions are available to /* Scheduling and message passing functions. The functions are available to
* other parts of the kernel through lock_...(). The lock temporarily disables * other parts of the kernel through lock_...(). The lock temporarily disables
@ -106,10 +107,15 @@ long bit_map; /* notification event set or flags */
int src_dst_p; /* Process slot number */ int src_dst_p; /* Process slot number */
vir_clicks vlo, vhi; /* virtual clicks containing message to send */ vir_clicks vlo, vhi; /* virtual clicks containing message to send */
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.total= add64u(ipc_stats.total, 1);
#if 1 #if 1
if (RTS_ISSET(caller_ptr, SLOT_FREE)) if (RTS_ISSET(caller_ptr, SLOT_FREE))
{ {
kprintf("called by the dead?!?\n"); kprintf("called by the dead?!?\n");
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.deadproc++;
return EINVAL; return EINVAL;
} }
#endif #endif
@ -134,6 +140,8 @@ long bit_map; /* notification event set or flags */
kprintf("sys_call: trap %d by %d with bad endpoint %d\n", kprintf("sys_call: trap %d by %d with bad endpoint %d\n",
call_nr, proc_nr(caller_ptr), src_dst_e); call_nr, proc_nr(caller_ptr), src_dst_e);
#endif #endif
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.bad_endpoint++;
return EINVAL; return EINVAL;
} }
src_dst_p = src_dst_e; src_dst_p = src_dst_e;
@ -147,6 +155,8 @@ if (src_dst_e == 0) panic("sys_call: no PM", NO_NUM);
kprintf("sys_call: trap %d by %d with bad endpoint %d\n", kprintf("sys_call: trap %d by %d with bad endpoint %d\n",
call_nr, proc_nr(caller_ptr), src_dst_e); call_nr, proc_nr(caller_ptr), src_dst_e);
#endif #endif
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.bad_endpoint++;
return EDEADSRCDST; return EDEADSRCDST;
} }
@ -160,9 +170,12 @@ if (src_dst_e == 0) panic("sys_call: no PM", NO_NUM);
nr_to_id(src_dst_p))) { nr_to_id(src_dst_p))) {
#if DEBUG_ENABLE_IPC_WARNINGS #if DEBUG_ENABLE_IPC_WARNINGS
kprintf( kprintf(
"sys_call: ipc sendrec mask denied trap %d from %d to %d\n", "sys_call: ipc sendrec mask denied trap %d from %d ('%s') to %d\n",
call_nr, proc_nr(caller_ptr), src_dst_p); call_nr, proc_nr(caller_ptr),
caller_ptr->p_name, src_dst_p);
#endif #endif
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.dst_not_allowed++;
return(ECALLDENIED); /* call denied by ipc mask */ return(ECALLDENIED); /* call denied by ipc mask */
} }
} }
@ -175,6 +188,8 @@ if (src_dst_e == 0) panic("sys_call: no PM", NO_NUM);
"sys_call: ipc mask denied trap %d from %d to %d\n", "sys_call: ipc mask denied trap %d from %d to %d\n",
call_nr, proc_nr(caller_ptr), src_dst_p); call_nr, proc_nr(caller_ptr), src_dst_p);
#endif #endif
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.dst_not_allowed++;
return(ECALLDENIED); /* call denied by ipc mask */ return(ECALLDENIED); /* call denied by ipc mask */
} }
} }
@ -187,7 +202,9 @@ if (src_dst_e == 0) panic("sys_call: no PM", NO_NUM);
kprintf("sys_call: trap %d not allowed, caller %d, src_dst %d\n", kprintf("sys_call: trap %d not allowed, caller %d, src_dst %d\n",
call_nr, proc_nr(caller_ptr), src_dst_p); call_nr, proc_nr(caller_ptr), src_dst_p);
#endif #endif
return(ETRAPDENIED); /* trap denied by mask or kernel */ if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.bad_call++;
return(ETRAPDENIED); /* trap denied by mask or kernel */
} }
/* Check if the process has privileges for the requested call. Calls to the /* Check if the process has privileges for the requested call. Calls to the
@ -199,19 +216,21 @@ if (src_dst_e == 0) panic("sys_call: no PM", NO_NUM);
kprintf("sys_call: trap %d not allowed, caller %d, src_dst %d\n", kprintf("sys_call: trap %d not allowed, caller %d, src_dst %d\n",
call_nr, proc_nr(caller_ptr), src_dst_p); call_nr, proc_nr(caller_ptr), src_dst_p);
#endif #endif
return(ETRAPDENIED); /* trap denied by mask or kernel */ if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.call_not_allowed++;
return(ETRAPDENIED); /* trap denied by mask or kernel */
} }
#if 0
if ((iskerneln(src_dst_p) && _function != SENDREC if ((iskerneln(src_dst_p) && _function != SENDREC
&& _function != RECEIVE)) { && _function != RECEIVE)) {
#if DEBUG_ENABLE_IPC_WARNINGS #if DEBUG_ENABLE_IPC_WARNINGS
kprintf("sys_call: trap %d not allowed, caller %d, src_dst %d\n", kprintf("sys_call: trap %d not allowed, caller %d, src_dst %d\n",
function, proc_nr(caller_ptr), src_dst); function, proc_nr(caller_ptr), src_dst);
#endif #endif
return(ETRAPDENIED); /* trap denied by mask or kernel */ if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.call_not_allowed++;
return(ETRAPDENIED); /* trap denied by mask or kernel */
} }
#endif
/* If the call involves a message buffer, i.e., for SEND, SENDNB, SENDREC, /* If the call involves a message buffer, i.e., for SEND, SENDNB, SENDREC,
* or RECEIVE, check the message pointer. This check allows a message to be * or RECEIVE, check the message pointer. This check allows a message to be
@ -230,6 +249,8 @@ if (src_dst_e == 0) panic("sys_call: no PM", NO_NUM);
"sys_call: invalid message pointer, trap %d, caller %d\n", "sys_call: invalid message pointer, trap %d, caller %d\n",
call_nr, proc_nr(caller_ptr)); call_nr, proc_nr(caller_ptr));
#endif #endif
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.bad_buffer++;
return(EFAULT); /* invalid message pointer */ return(EFAULT); /* invalid message pointer */
} }
} }
@ -241,7 +262,9 @@ if (src_dst_e == 0) panic("sys_call: no PM", NO_NUM);
kprintf("sys_call: trap %d from %d to %d deadlocked, group size %d\n", kprintf("sys_call: trap %d from %d to %d deadlocked, group size %d\n",
call_nr, proc_nr(caller_ptr), src_dst_p, group_size); call_nr, proc_nr(caller_ptr), src_dst_p, group_size);
#endif #endif
return(ELOCKED); if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.deadlock++;
return(ELOCKED);
} }
} }
@ -359,7 +382,12 @@ unsigned flags; /* system call flags */
dst_p = _ENDPOINT_P(dst_e); dst_p = _ENDPOINT_P(dst_e);
dst_ptr = proc_addr(dst_p); dst_ptr = proc_addr(dst_p);
if (RTS_ISSET(dst_ptr, NO_ENDPOINT)) return EDSTDIED; if (RTS_ISSET(dst_ptr, NO_ENDPOINT))
{
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.dst_died++;
return EDSTDIED;
}
/* Check if 'dst' is blocked waiting for this message. The destination's /* Check if 'dst' is blocked waiting for this message. The destination's
* SENDING flag may be set when its SENDREC call blocked while sending. * SENDING flag may be set when its SENDREC call blocked while sending.
@ -383,6 +411,8 @@ unsigned flags; /* system call flags */
*xpp = caller_ptr; /* add caller to end */ *xpp = caller_ptr; /* add caller to end */
caller_ptr->p_q_link = NIL_PROC; /* mark new end of list */ caller_ptr->p_q_link = NIL_PROC; /* mark new end of list */
} else { } else {
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.not_ready++;
return(ENOTREADY); return(ENOTREADY);
} }
return(OK); return(OK);
@ -413,7 +443,12 @@ unsigned flags; /* system call flags */
else else
{ {
okendpt(src_e, &src_p); okendpt(src_e, &src_p);
if (RTS_ISSET(proc_addr(src_p), NO_ENDPOINT)) return ESRCDIED; if (RTS_ISSET(proc_addr(src_p), NO_ENDPOINT))
{
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.src_died++;
return ESRCDIED;
}
} }
@ -458,6 +493,8 @@ unsigned flags; /* system call flags */
if (RTS_ISSET(*xpp, SLOT_FREE)) if (RTS_ISSET(*xpp, SLOT_FREE))
{ {
kprintf("listening to the dead?!?\n"); kprintf("listening to the dead?!?\n");
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.deadproc++;
return EINVAL; return EINVAL;
} }
#endif #endif
@ -499,7 +536,9 @@ unsigned flags; /* system call flags */
RTS_SET(caller_ptr, RECEIVING); RTS_SET(caller_ptr, RECEIVING);
return(OK); return(OK);
} else { } else {
return(ENOTREADY); if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.not_ready++;
return(ENOTREADY);
} }
} }
@ -564,6 +603,8 @@ size_t size;
{ {
kprintf( kprintf(
"mini_senda: warning caller has no privilege structure\n"); "mini_senda: warning caller has no privilege structure\n");
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.no_priv++;
return EPERM; return EPERM;
} }
@ -581,7 +622,11 @@ size_t size;
* times the number of process table entries. * times the number of process table entries.
*/ */
if (size > 16*(NR_TASKS + NR_PROCS)) if (size > 16*(NR_TASKS + NR_PROCS))
{
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.bad_size++;
return EDOM; return EDOM;
}
/* Map table */ /* Map table */
tab_phys= umap_local(caller_ptr, D, (vir_bytes)table, tab_phys= umap_local(caller_ptr, D, (vir_bytes)table,
@ -589,6 +634,8 @@ size_t size;
if (tab_phys == 0) if (tab_phys == 0)
{ {
kprintf("mini_senda: got bad table pointer/size\n"); kprintf("mini_senda: got bad table pointer/size\n");
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.bad_buffer++;
return EFAULT; return EFAULT;
} }
@ -611,6 +658,8 @@ size_t size;
if (flags & ~(AMF_VALID|AMF_DONE|AMF_NOTIFY) || if (flags & ~(AMF_VALID|AMF_DONE|AMF_NOTIFY) ||
!(flags & AMF_VALID)) !(flags & AMF_VALID))
{ {
if (caller_ptr->p_endpoint == ipc_stats_target)
ipc_stats.bad_senda++;
return EINVAL; return EINVAL;
} }
@ -784,6 +833,8 @@ struct proc *dst_ptr;
{ {
kprintf("try_one: got bad table pointer/size\n"); kprintf("try_one: got bad table pointer/size\n");
privp->s_asynsize= 0; privp->s_asynsize= 0;
if (src_ptr->p_endpoint == ipc_stats_target)
ipc_stats.bad_buffer++;
return EFAULT; return EFAULT;
} }
@ -810,6 +861,8 @@ struct proc *dst_ptr;
{ {
kprintf("try_one: bad bits in table\n"); kprintf("try_one: bad bits in table\n");
privp->s_asynsize= 0; privp->s_asynsize= 0;
if (src_ptr->p_endpoint == ipc_stats_target)
ipc_stats.bad_senda++;
return EINVAL; return EINVAL;
} }
@ -831,16 +884,9 @@ struct proc *dst_ptr;
if (tabent.dst != dst_e) if (tabent.dst != dst_e)
{ {
kprintf("try_one: wrong dst %d, looking for %d\n",
tabent.dst, dst_e);
continue; continue;
} }
#if 0
kprintf("try_one: entry[%d]: flags 0x%x dst %d\n",
i, tabent.flags, tabent.dst);
#endif
/* Deliver message */ /* Deliver message */
table_ptr= (asynmsg_t *)privp->s_asyntab; table_ptr= (asynmsg_t *)privp->s_asyntab;
m_ptr= &table_ptr[i].msg; /* Note: pointer in the m_ptr= &table_ptr[i].msg; /* Note: pointer in the