From d477a9ed82e20358a702cc3bcc093018264d1364 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Thu, 4 Aug 2011 23:52:03 +0000 Subject: [PATCH] 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 --- commands/service/service.c | 1 + common/include/minix/com.h | 5 ++++- common/include/minix/vm.h | 3 ++- etc/system.conf | 19 ------------------- lib/libc/other/_vm_query_exit.c | 11 +++++++++++ servers/ipc/Makefile | 3 +++ servers/ipc/ipc.conf | 19 +++++++++++++++++++ servers/ipc/main.c | 8 ++++++++ servers/vm/main.c | 1 + servers/vm/proto.h | 1 + servers/vm/queryexit.c | 28 ++++++++++++++++++++++++++-- servers/vm/vmproc.h | 1 + 12 files changed, 77 insertions(+), 23 deletions(-) create mode 100644 servers/ipc/ipc.conf diff --git a/commands/service/service.c b/commands/service/service.c index 0eab47002..68314c8f6 100644 --- a/commands/service/service.c +++ b/commands/service/service.c @@ -1074,6 +1074,7 @@ struct { "GETREF", VM_GETREF }, { "RS_SET_PRIV", VM_RS_SET_PRIV }, { "QUERY_EXIT", VM_QUERY_EXIT }, + { "WATCH_EXIT", VM_WATCH_EXIT }, { "NOTIFY_SIG", VM_NOTIFY_SIG }, { "INFO", VM_INFO }, { "RS_UPDATE", VM_RS_UPDATE }, diff --git a/common/include/minix/com.h b/common/include/minix/com.h index 342bd0ba1..25ee69a56 100644 --- a/common/include/minix/com.h +++ b/common/include/minix/com.h @@ -1071,8 +1071,11 @@ # define VM_RS_MEM_PIN 0 /* pin memory */ # 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. */ -#define NR_VM_CALLS 43 +#define NR_VM_CALLS 44 #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 */ diff --git a/common/include/minix/vm.h b/common/include/minix/vm.h index 63bc35925..6ce0d5c7e 100644 --- a/common/include/minix/vm.h +++ b/common/include/minix/vm.h @@ -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_update, (endpoint_t src_e, endpoint_t dst_e)); _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( void vm_forgetblocks, (void)); _PROTOTYPE( int vm_yield_block_get_block, (u64_t yieldid, u64_t getid, diff --git a/etc/system.conf b/etc/system.conf index d620d0873..655fe2739 100644 --- a/etc/system.conf +++ b/etc/system.conf @@ -520,25 +520,6 @@ service amddev 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 { system diff --git a/lib/libc/other/_vm_query_exit.c b/lib/libc/other/_vm_query_exit.c index c6e85f17c..6d07617ef 100644 --- a/lib/libc/other/_vm_query_exit.c +++ b/lib/libc/other/_vm_query_exit.c @@ -22,3 +22,14 @@ PUBLIC int vm_query_exit(int *endpt) *endpt = m.VM_QUERY_RET_PT; 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); +} + diff --git a/servers/ipc/Makefile b/servers/ipc/Makefile index 89225c7d2..ccda5f1ca 100644 --- a/servers/ipc/Makefile +++ b/servers/ipc/Makefile @@ -8,5 +8,8 @@ LDADD+= -lsys MAN= BINDIR?= /usr/sbin +FILES=ipc.conf +FILESNAME=ipc +FILESDIR= /etc/system.conf.d .include diff --git a/servers/ipc/ipc.conf b/servers/ipc/ipc.conf new file mode 100644 index 000000000..a4cc015fc --- /dev/null +++ b/servers/ipc/ipc.conf @@ -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 + ; +}; diff --git a/servers/ipc/main.c b/servers/ipc/main.c index 05a72c160..76928ca91 100644 --- a/servers/ipc/main.c +++ b/servers/ipc/main.c @@ -64,6 +64,14 @@ PUBLIC int main(int argc, char *argv[]) /* dispatch messages */ 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) { int result; diff --git a/servers/vm/main.c b/servers/vm/main.c index 925eb8628..576522319 100644 --- a/servers/vm/main.c +++ b/servers/vm/main.c @@ -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_INFO, do_info); CALLMAP(VM_QUERY_EXIT, do_query_exit); + CALLMAP(VM_WATCH_EXIT, do_watch_exit); CALLMAP(VM_FORGETBLOCKS, do_forgetblocks); CALLMAP(VM_FORGETBLOCK, do_forgetblock); CALLMAP(VM_YIELDBLOCKGETBLOCK, do_yieldblockgetblock); diff --git a/servers/vm/proto.h b/servers/vm/proto.h index 813906ec0..506e59d78 100644 --- a/servers/vm/proto.h +++ b/servers/vm/proto.h @@ -207,5 +207,6 @@ _PROTOTYPE(int do_rs_memctl, (message *m)); /* queryexit.c */ _PROTOTYPE(int do_query_exit, (message *m)); +_PROTOTYPE(int do_watch_exit, (message *m)); _PROTOTYPE(int do_notify_sig, (message *m)); _PROTOTYPE(void init_query_exit, (void)); diff --git a/servers/vm/queryexit.c b/servers/vm/queryexit.c index d5ae12491..3774c7936 100644 --- a/servers/vm/queryexit.c +++ b/servers/vm/queryexit.c @@ -67,10 +67,19 @@ PUBLIC int do_query_exit(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 ipc_ep = m->VM_NOTIFY_SIG_IPC; 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++) { /* its signal is already here */ @@ -80,7 +89,7 @@ PUBLIC int do_notify_sig(message *m) avails++; } if (!avails) { - /* no slot for signals, impossible */ + /* no slot for signals, unlikely */ printf("VM: no slot for signals!\n"); return ENOMEM; } @@ -106,6 +115,21 @@ out: 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 * *===========================================================================*/ diff --git a/servers/vm/vmproc.h b/servers/vm/vmproc.h index 0b7956bb7..8dd0ed62e 100644 --- a/servers/vm/vmproc.h +++ b/servers/vm/vmproc.h @@ -65,5 +65,6 @@ struct vmproc { #define VMF_HAS_DMA 0x010 /* Process directly or indirectly granted * DMA buffers. */ +#define VMF_WATCHEXIT 0x020 /* Store in queryexit table */ #endif -- 2.44.0