vm/ipc: only report signals when it matters to ipc

. ipc wants to know about processes that get
	  signals, so that it can break blocking ipc operations
	. doing it for every single signal is wasteful
	  and causes the annoying 'no slot for signals' message
	. this fix tells vm on a per-process basis it (ipc)
	  wants to be notified, i.e. only when it does any ipc calls
	. move ipc config to separate config file while we're at it
This commit is contained in:
Ben Gras 2011-08-04 23:52:03 +00:00
parent 862fb8354d
commit d477a9ed82
12 changed files with 77 additions and 23 deletions

View File

@ -1074,6 +1074,7 @@ struct
{ "GETREF", VM_GETREF }, { "GETREF", VM_GETREF },
{ "RS_SET_PRIV", VM_RS_SET_PRIV }, { "RS_SET_PRIV", VM_RS_SET_PRIV },
{ "QUERY_EXIT", VM_QUERY_EXIT }, { "QUERY_EXIT", VM_QUERY_EXIT },
{ "WATCH_EXIT", VM_WATCH_EXIT },
{ "NOTIFY_SIG", VM_NOTIFY_SIG }, { "NOTIFY_SIG", VM_NOTIFY_SIG },
{ "INFO", VM_INFO }, { "INFO", VM_INFO },
{ "RS_UPDATE", VM_RS_UPDATE }, { "RS_UPDATE", VM_RS_UPDATE },

View File

@ -1071,8 +1071,11 @@
# define VM_RS_MEM_PIN 0 /* pin memory */ # define VM_RS_MEM_PIN 0 /* pin memory */
# define VM_RS_MEM_MAKE_VM 1 /* make VM instance */ # define VM_RS_MEM_MAKE_VM 1 /* make VM instance */
#define VM_WATCH_EXIT (VM_RQ_BASE+43)
# define VM_WE_EP m1_i1
/* Total. */ /* Total. */
#define NR_VM_CALLS 43 #define NR_VM_CALLS 44
#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 */

View File

@ -26,7 +26,8 @@ _PROTOTYPE( int vm_notify_sig, (endpoint_t ep, endpoint_t ipc_ep));
_PROTOTYPE( int vm_set_priv, (int procnr, void *buf)); _PROTOTYPE( int vm_set_priv, (int procnr, void *buf));
_PROTOTYPE( int vm_update, (endpoint_t src_e, endpoint_t dst_e)); _PROTOTYPE( int vm_update, (endpoint_t src_e, endpoint_t dst_e));
_PROTOTYPE( int vm_memctl, (endpoint_t ep, int req)); _PROTOTYPE( int vm_memctl, (endpoint_t ep, int req));
_PROTOTYPE( int vm_query_exit, (int *endpt)); _PROTOTYPE( int vm_query_exit, (endpoint_t *endpt));
_PROTOTYPE( int vm_watch_exit, (endpoint_t ep));
_PROTOTYPE( int vm_forgetblock, (u64_t id)); _PROTOTYPE( int vm_forgetblock, (u64_t id));
_PROTOTYPE( void vm_forgetblocks, (void)); _PROTOTYPE( void vm_forgetblocks, (void));
_PROTOTYPE( int vm_yield_block_get_block, (u64_t yieldid, u64_t getid, _PROTOTYPE( int vm_yield_block_get_block, (u64_t yieldid, u64_t getid,

View File

@ -520,25 +520,6 @@ service amddev
uid 0; uid 0;
}; };
service ipc
{
system
UMAP # 14
VIRCOPY # 15
;
uid 0;
ipc
SYSTEM USER pm rs log tty ds vm
;
vm
REMAP
SHM_UNMAP
GETPHYS
GETREF
QUERY_EXIT
;
};
service osscore service osscore
{ {
system system

View File

@ -22,3 +22,14 @@ PUBLIC int vm_query_exit(int *endpt)
*endpt = m.VM_QUERY_RET_PT; *endpt = m.VM_QUERY_RET_PT;
return (m.VM_QUERY_IS_MORE ? 1 : 0); return (m.VM_QUERY_IS_MORE ? 1 : 0);
} }
PUBLIC int vm_watch_exit(endpoint_t ep)
{
message m;
int r;
memset(&m, 0, sizeof(m));
m.VM_WE_EP = ep;
return _syscall(VM_PROC_NR, VM_WATCH_EXIT, &m);
}

View File

@ -8,5 +8,8 @@ LDADD+= -lsys
MAN= MAN=
BINDIR?= /usr/sbin BINDIR?= /usr/sbin
FILES=ipc.conf
FILESNAME=ipc
FILESDIR= /etc/system.conf.d
.include <minix.service.mk> .include <minix.service.mk>

19
servers/ipc/ipc.conf Normal file
View File

@ -0,0 +1,19 @@
service ipc
{
system
UMAP # 14
VIRCOPY # 15
;
uid 0;
ipc
SYSTEM USER pm rs log tty ds vm
;
vm
REMAP
SHM_UNMAP
GETPHYS
GETREF
QUERY_EXIT
WATCH_EXIT
;
};

View File

@ -64,6 +64,14 @@ PUBLIC int main(int argc, char *argv[])
/* dispatch messages */ /* dispatch messages */
for (i = 0; i < SIZE(ipc_calls); i++) { for (i = 0; i < SIZE(ipc_calls); i++) {
/* If any process does an IPC call,
* we have to know about it exiting.
* Tell VM to watch it for us.
*/
if(vm_watch_exit(m.m_source) != OK) {
printf("IPC: watch failed on %d\n", m.m_source);
}
if (ipc_calls[i].type == call_type) { if (ipc_calls[i].type == call_type) {
int result; int result;

View File

@ -365,6 +365,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
CALLMAP(VM_GETREF, do_get_refcount); CALLMAP(VM_GETREF, do_get_refcount);
CALLMAP(VM_INFO, do_info); CALLMAP(VM_INFO, do_info);
CALLMAP(VM_QUERY_EXIT, do_query_exit); CALLMAP(VM_QUERY_EXIT, do_query_exit);
CALLMAP(VM_WATCH_EXIT, do_watch_exit);
CALLMAP(VM_FORGETBLOCKS, do_forgetblocks); CALLMAP(VM_FORGETBLOCKS, do_forgetblocks);
CALLMAP(VM_FORGETBLOCK, do_forgetblock); CALLMAP(VM_FORGETBLOCK, do_forgetblock);
CALLMAP(VM_YIELDBLOCKGETBLOCK, do_yieldblockgetblock); CALLMAP(VM_YIELDBLOCKGETBLOCK, do_yieldblockgetblock);

View File

@ -207,5 +207,6 @@ _PROTOTYPE(int do_rs_memctl, (message *m));
/* queryexit.c */ /* queryexit.c */
_PROTOTYPE(int do_query_exit, (message *m)); _PROTOTYPE(int do_query_exit, (message *m));
_PROTOTYPE(int do_watch_exit, (message *m));
_PROTOTYPE(int do_notify_sig, (message *m)); _PROTOTYPE(int do_notify_sig, (message *m));
_PROTOTYPE(void init_query_exit, (void)); _PROTOTYPE(void init_query_exit, (void));

View File

@ -67,10 +67,19 @@ PUBLIC int do_query_exit(message *m)
*===========================================================================*/ *===========================================================================*/
PUBLIC int do_notify_sig(message *m) PUBLIC int do_notify_sig(message *m)
{ {
int i, avails = 0; int i, avails = 0, p;
endpoint_t ep = m->VM_NOTIFY_SIG_ENDPOINT; endpoint_t ep = m->VM_NOTIFY_SIG_ENDPOINT;
endpoint_t ipc_ep = m->VM_NOTIFY_SIG_IPC; endpoint_t ipc_ep = m->VM_NOTIFY_SIG_IPC;
int r; int r;
struct vmproc *vmp;
int pslot;
if(vm_isokendpt(ep, &pslot) != OK) return ESRCH;
vmp = &vmproc[pslot];
/* Only record the event if we've been asked to report it. */
if(!(vmp->vm_flags & VMF_WATCHEXIT))
return OK;
for (i = 0; i < NR_PROCS; i++) { for (i = 0; i < NR_PROCS; i++) {
/* its signal is already here */ /* its signal is already here */
@ -80,7 +89,7 @@ PUBLIC int do_notify_sig(message *m)
avails++; avails++;
} }
if (!avails) { if (!avails) {
/* no slot for signals, impossible */ /* no slot for signals, unlikely */
printf("VM: no slot for signals!\n"); printf("VM: no slot for signals!\n");
return ENOMEM; return ENOMEM;
} }
@ -106,6 +115,21 @@ out:
return OK; return OK;
} }
/*===========================================================================*
* do_watch_exit *
*===========================================================================*/
PUBLIC int do_watch_exit(message *m)
{
endpoint_t e = m->VM_WE_EP;
struct vmproc *vmp;
int p;
if(vm_isokendpt(e, &p) != OK) return ESRCH;
vmp = &vmproc[p];
vmp->vm_flags |= VMF_WATCHEXIT;
return OK;
}
/*===========================================================================* /*===========================================================================*
* init_query_exit * * init_query_exit *
*===========================================================================*/ *===========================================================================*/

View File

@ -65,5 +65,6 @@ struct vmproc {
#define VMF_HAS_DMA 0x010 /* Process directly or indirectly granted #define VMF_HAS_DMA 0x010 /* Process directly or indirectly granted
* DMA buffers. * DMA buffers.
*/ */
#define VMF_WATCHEXIT 0x020 /* Store in queryexit table */
#endif #endif