From 7adb15b6dcf5e168299d7b37219522427f73b0c9 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Wed, 12 Dec 2012 21:40:16 +0100 Subject: [PATCH] Remove upc_{control,register} syscalls and everything that has to do with it. It's no longer used for anything. Requested-by: vsrinivas Approved-by: dillon --- Makefile_upgrade.inc | 5 + lib/libc/sys/Makefile.inc | 3 +- lib/libc/sys/upc_register.2 | 415 ------------------------------ sys/conf/files | 1 - sys/cpu/i386/include/cpu.h | 3 - sys/cpu/x86_64/include/cpu.h | 3 - sys/kern/init_sysent.c | 4 +- sys/kern/kern_exec.c | 2 - sys/kern/kern_exit.c | 7 - sys/kern/kern_upcall.c | 301 ---------------------- sys/kern/syscalls.c | 4 +- sys/kern/syscalls.master | 4 +- sys/platform/pc32/i386/genassym.c | 1 - sys/platform/pc32/i386/ipl.s | 2 +- sys/platform/pc32/i386/machdep.c | 153 ----------- sys/platform/pc32/i386/trap.c | 9 +- sys/platform/pc64/x86_64/genassym.c | 1 - sys/platform/pc64/x86_64/ipl.s | 2 +- sys/platform/pc64/x86_64/machdep.c | 153 ----------- sys/platform/pc64/x86_64/trap.c | 6 +- sys/platform/vkernel/i386/cpu_regs.c | 153 ----------- sys/platform/vkernel/i386/genassym.c | 1 - sys/platform/vkernel/i386/trap.c | 9 +- sys/platform/vkernel64/x86_64/cpu_regs.c | 153 ----------- sys/platform/vkernel64/x86_64/trap.c | 9 +- sys/sys/globaldata.h | 6 +- sys/sys/proc.h | 7 +- sys/sys/signalvar.h | 4 - sys/sys/syscall.h | 4 +- sys/sys/syscall.mk | 2 - sys/sys/sysproto.h | 19 -- sys/sys/sysunion.h | 2 - sys/sys/upcall.h | 85 ------ sys/vm/vm_map.c | 8 +- sys/vm/vm_map.h | 20 +-- test/sysperf/Makefile | 8 - test/sysperf/upcall.S | 32 --- test/sysperf/upcall1.c | 65 ----- 38 files changed, 32 insertions(+), 1634 deletions(-) delete mode 100644 lib/libc/sys/upc_register.2 delete mode 100644 sys/kern/kern_upcall.c delete mode 100644 sys/sys/upcall.h delete mode 100644 test/sysperf/upcall.S delete mode 100644 test/sysperf/upcall1.c diff --git a/Makefile_upgrade.inc b/Makefile_upgrade.inc index 5c2b871..0afc2a9 100644 --- a/Makefile_upgrade.inc +++ b/Makefile_upgrade.inc @@ -2093,6 +2093,11 @@ TO_REMOVE+=/usr/share/man/cat8/i386/stlstty.8.gz TO_REMOVE+=/usr/share/man/man8/i386/stlstty.8.gz TO_REMOVE+=/usr/libdata/stallion TO_REMOVE+=/usr/include/bus/isa/isa_compat.h +TO_REMOVE+=/usr/include/sys/upcall.h +TO_REMOVE+=/usr/share/man/cat2/upc_control.2.gz +TO_REMOVE+=/usr/share/man/man2/upc_control.2.gz +TO_REMOVE+=/usr/share/man/cat2/upc_register.2.gz +TO_REMOVE+=/usr/share/man/man2/upc_register.2.gz .if ${MACHINE_ARCH} == "x86_64" TO_REMOVE+=/usr/sbin/stlstats diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 963643b..a3c3158 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -87,7 +87,7 @@ MAN+= _exit.2 accept.2 access.2 acct.2 adjtime.2 \ sigstack.2 sigsuspend.2 socket.2 socketpair.2 stat.2 statfs.2 \ statvfs.2 swapon.2 symlink.2 sync.2 sysarch.2 syscall.2 syslink.2 \ truncate.2 tls.2 umask.2 umtx.2 undelete.2 \ - unlink.2 unlinkat.2 utimes.2 utrace.2 upc_register.2 usched_set.2 \ + unlink.2 unlinkat.2 utimes.2 utrace.2 usched_set.2 \ uuidgen.2 \ varsym.2 vfork.2 vquotactl.2 wait.2 write.2 @@ -171,7 +171,6 @@ MLINKS+=swapon.2 swapoff.2 MLINKS+=tls.2 set_tls_area.2 tls.2 get_tls_area.2 MLINKS+=truncate.2 ftruncate.2 MLINKS+=umtx.2 umtx_sleep.2 umtx.2 umtx_wakeup.2 -MLINKS+=upc_register.2 upc_control.2 MLINKS+=utimes.2 futimes.2 utimes.2 lutimes.2 MLINKS+=varsym.2 varsym_get.2 \ varsym.2 varsym_list.2 \ diff --git a/lib/libc/sys/upc_register.2 b/lib/libc/sys/upc_register.2 deleted file mode 100644 index d56fa31..0000000 --- a/lib/libc/sys/upc_register.2 +++ /dev/null @@ -1,415 +0,0 @@ -.\" Copyright (c) 2003 Matthew Dillon -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $DragonFly: src/lib/libc/sys/upc_register.2,v 1.10 2008/05/02 02:05:04 swildner Exp $ -.\" -.Dd November 20, 2003 -.Dt UPC_REGISTER 2 -.Os -.Sh NAME -.Nm upc_register , -.Nm upc_control -.Nd configure and control upcalls -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/upcall.h -.Ft int -.Fn upc_register "struct upcall *upc" "upcall_func_t ctxfunc" "upcall_func_t cfunc" "void *data" -.Ft int -.Fn upc_control "int command" "int upcall_id" "void *data" -.Sh DESCRIPTION -The -.Fn upc_register -function -registers an upcall. -Note that the specified upcall structural pointer -is per-process, not per-upcall. -It points to a structure in user memory -that both the user and kernel manipulate to deal with upcall/critical-section -interlocks. -.Fa ctxfunc -is a pointer to context save and restore code. -The native upcall interface -does not necessarily save and restore call-used registers. -This function -is typically written in assembly and supplied by -.Em libc . -.Fa cfunc -is a pointer to a C style function and -.Fa data -is the data passed to it as an argument. -A positive upcall identifier -will be returned or -1 if an error occurred. -.Pp -When an upcall is executed the -kernel will add -.Dv TDPRI_CRIT -to the critical section count in the upcall -structure, push a minimal context (not even call-used), and pass the C -function and data pointers to -.Fa ctxfunc -in registers. -.Fa ctxfunc -will then proceed to save appropriate state, call the C function, and -deal with cleanup. -Cleanup typically involves an interlocking operation -and a call to -.Fn upc_control -in order to undo the critical section count and process any additional -pending upcalls atomically. -.Fa ctxfunc -will typically pop most of its state, set upcall->pending to 1, -subtract -.Dv TDPRI_CRIT -from upcall->crit_count, and call -.Fn upc_control "UPC_CONTROL_NEXT" "-1" "stack_pointer" -which atomically handles any further pending upcalls and/or pops the -original stack context supplied to -.Fn upc_control -and resumes the originally interrupted code. -This is all very complex which is why -.Em libc -typically supplies -.Fa ctxfunc . -.Pp -Note that upcalls can only occur if the target process is not in a critical -section. -If an upcall cannot be dispatched it will instead be made pending -and the pending field in the user-supplied upcall structure will be set to -non-zero. -Userland critical-section-exiting code must check the pending -bit and call the appropriate -.Fn upc_control -function to handle any pending upcalls. -.Pp -The upcall identifier space is shared amongst all processes sharing the -same VM space. -That is, all the processes created through -.Fn clone -or -.Fn rfork "RFMEM" . -Through appropriate -.Fn upc_control -calls any process within this domain can generate an upcall on any other -process within this domain, including itself. -Each process typically -installs a different (per-process) upcall data structure. -.Pp -The -.Fn upc_control -function, -is a multi-function system call capable of dispatching upcalls, handling -the context assembly function's interlocks, deleting upcalls, and polling -for upcalls. -.Pp -.Ft int -.Fn upc_control "UPC_CONTROL_DISPATCH" "upcid" "(int)priority" -.Bd -literal -offset indent -Dispatch a particular upcall. -The value -.Li 0 -is returned on success, -.Er ENOENT -if -.Fa upcid -does not exist. -You can dispatch upcalls belonging to your process or -to another process. -You may specify a -.Fa upcid -of -1 to re-dispatch the first upcall owned by your own process that is -pending from a previous operation. -Note that that critical section and -pending rules apply, and an actual dispatch will pushdown the stack. -.Pp -The priority will be compared against the current crit_count to determine -whether the upcall dispatches or is made pending. -.Pp -This command is most often used to alert a target process to a change in -a shared structure, queue, etc. -.Ed -.Pp -.Ft int -.Fn upc_control "UPC_CONTROL_NEXT" "-1" "stack_pointer" -.Bd -literal -offset indent -Do interlocking and stack munging to process additional upcalls. -This -system call should never be made directly by C code because it expects -all registers not saved by the operating system in entering a context -function to have been popped and a pointer to the base of the OS-supplied -stack context on entry to the context routine to be supplied. -This routine -does not return to the caller but instead either regenerates the stack -context for the next pending upcall or it restores the original context, -resuming whomever was interrupted by the original upcall that entered the -context routine. -.Ed -.Pp -.Ft int -.Fn upc_control "UPC_CONTROL_DELETE" "upcid" "NULL" -.Bd -literal -offset indent -Delete the specified -.Fa upcid -or, if -1 is specified, delete all upcall registered by the current process. -If -1 is specified, the upcalls registered by another process will not be -deleted. -If a particular -.Fa upcid -is specified, it will be deleted regardless of which process registered it. -The upcall structural pointer registered with this or any other process is -not effected. -.Ed -.Pp -.Ft int -.Fn upc_control "UPC_CONTROL_POLL" "upcid" "NULL" -.Pp -.Ft int -.Fn upc_control "UPC_CONTROL_POLLANDCLEAR" "upcid" "(int)priority" -.Bd -literal -offset indent -Poll or poll-and-clear the pending status for a particular upcall. -The value -.Li 0 -or -.Li 1 -is returned, or -.Li -1 -if an error occurred (e.g. -.Er ENOENT ). -If a -.Fa upcid -of -1 is specified, locate a pending upcall for the current process and return -it's -.Fa upcid , -or 0 if no upcalls for the current process are pending. -.Pp -The priority will be compared against the upcall's pending priority. -Only -upcalls with greater or equal pending priorities are returned. You must -specify a minimum priority of 1 or this call will simply return a random -registered upcall that may or may not be pending. -.Ed -.Pp -.Bd -literal -offset indent -compact -struct upcall { - int magic; /* must be UPCALL_MAGIC */ - int crit_count; /* critical section count */ - int pending; /* additional upcalls are pending */ -}; -.Ed -.Pp -This is a user space structure a pointer to which is registered with the -kernel via -.Fn upc_register -\. -The -.Fa crit_count -field prevents new upcalls from being dispatched. -When an upcall is -dispatched the kernel automatically adds -.Dv UPC_CRITADD -to -.Fa crit_count -and sets -.Fa pending -to indicate whether any additional upcalls are pending. -A non-zero -.Fa pending -OR -.Fa crit_count -will prevent new upcalls from the being dispatched. -The context function -code is expected to make appropriate checks to dispatch any remaining upcalls -when the current upcall has completed. -In particular, the context function -must subtract -.Va UPC_CRITADD -from -.Fa crit_count -before restoring the original context or calling -.Fn upc_control "UPC_CONTROL_NEXT" "..." -\. -Note that -.Fa pending -may be set as a side effect to various -.Fn upc_control -system calls as well as as a side effect to upcall dispatches. -.Pp -Userland threading code typically uses -.Fa crit_count -to control critical sections within a virtual CPU (i.e., cloned process). -Entering a critical section is as simply as add -.Dv UPC_CRITADD -to -.Fa crit_count . -No atomic or locked instructions are required as this field is accessed -only by the current process and any upcalls or interrupts will restore it -to the condition they found it before returning. -Exiting a critical section -is almost as simple as subtracting -.Dv UPC_CRITADD -from -.Fa crit_count . -The routine which performs this function must also check the -.Fa pending -field once the critical section count has reached 0. -If the pending field -is non-zero, the routine will generally call -.Fn upc_control "UPC_CONTROL_DISPATCH" "-1" "NULL" -to dispatch upcalls which were made pending while you were in the critical -section. -.Sh CONTEXT FUNCTION - IA32 -The context function is called with the stack pointer pointing at a -kernel-constructed stack frame. -Only a minimal number of registers are -saved by the kernel. -.Pp -.Bd -literal -offset indent -compact -frame { - int32_t eax; - int32_t ecx; - int32_t edx; - int32_t eflags; - int32_t origip; -} -.Ed -.Pp -On entry, %eax will hold the C function pointer, %ecx will hold the -C data pointer, and %edx will hold a pointer to the user-supplied upcall -structure. -The context code does not need to push %eax, %ecx, or %edx -because these registers have already been pushed on the stack for it, but -it must generally push any remaining registers that it might use and be -careful in regards to others, such as floating point registers, which -the OS has not saved. -The operating system has already adjusted the -.Fa crit_count -and -.Fa pending -fields in the user-supplied -.Fa upcall -structure, so the context code will generally next push the data pointer -(%ecx) and call the C function through %eax. -Upon return the context code -is responsible for interlocking the upcall return which it does by first -setting -.Fa pending -to 1, then subtracting -.Va UPC_CRITADD -from -.Fa crit_count , -then restoring its part of the context but leaving the OS context intact, -then calling -.Fn upc_control "UPC_CONTROL_NEXT" "-1" "stack_pointer_to_OS_context" -\. -The control function will not return. -It will either restart the context -at the next upcall, if more are pending, or it will restore the original -context. -.Pp -The context code does not have to follow this regime. -There is nothing -preventing the context code from restoring the original frame itself and -returning directly to the originally interrupted user code without having -to make another kernel transition. -It is possible to optimize this by -having the context code subtract down -.Va UPC_CRITADD -as per normal but not pre-set the -.Fa pending -field. If it does this and -.Fa pending -is 0, it is possible for the kernel to initiate another upcall before -the context code has had a chance to pop its stack and restore the original -user context. -This is OK under controlled circumstances. -On the other hand, -if -.Fa pending -is 1 -the context code knows there is another upcall pending and can call -.Fn upc_control -as appropriate. -.Pp -.Bd -literal -offset indent -compact - /* - * upc is a global pointing to this process's upcall structure - * (just as an example). The Os-supplied stack frame is: - * - * [%eax %ecx %edx,%eflags %original_ip] - */ -callused_wrapper: - pushl %edx /* save %edx (upcall pointer) */ - pushl %ecx /* func=%eax(data=%ecx) */ - call *%eax /* call the C function */ - addl $4,%esp - popl %edx /* restore the upcall pointer */ - incl PENDING(%edx) /* setting pending stops upcalls */ - subl $32,CRIT_COUNT(%edx) /* cleanup crit section count */ - pushl %esp /* sp pointing to os user frame */ - pushl $-1 /* upcid */ - pushl $2 /* FETCH next */ - call upc_control - /* not reached */ - /* just for show, restore Os supplied user context */ - popl %eax /* code just for show */ - popl %ecx /* code just for show */ - popl %edx /* code just for show */ - popfl /* code just for show */ - ret /* code just for show */ -.Ed -.Sh ERRORS -The -.Fn upc_register -function -returns: -.Bl -tag -width Er -.It Bq Er EFBIG -if the kernel has reached its upcall registration limit. -The limit is on a -per-shared-vmspace basis and is no less then 32. -Otherwise this function -returns a non-zero, positive number indicating the upcall identifier that -was registered. -.Pp -The -.Fn upc_control -function -returns -.It Bq Er ENOENT -if a particular requested -.Fa upcid -cannot be found. -.El -.Sh SEE ALSO -.Xr rfork 2 , -.Xr clone 3 -.Sh HISTORY -The -.Fn upc_register -and -.Fn upc_control -function calls -appeared in -.Dx 1.0 . diff --git a/sys/conf/files b/sys/conf/files index 3353a30..b71c8bb 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -864,7 +864,6 @@ kern/kern_shutdown.c standard kern/kern_sig.c standard kern/kern_memio.c standard kern/kern_udev.c standard -kern/kern_upcall.c standard kern/kern_sfbuf.c standard kern/kern_subr.c standard kern/kern_iosched.c standard diff --git a/sys/cpu/i386/include/cpu.h b/sys/cpu/i386/include/cpu.h index 761375a..471bb23 100644 --- a/sys/cpu/i386/include/cpu.h +++ b/sys/cpu/i386/include/cpu.h @@ -35,7 +35,6 @@ * * from: @(#)cpu.h 5.4 (Berkeley) 5/9/91 * $FreeBSD: src/sys/i386/include/cpu.h,v 1.43.2.2 2001/06/15 09:37:57 scottl Exp $ - * $DragonFly: src/sys/cpu/i386/include/cpu.h,v 1.25 2007/03/01 01:46:52 corecode Exp $ */ #ifndef _CPU_CPU_H_ @@ -84,8 +83,6 @@ atomic_set_int(&mycpu->gd_reqflags, RQF_IPIQ) #define signotify() \ atomic_set_int(&mycpu->gd_reqflags, RQF_AST_SIGNAL) -#define sigupcall() \ - atomic_set_int(&mycpu->gd_reqflags, RQF_AST_UPCALL) #define clear_user_resched() \ atomic_clear_int(&mycpu->gd_reqflags, RQF_AST_USER_RESCHED) #define clear_lwkt_resched() \ diff --git a/sys/cpu/x86_64/include/cpu.h b/sys/cpu/x86_64/include/cpu.h index 293113f..15ea1dc 100644 --- a/sys/cpu/x86_64/include/cpu.h +++ b/sys/cpu/x86_64/include/cpu.h @@ -35,7 +35,6 @@ * * from: @(#)cpu.h 5.4 (Berkeley) 5/9/91 * $FreeBSD: src/sys/i386/include/cpu.h,v 1.43.2.2 2001/06/15 09:37:57 scottl Exp $ - * $DragonFly: src/sys/cpu/i386/include/cpu.h,v 1.25 2007/03/01 01:46:52 corecode Exp $ */ #ifndef _CPU_CPU_H_ @@ -85,8 +84,6 @@ atomic_set_int(&mycpu->gd_reqflags, RQF_IPIQ) #define signotify() \ atomic_set_int(&mycpu->gd_reqflags, RQF_AST_SIGNAL) -#define sigupcall() \ - atomic_set_int(&mycpu->gd_reqflags, RQF_AST_UPCALL) #define clear_user_resched() \ atomic_clear_int(&mycpu->gd_reqflags, RQF_AST_USER_RESCHED) #define clear_lwkt_resched() \ diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 0e498f6..20563bb 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -487,8 +487,8 @@ struct sysent sysent[] = { { AS(varsym_set_args), (sy_call_t *)sys_varsym_set }, /* 450 = varsym_set */ { AS(varsym_get_args), (sy_call_t *)sys_varsym_get }, /* 451 = varsym_get */ { AS(varsym_list_args), (sy_call_t *)sys_varsym_list }, /* 452 = varsym_list */ - { AS(upc_register_args), (sy_call_t *)sys_upc_register }, /* 453 = upc_register */ - { AS(upc_control_args), (sy_call_t *)sys_upc_control }, /* 454 = upc_control */ + { 0, (sy_call_t *)sys_nosys }, /* 453 = obsolete upc_register */ + { 0, (sy_call_t *)sys_nosys }, /* 454 = obsolete upc_control */ { 0, (sy_call_t *)sys_nosys }, /* 455 = obsolete caps_sys_service */ { 0, (sy_call_t *)sys_nosys }, /* 456 = obsolete caps_sys_client */ { 0, (sy_call_t *)sys_nosys }, /* 457 = obsolete caps_sys_close */ diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 4aa7cb8..bc89cce 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -803,8 +803,6 @@ exec_new_vmspace(struct image_params *imgp, struct vmspace *vmcopy) map = &vmspace->vm_map; } else if (vmspace->vm_sysref.refcnt == 1) { shmexit(vmspace); - if (vmspace->vm_upcalls) - upc_release(vmspace, ONLY_LWP_IN_PROC(imgp->proc)); pmap_remove_pages(vmspace_pmap(vmspace), 0, VM_MAX_USER_ADDRESS); vm_map_remove(map, 0, VM_MAX_USER_ADDRESS); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index a7c8aed..a4d223d 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -63,7 +63,6 @@ #include #include #include -#include #include #include #include @@ -380,12 +379,6 @@ exit1(int rv) vm = p->p_vmspace; /* - * Release upcalls associated with this process - */ - if (vm->vm_upcalls) - upc_release(vm, lp); - - /* * Clean up data related to virtual kernel operation. Clean up * any vkernel context related to the current lwp now so we can * destroy p_vkernel. diff --git a/sys/kern/kern_upcall.c b/sys/kern/kern_upcall.c deleted file mode 100644 index 4bc8eb9..0000000 --- a/sys/kern/kern_upcall.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2003,2004,2006 The DragonFly Project. All rights reserved. - * - * This code is derived from software contributed to The DragonFly Project - * by Matthew Dillon - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of The DragonFly Project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific, prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Implement upcall registration and dispatch. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include - -MALLOC_DEFINE(M_UPCALL, "upcalls", "upcall registration structures"); - -static void -sigupcall_remote(void *arg) -{ - struct lwp *lp = arg; - if (lp == lwkt_preempted_proc()) - sigupcall(); -} - -/* - * upc_register: - * - * Register an upcall context wrapper and procedure. Note that the - * upcall context is set globally for the process, not for each upcall. - * - * ARGS(struct upcall *upc, upcall_func_t ctx, upcall_func_t func, void *data) - * - * MPALMOSTSAFE - */ -int -sys_upc_register(struct upc_register_args *uap) -{ - struct lwp *lp = curthread->td_lwp; - struct vmspace *vm = curproc->p_vmspace; - struct vmupcall *vu; - - /* - * Note: inconsequential MP race - */ - if (vm->vm_upccount >= UPCALL_MAXCOUNT) - return(EFBIG); - - vu = kmalloc(sizeof(struct vmupcall), M_UPCALL, M_WAITOK|M_ZERO); - vu->vu_ctx = uap->ctxfunc; - vu->vu_func = uap->func; - vu->vu_data = uap->data; - vu->vu_lwp = lp; - lp->lwp_upcall = uap->upc; - - get_mplock(); - if (vm->vm_upcalls != NULL) - vu->vu_id = vm->vm_upcalls->vu_id + 1; - else - vu->vu_id = UPC_RESERVED; - vu->vu_next = vm->vm_upcalls; - vm->vm_upcalls = vu; - ++vm->vm_upccount; - rel_mplock(); - uap->sysmsg_result = vu->vu_id; - return(0); -} - -/* - * upc_control: - * - * ARGS(int cmd, int upcid, void *data) - * - * MPALMOSTSAFE - */ -int -sys_upc_control(struct upc_control_args *uap) -{ - struct lwp *lp = curthread->td_lwp; - struct lwp *targlp; - struct vmspace *vms = curproc->p_vmspace; - struct vmupcall *vu; - struct vmupcall *vu_send; - struct vmupcall **vupp; - int error; - - get_mplock(); - switch(uap->cmd) { - case UPC_CONTROL_DISPATCH: - /* - * Dispatch the specified upcall id or the next pending id if -1. - * the upcall will be marked pending but an actual upcall will only - * occur if userland is not in a critical section and the userland - * pending bit is not set. - * - * You can dispatch an upcall associated with your process or another - * process sharing the same VM space. - */ - error = (uap->upcid == -1) ? 0 : ENOENT; - for (vu = vms->vm_upcalls; vu; vu = vu->vu_next) { - if (vu->vu_id == uap->upcid || - (uap->upcid == -1 && - vu->vu_pending >= (int)(intptr_t)uap->data && vu->vu_lwp == lp) - ) { - if (vu->vu_pending < (int)(intptr_t)uap->data) - vu->vu_pending = (int)(intptr_t)uap->data; - error = 0; - targlp = vu->vu_lwp; - targlp->lwp_proc->p_flags |= P_UPCALLPEND; /* XXX lwp flags */ - if (targlp->lwp_proc->p_flags & P_UPCALLWAIT) - wakeup(&targlp->lwp_upcall); - if (targlp->lwp_thread->td_gd != mycpu) - lwkt_send_ipiq(targlp->lwp_thread->td_gd, sigupcall_remote, targlp); - else - sigupcall(); - break; - } - } - break; - case UPC_CONTROL_NEXT: - /* - * This is used by the context code to fetch the next pending upcall. - * The context code has two choices: (A) it can drop - * upcall->crit_count and set upcall->pending then make this call - * unconditionally or * (B) it can drop upcall->crit_count and then - * test upcall->pending and only make this call if upcall->pending - * is set. If upcall->pending is clear the context code can pop - * the upcall stack itself and return without entering into the kernel - * again. (B) is more efficient but leaves a small window of - * opportunity where multiple upcalls can pushdown the stack. - * - * If another upcall is pending the crit_count will be bumped and - * the function, data, and context pointers will be returned in - * registers (C cannot call this routine). If no more upcalls are - * pending the pending bit will be cleared and the 'data' argument - * is expected to be pointing at the upcall context which we will - * then pop, returning to the original code that was interrupted - * (NOT the context code). - */ - vu_send = NULL; - for (vu = vms->vm_upcalls; vu; vu = vu->vu_next) { - if (vu->vu_lwp == lp && vu->vu_pending) { - if (vu_send) - break; - vu_send = vu; - } - } - /* - * vu_send may be NULL, indicating that no more upcalls are pending - * for this cpu. We set the userland pending bit based on whether - * additional upcalls are pending or not. - */ - error = fetchupcall(vu_send, vu != NULL, uap->data); - break; - case UPC_CONTROL_DELETE: - /* - * Delete the specified upcall id. If the upcall id is -1, delete - * all upcall id's associated with the current process. - */ - error = (uap->upcid == -1) ? 0 : ENOENT; - vupp = &vms->vm_upcalls; - while ((vu = *vupp) != NULL) { - if (vu->vu_id == uap->upcid || - (uap->upcid == -1 && vu->vu_lwp == lp) - ) { - *vupp = vu->vu_next; - error = 0; - kfree(vu, M_UPCALL); - } else { - vupp = &vu->vu_next; - } - } - break; - case UPC_CONTROL_POLL: - case UPC_CONTROL_POLLANDCLEAR: - case UPC_CONTROL_WAIT: - /* - * If upcid is -1 poll for the first pending upcall and return the - * id or 0 if no upcalls are pending. - * - * If upcid is a particular upcall then poll that upcall and return - * its pending status (0 or 1). For POLLANDCLEAR, also clear the - * pending status. The userland pending bit is not modified by - * this call (maybe we should modify it for poll-and-clear). - */ - error = (uap->upcid == -1) ? 0 : ENOENT; - for (vu = vms->vm_upcalls; vu; vu = vu->vu_next) { - if (vu->vu_id == uap->upcid || - (uap->upcid == -1 && - vu->vu_pending >= (int)(intptr_t)uap->data && vu->vu_lwp == lp) - ) { - error = 0; - if (uap->upcid == -1) - uap->sysmsg_result = vu->vu_id; - else - uap->sysmsg_result = vu->vu_pending; - if (uap->cmd == UPC_CONTROL_POLLANDCLEAR) - vu->vu_pending = 0; - break; - } - } - if (uap->cmd == UPC_CONTROL_WAIT && vu == NULL) { - lp->lwp_proc->p_flags |= P_UPCALLWAIT; /* XXX lwp flags */ - tsleep(&lp->lwp_upcall, PCATCH, "wupcall", 0); - lp->lwp_proc->p_flags &= ~P_UPCALLWAIT; /* XXX lwp flags */ - } - break; - default: - error = EINVAL; - break; - } - rel_mplock(); - return(error); -} - -void -upc_release(struct vmspace *vm, struct lwp *lp) -{ - struct vmupcall **vupp; - struct vmupcall *vu; - - vupp = &vm->vm_upcalls; - while ((vu = *vupp) != NULL) { - if (vu->vu_lwp == lp) { - *vupp = vu->vu_next; - kfree(vu, M_UPCALL); - --vm->vm_upccount; - } else { - vupp = &vu->vu_next; - } - } -} - -/* - * XXX eventually we should sort by vu_pending priority and dispatch - * the highest priority upcall first. - */ -void -postupcall(struct lwp *lp) -{ - struct vmspace *vm = lp->lwp_proc->p_vmspace; - struct vmupcall *vu; - struct vmupcall *vu_send = NULL; - - for (vu = vm->vm_upcalls; vu; vu = vu->vu_next) { - if (vu->vu_lwp == lp && vu->vu_pending) { - if (vu_send) { - sendupcall(vu, 1); - return; - } - vu_send = vu; - } - } - if (vu_send) - sendupcall(vu_send, 0); -} - diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 9b1fb87..54822a4 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -461,8 +461,8 @@ const char *syscallnames[] = { "varsym_set", /* 450 = varsym_set */ "varsym_get", /* 451 = varsym_get */ "varsym_list", /* 452 = varsym_list */ - "upc_register", /* 453 = upc_register */ - "upc_control", /* 454 = upc_control */ + "obs_upc_register", /* 453 = obsolete upc_register */ + "obs_upc_control", /* 454 = obsolete upc_control */ "obs_caps_sys_service", /* 455 = obsolete caps_sys_service */ "obs_caps_sys_client", /* 456 = obsolete caps_sys_client */ "obs_caps_sys_close", /* 457 = obsolete caps_sys_close */ diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 9093fbe..da238e2 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -629,8 +629,8 @@ 450 STD BSD { int varsym_set(int level, const char *name, const char *data); } 451 STD BSD { int varsym_get(int mask, const char *wild, char *buf, int bufsize); } 452 STD BSD { int varsym_list(int level, char *buf, int maxsize, int *marker); } -453 STD BSD { int upc_register(struct upcall *upc, void *ctxfunc, void *func, void *data); } -454 STD BSD { int upc_control(int cmd, int upcid, void *data); } +453 OBSOL BSD upc_register +454 OBSOL BSD upc_control 455 OBSOL BSD caps_sys_service 456 OBSOL BSD caps_sys_client 457 OBSOL BSD caps_sys_close diff --git a/sys/platform/pc32/i386/genassym.c b/sys/platform/pc32/i386/genassym.c index bdeb6a5..10336f9 100644 --- a/sys/platform/pc32/i386/genassym.c +++ b/sys/platform/pc32/i386/genassym.c @@ -192,7 +192,6 @@ ASSYM(RQF_AST_OWEUPC, RQF_AST_OWEUPC); ASSYM(RQF_AST_SIGNAL, RQF_AST_SIGNAL); ASSYM(RQF_AST_USER_RESCHED, RQF_AST_USER_RESCHED); ASSYM(RQF_AST_LWKT_RESCHED, RQF_AST_LWKT_RESCHED); -ASSYM(RQF_AST_UPCALL, RQF_AST_UPCALL); ASSYM(RQF_TIMER, RQF_TIMER); ASSYM(RQF_AST_MASK, RQF_AST_MASK); diff --git a/sys/platform/pc32/i386/ipl.s b/sys/platform/pc32/i386/ipl.s index 7d4ec0c..e2d0b8d 100644 --- a/sys/platform/pc32/i386/ipl.s +++ b/sys/platform/pc32/i386/ipl.s @@ -288,7 +288,7 @@ doreti_soft: * to do is a reschedule. */ doreti_ast: - andl $~(RQF_AST_SIGNAL|RQF_AST_UPCALL),PCPU(reqflags) + andl $~RQF_AST_SIGNAL,PCPU(reqflags) sti movl %eax,%esi /* save cpl (can't use stack) */ movl $T_ASTFLT,TF_TRAPNO(%esp) diff --git a/sys/platform/pc32/i386/machdep.c b/sys/platform/pc32/i386/machdep.c index 9cc82a6..75442571 100644 --- a/sys/platform/pc32/i386/machdep.c +++ b/sys/platform/pc32/i386/machdep.c @@ -69,7 +69,6 @@ #include #include #include -#include #include #include @@ -702,158 +701,6 @@ sys_sigreturn(struct sigreturn_args *uap) } /* - * Stack frame on entry to function. %eax will contain the function vector, - * %ecx will contain the function data. flags, ecx, and eax will have - * already been pushed on the stack. - */ -struct upc_frame { - register_t eax; - register_t ecx; - register_t edx; - register_t flags; - register_t oldip; -}; - -void -sendupcall(struct vmupcall *vu, int morepending) -{ - struct lwp *lp = curthread->td_lwp; - struct trapframe *regs; - struct upcall upcall; - struct upc_frame upc_frame; - int crit_count = 0; - - /* - * If we are a virtual kernel running an emulated user process - * context, switch back to the virtual kernel context before - * trying to post the signal. - */ - if (lp->lwp_vkernel && lp->lwp_vkernel->ve) { - lp->lwp_md.md_regs->tf_trapno = 0; - vkernel_trap(lp, lp->lwp_md.md_regs); - } - - /* - * Get the upcall data structure - */ - if (copyin(lp->lwp_upcall, &upcall, sizeof(upcall)) || - copyin((char *)upcall.upc_uthread + upcall.upc_critoff, &crit_count, sizeof(int)) - ) { - vu->vu_pending = 0; - kprintf("bad upcall address\n"); - return; - } - - /* - * If the data structure is already marked pending or has a critical - * section count, mark the data structure as pending and return - * without doing an upcall. vu_pending is left set. - */ - if (upcall.upc_pending || crit_count >= vu->vu_pending) { - if (upcall.upc_pending < vu->vu_pending) { - upcall.upc_pending = vu->vu_pending; - copyout(&upcall.upc_pending, &lp->lwp_upcall->upc_pending, - sizeof(upcall.upc_pending)); - } - return; - } - - /* - * We can run this upcall now, clear vu_pending. - * - * Bump our critical section count and set or clear the - * user pending flag depending on whether more upcalls are - * pending. The user will be responsible for calling - * upc_dispatch(-1) to process remaining upcalls. - */ - vu->vu_pending = 0; - upcall.upc_pending = morepending; - ++crit_count; - copyout(&upcall.upc_pending, &lp->lwp_upcall->upc_pending, - sizeof(upcall.upc_pending)); - copyout(&crit_count, (char *)upcall.upc_uthread + upcall.upc_critoff, - sizeof(int)); - - /* - * Construct a stack frame and issue the upcall - */ - regs = lp->lwp_md.md_regs; - upc_frame.eax = regs->tf_eax; - upc_frame.ecx = regs->tf_ecx; - upc_frame.edx = regs->tf_edx; - upc_frame.flags = regs->tf_eflags; - upc_frame.oldip = regs->tf_eip; - if (copyout(&upc_frame, (void *)(regs->tf_esp - sizeof(upc_frame)), - sizeof(upc_frame)) != 0) { - kprintf("bad stack on upcall\n"); - } else { - regs->tf_eax = (register_t)vu->vu_func; - regs->tf_ecx = (register_t)vu->vu_data; - regs->tf_edx = (register_t)lp->lwp_upcall; - regs->tf_eip = (register_t)vu->vu_ctx; - regs->tf_esp -= sizeof(upc_frame); - } -} - -/* - * fetchupcall occurs in the context of a system call, which means that - * we have to return EJUSTRETURN in order to prevent eax and edx from - * being overwritten by the syscall return value. - * - * if vu is not NULL we return the new context in %edx, the new data in %ecx, - * and the function pointer in %eax. - */ -int -fetchupcall(struct vmupcall *vu, int morepending, void *rsp) -{ - struct upc_frame upc_frame; - struct lwp *lp = curthread->td_lwp; - struct trapframe *regs; - int error; - struct upcall upcall; - int crit_count; - - regs = lp->lwp_md.md_regs; - - error = copyout(&morepending, &lp->lwp_upcall->upc_pending, sizeof(int)); - if (error == 0) { - if (vu) { - /* - * This jumps us to the next ready context. - */ - vu->vu_pending = 0; - error = copyin(lp->lwp_upcall, &upcall, sizeof(upcall)); - crit_count = 0; - if (error == 0) - error = copyin((char *)upcall.upc_uthread + upcall.upc_critoff, &crit_count, sizeof(int)); - ++crit_count; - if (error == 0) - error = copyout(&crit_count, (char *)upcall.upc_uthread + upcall.upc_critoff, sizeof(int)); - regs->tf_eax = (register_t)vu->vu_func; - regs->tf_ecx = (register_t)vu->vu_data; - regs->tf_edx = (register_t)lp->lwp_upcall; - regs->tf_eip = (register_t)vu->vu_ctx; - regs->tf_esp = (register_t)rsp; - } else { - /* - * This returns us to the originally interrupted code. - */ - error = copyin(rsp, &upc_frame, sizeof(upc_frame)); - regs->tf_eax = upc_frame.eax; - regs->tf_ecx = upc_frame.ecx; - regs->tf_edx = upc_frame.edx; - regs->tf_eflags = (regs->tf_eflags & ~PSL_USERCHANGE) | - (upc_frame.flags & PSL_USERCHANGE); - regs->tf_eip = upc_frame.oldip; - regs->tf_esp = (register_t)((char *)rsp + sizeof(upc_frame)); - } - } - if (error == 0) - error = EJUSTRETURN; - return(error); -} - -/* * Machine dependent boot() routine * * I haven't seen anything to put here yet diff --git a/sys/platform/pc32/i386/trap.c b/sys/platform/pc32/i386/trap.c index 8268c77..4087c8d 100644 --- a/sys/platform/pc32/i386/trap.c +++ b/sys/platform/pc32/i386/trap.c @@ -70,7 +70,6 @@ #include #endif #include -#include #include #include #include @@ -210,7 +209,7 @@ userenter(struct thread *curtd, struct proc *curp) } /* - * Handle signals, upcalls, profiling, and other AST's and/or tasks that + * Handle signals, profiling, and other AST's and/or tasks that * must be completed before we can return to or try to return to userland. * * Note that td_sticks is a 64 bit quantity, but there's no point doing 64 @@ -262,7 +261,7 @@ recheck: * Post any pending upcalls. If running a virtual kernel be sure * to restore the virtual kernel's vmspace before posting the upcall. */ - if (p->p_flags & (P_SIGVTALRM | P_SIGPROF | P_UPCALLPEND)) { + if (p->p_flags & (P_SIGVTALRM | P_SIGPROF)) { lwkt_gettoken(&p->p_token); if (p->p_flags & P_SIGVTALRM) { p->p_flags &= ~P_SIGVTALRM; @@ -272,10 +271,6 @@ recheck: p->p_flags &= ~P_SIGPROF; ksignal(p, SIGPROF); } - if (p->p_flags & P_UPCALLPEND) { - p->p_flags &= ~P_UPCALLPEND; - postupcall(lp); - } lwkt_reltoken(&p->p_token); goto recheck; } diff --git a/sys/platform/pc64/x86_64/genassym.c b/sys/platform/pc64/x86_64/genassym.c index bc8e0f8..12f860e 100644 --- a/sys/platform/pc64/x86_64/genassym.c +++ b/sys/platform/pc64/x86_64/genassym.c @@ -217,7 +217,6 @@ ASSYM(RQF_AST_OWEUPC, RQF_AST_OWEUPC); ASSYM(RQF_AST_SIGNAL, RQF_AST_SIGNAL); ASSYM(RQF_AST_USER_RESCHED, RQF_AST_USER_RESCHED); ASSYM(RQF_AST_LWKT_RESCHED, RQF_AST_LWKT_RESCHED); -ASSYM(RQF_AST_UPCALL, RQF_AST_UPCALL); ASSYM(RQF_TIMER, RQF_TIMER); ASSYM(RQF_AST_MASK, RQF_AST_MASK); ASSYM(RQF_QUICKRET, RQF_QUICKRET); diff --git a/sys/platform/pc64/x86_64/ipl.s b/sys/platform/pc64/x86_64/ipl.s index 900b91a..8a67480 100644 --- a/sys/platform/pc64/x86_64/ipl.s +++ b/sys/platform/pc64/x86_64/ipl.s @@ -294,7 +294,7 @@ doreti_soft: * to do is a reschedule. */ doreti_ast: - andl $~(RQF_AST_SIGNAL|RQF_AST_UPCALL),PCPU(reqflags) + andl $~RQF_AST_SIGNAL,PCPU(reqflags) sti movl %eax,%r12d /* save cpl (can't use stack) */ movl $T_ASTFLT,TF_TRAPNO(%rsp) diff --git a/sys/platform/pc64/x86_64/machdep.c b/sys/platform/pc64/x86_64/machdep.c index 227eef8..d1ba94f 100644 --- a/sys/platform/pc64/x86_64/machdep.c +++ b/sys/platform/pc64/x86_64/machdep.c @@ -68,7 +68,6 @@ #include #include #include -#include #include #include @@ -753,158 +752,6 @@ sys_sigreturn(struct sigreturn_args *uap) } /* - * Stack frame on entry to function. %rax will contain the function vector, - * %rcx will contain the function data. flags, rcx, and rax will have - * already been pushed on the stack. - */ -struct upc_frame { - register_t rax; - register_t rcx; - register_t rdx; - register_t flags; - register_t oldip; -}; - -void -sendupcall(struct vmupcall *vu, int morepending) -{ - struct lwp *lp = curthread->td_lwp; - struct trapframe *regs; - struct upcall upcall; - struct upc_frame upc_frame; - int crit_count = 0; - - /* - * If we are a virtual kernel running an emulated user process - * context, switch back to the virtual kernel context before - * trying to post the signal. - */ - if (lp->lwp_vkernel && lp->lwp_vkernel->ve) { - lp->lwp_md.md_regs->tf_trapno = 0; - vkernel_trap(lp, lp->lwp_md.md_regs); - } - - /* - * Get the upcall data structure - */ - if (copyin(lp->lwp_upcall, &upcall, sizeof(upcall)) || - copyin((char *)upcall.upc_uthread + upcall.upc_critoff, &crit_count, sizeof(int)) - ) { - vu->vu_pending = 0; - kprintf("bad upcall address\n"); - return; - } - - /* - * If the data structure is already marked pending or has a critical - * section count, mark the data structure as pending and return - * without doing an upcall. vu_pending is left set. - */ - if (upcall.upc_pending || crit_count >= vu->vu_pending) { - if (upcall.upc_pending < vu->vu_pending) { - upcall.upc_pending = vu->vu_pending; - copyout(&upcall.upc_pending, &lp->lwp_upcall->upc_pending, - sizeof(upcall.upc_pending)); - } - return; - } - - /* - * We can run this upcall now, clear vu_pending. - * - * Bump our critical section count and set or clear the - * user pending flag depending on whether more upcalls are - * pending. The user will be responsible for calling - * upc_dispatch(-1) to process remaining upcalls. - */ - vu->vu_pending = 0; - upcall.upc_pending = morepending; - ++crit_count; - copyout(&upcall.upc_pending, &lp->lwp_upcall->upc_pending, - sizeof(upcall.upc_pending)); - copyout(&crit_count, (char *)upcall.upc_uthread + upcall.upc_critoff, - sizeof(int)); - - /* - * Construct a stack frame and issue the upcall - */ - regs = lp->lwp_md.md_regs; - upc_frame.rax = regs->tf_rax; - upc_frame.rcx = regs->tf_rcx; - upc_frame.rdx = regs->tf_rdx; - upc_frame.flags = regs->tf_rflags; - upc_frame.oldip = regs->tf_rip; - if (copyout(&upc_frame, (void *)(regs->tf_rsp - sizeof(upc_frame) - 128), - sizeof(upc_frame)) != 0) { - kprintf("bad stack on upcall\n"); - } else { - regs->tf_rax = (register_t)vu->vu_func; - regs->tf_rcx = (register_t)vu->vu_data; - regs->tf_rdx = (register_t)lp->lwp_upcall; - regs->tf_rip = (register_t)vu->vu_ctx; - regs->tf_rsp -= sizeof(upc_frame) + 128; - } -} - -/* - * fetchupcall occurs in the context of a system call, which means that - * we have to return EJUSTRETURN in order to prevent eax and edx from - * being overwritten by the syscall return value. - * - * if vu is not NULL we return the new context in %edx, the new data in %ecx, - * and the function pointer in %eax. - */ -int -fetchupcall(struct vmupcall *vu, int morepending, void *rsp) -{ - struct upc_frame upc_frame; - struct lwp *lp = curthread->td_lwp; - struct trapframe *regs; - int error; - struct upcall upcall; - int crit_count; - - regs = lp->lwp_md.md_regs; - - error = copyout(&morepending, &lp->lwp_upcall->upc_pending, sizeof(int)); - if (error == 0) { - if (vu) { - /* - * This jumps us to the next ready context. - */ - vu->vu_pending = 0; - error = copyin(lp->lwp_upcall, &upcall, sizeof(upcall)); - crit_count = 0; - if (error == 0) - error = copyin((char *)upcall.upc_uthread + upcall.upc_critoff, &crit_count, sizeof(int)); - ++crit_count; - if (error == 0) - error = copyout(&crit_count, (char *)upcall.upc_uthread + upcall.upc_critoff, sizeof(int)); - regs->tf_rax = (register_t)vu->vu_func; - regs->tf_rcx = (register_t)vu->vu_data; - regs->tf_rdx = (register_t)lp->lwp_upcall; - regs->tf_rip = (register_t)vu->vu_ctx; - regs->tf_rsp = (register_t)rsp; - } else { - /* - * This returns us to the originally interrupted code. - */ - error = copyin(rsp, &upc_frame, sizeof(upc_frame)); - regs->tf_rax = upc_frame.rax; - regs->tf_rcx = upc_frame.rcx; - regs->tf_rdx = upc_frame.rdx; - regs->tf_rflags = (regs->tf_rflags & ~PSL_USERCHANGE) | - (upc_frame.flags & PSL_USERCHANGE); - regs->tf_rip = upc_frame.oldip; - regs->tf_rsp = (register_t)((char *)rsp + sizeof(upc_frame)); - } - } - if (error == 0) - error = EJUSTRETURN; - return(error); -} - -/* * Machine dependent boot() routine * * I haven't seen anything to put here yet diff --git a/sys/platform/pc64/x86_64/trap.c b/sys/platform/pc64/x86_64/trap.c index a36f64f..64c3397 100644 --- a/sys/platform/pc64/x86_64/trap.c +++ b/sys/platform/pc64/x86_64/trap.c @@ -251,7 +251,7 @@ recheck: * Post any pending upcalls. If running a virtual kernel be sure * to restore the virtual kernel's vmspace before posting the upcall. */ - if (p->p_flags & (P_SIGVTALRM | P_SIGPROF | P_UPCALLPEND)) { + if (p->p_flags & (P_SIGVTALRM | P_SIGPROF)) { lwkt_gettoken(&p->p_token); if (p->p_flags & P_SIGVTALRM) { p->p_flags &= ~P_SIGVTALRM; @@ -261,10 +261,6 @@ recheck: p->p_flags &= ~P_SIGPROF; ksignal(p, SIGPROF); } - if (p->p_flags & P_UPCALLPEND) { - p->p_flags &= ~P_UPCALLPEND; - postupcall(lp); - } lwkt_reltoken(&p->p_token); goto recheck; } diff --git a/sys/platform/vkernel/i386/cpu_regs.c b/sys/platform/vkernel/i386/cpu_regs.c index 548abea..d5d52a4 100644 --- a/sys/platform/vkernel/i386/cpu_regs.c +++ b/sys/platform/vkernel/i386/cpu_regs.c @@ -64,7 +64,6 @@ #include #include #include -#include #include #include @@ -503,158 +502,6 @@ sys_sigreturn(struct sigreturn_args *uap) } /* - * Stack frame on entry to function. %eax will contain the function vector, - * %ecx will contain the function data. flags, ecx, and eax will have - * already been pushed on the stack. - */ -struct upc_frame { - register_t eax; - register_t ecx; - register_t edx; - register_t flags; - register_t oldip; -}; - -void -sendupcall(struct vmupcall *vu, int morepending) -{ - struct lwp *lp = curthread->td_lwp; - struct trapframe *regs; - struct upcall upcall; - struct upc_frame upc_frame; - int crit_count = 0; - - /* - * If we are a virtual kernel running an emulated user process - * context, switch back to the virtual kernel context before - * trying to post the signal. - */ - if (lp->lwp_vkernel && lp->lwp_vkernel->ve) { - lp->lwp_md.md_regs->tf_trapno = 0; - vkernel_trap(lp, lp->lwp_md.md_regs); - } - - /* - * Get the upcall data structure - */ - if (copyin(lp->lwp_upcall, &upcall, sizeof(upcall)) || - copyin((char *)upcall.upc_uthread + upcall.upc_critoff, &crit_count, sizeof(int)) - ) { - vu->vu_pending = 0; - kprintf("bad upcall address\n"); - return; - } - - /* - * If the data structure is already marked pending or has a critical - * section count, mark the data structure as pending and return - * without doing an upcall. vu_pending is left set. - */ - if (upcall.upc_pending || crit_count >= vu->vu_pending) { - if (upcall.upc_pending < vu->vu_pending) { - upcall.upc_pending = vu->vu_pending; - copyout(&upcall.upc_pending, &lp->lwp_upcall->upc_pending, - sizeof(upcall.upc_pending)); - } - return; - } - - /* - * We can run this upcall now, clear vu_pending. - * - * Bump our critical section count and set or clear the - * user pending flag depending on whether more upcalls are - * pending. The user will be responsible for calling - * upc_dispatch(-1) to process remaining upcalls. - */ - vu->vu_pending = 0; - upcall.upc_pending = morepending; - ++crit_count; - copyout(&upcall.upc_pending, &lp->lwp_upcall->upc_pending, - sizeof(upcall.upc_pending)); - copyout(&crit_count, (char *)upcall.upc_uthread + upcall.upc_critoff, - sizeof(int)); - - /* - * Construct a stack frame and issue the upcall - */ - regs = lp->lwp_md.md_regs; - upc_frame.eax = regs->tf_eax; - upc_frame.ecx = regs->tf_ecx; - upc_frame.edx = regs->tf_edx; - upc_frame.flags = regs->tf_eflags; - upc_frame.oldip = regs->tf_eip; - if (copyout(&upc_frame, (void *)(regs->tf_esp - sizeof(upc_frame)), - sizeof(upc_frame)) != 0) { - kprintf("bad stack on upcall\n"); - } else { - regs->tf_eax = (register_t)vu->vu_func; - regs->tf_ecx = (register_t)vu->vu_data; - regs->tf_edx = (register_t)lp->lwp_upcall; - regs->tf_eip = (register_t)vu->vu_ctx; - regs->tf_esp -= sizeof(upc_frame); - } -} - -/* - * fetchupcall occurs in the context of a system call, which means that - * we have to return EJUSTRETURN in order to prevent eax and edx from - * being overwritten by the syscall return value. - * - * if vu is not NULL we return the new context in %edx, the new data in %ecx, - * and the function pointer in %eax. - */ -int -fetchupcall (struct vmupcall *vu, int morepending, void *rsp) -{ - struct upc_frame upc_frame; - struct lwp *lp = curthread->td_lwp; - struct trapframe *regs; - int error; - struct upcall upcall; - int crit_count; - - regs = lp->lwp_md.md_regs; - - error = copyout(&morepending, &lp->lwp_upcall->upc_pending, sizeof(int)); - if (error == 0) { - if (vu) { - /* - * This jumps us to the next ready context. - */ - vu->vu_pending = 0; - error = copyin(lp->lwp_upcall, &upcall, sizeof(upcall)); - crit_count = 0; - if (error == 0) - error = copyin((char *)upcall.upc_uthread + upcall.upc_critoff, &crit_count, sizeof(int)); - ++crit_count; - if (error == 0) - error = copyout(&crit_count, (char *)upcall.upc_uthread + upcall.upc_critoff, sizeof(int)); - regs->tf_eax = (register_t)vu->vu_func; - regs->tf_ecx = (register_t)vu->vu_data; - regs->tf_edx = (register_t)lp->lwp_upcall; - regs->tf_eip = (register_t)vu->vu_ctx; - regs->tf_esp = (register_t)rsp; - } else { - /* - * This returns us to the originally interrupted code. - */ - error = copyin(rsp, &upc_frame, sizeof(upc_frame)); - regs->tf_eax = upc_frame.eax; - regs->tf_ecx = upc_frame.ecx; - regs->tf_edx = upc_frame.edx; - regs->tf_eflags = (regs->tf_eflags & ~PSL_USERCHANGE) | - (upc_frame.flags & PSL_USERCHANGE); - regs->tf_eip = upc_frame.oldip; - regs->tf_esp = (register_t)((char *)rsp + sizeof(upc_frame)); - } - } - if (error == 0) - error = EJUSTRETURN; - return(error); -} - -/* * cpu_idle() represents the idle LWKT. You cannot return from this function * (unless you want to blow things up!). Instead we look for runnable threads * and loop or halt as appropriate. Giant is not held on entry to the thread. diff --git a/sys/platform/vkernel/i386/genassym.c b/sys/platform/vkernel/i386/genassym.c index 219ed54..664ee96 100644 --- a/sys/platform/vkernel/i386/genassym.c +++ b/sys/platform/vkernel/i386/genassym.c @@ -183,7 +183,6 @@ ASSYM(RQF_AST_OWEUPC, RQF_AST_OWEUPC); ASSYM(RQF_AST_SIGNAL, RQF_AST_SIGNAL); ASSYM(RQF_AST_USER_RESCHED, RQF_AST_USER_RESCHED); ASSYM(RQF_AST_LWKT_RESCHED, RQF_AST_LWKT_RESCHED); -ASSYM(RQF_AST_UPCALL, RQF_AST_UPCALL); ASSYM(RQF_AST_MASK, RQF_AST_MASK); ASSYM(FIRST_SOFTINT, FIRST_SOFTINT); diff --git a/sys/platform/vkernel/i386/trap.c b/sys/platform/vkernel/i386/trap.c index 29f0a60..25a58d7 100644 --- a/sys/platform/vkernel/i386/trap.c +++ b/sys/platform/vkernel/i386/trap.c @@ -66,7 +66,6 @@ #include #endif #include -#include #include #include #include @@ -192,7 +191,7 @@ userenter(struct thread *curtd, struct proc *curp) } /* - * Handle signals, upcalls, profiling, and other AST's and/or tasks that + * Handle signals, profiling, and other AST's and/or tasks that * must be completed before we can return to or try to return to userland. * * Note that td_sticks is a 64 bit quantity, but there's no point doing 64 @@ -237,7 +236,7 @@ recheck: * Post any pending upcalls. If running a virtual kernel be sure * to restore the virtual kernel's vmspace before posting the upcall. */ - if (p->p_flags & (P_SIGVTALRM | P_SIGPROF | P_UPCALLPEND)) { + if (p->p_flags & (P_SIGVTALRM | P_SIGPROF)) { lwkt_gettoken(&p->p_token); if (p->p_flags & P_SIGVTALRM) { p->p_flags &= ~P_SIGVTALRM; @@ -247,10 +246,6 @@ recheck: p->p_flags &= ~P_SIGPROF; ksignal(p, SIGPROF); } - if (p->p_flags & P_UPCALLPEND) { - p->p_flags &= ~P_UPCALLPEND; - postupcall(lp); - } lwkt_reltoken(&p->p_token); goto recheck; } diff --git a/sys/platform/vkernel64/x86_64/cpu_regs.c b/sys/platform/vkernel64/x86_64/cpu_regs.c index 566582c..aad8884 100644 --- a/sys/platform/vkernel64/x86_64/cpu_regs.c +++ b/sys/platform/vkernel64/x86_64/cpu_regs.c @@ -63,7 +63,6 @@ #include #include #include -#include #include #include @@ -508,158 +507,6 @@ sys_sigreturn(struct sigreturn_args *uap) } /* - * Stack frame on entry to function. %rax will contain the function vector, - * %rcx will contain the function data. flags, rcx, and rax will have - * already been pushed on the stack. - */ -struct upc_frame { - register_t rax; - register_t rcx; - register_t rdx; - register_t flags; - register_t oldip; -}; - -void -sendupcall(struct vmupcall *vu, int morepending) -{ - struct lwp *lp = curthread->td_lwp; - struct trapframe *regs; - struct upcall upcall; - struct upc_frame upc_frame; - int crit_count = 0; - - /* - * If we are a virtual kernel running an emulated user process - * context, switch back to the virtual kernel context before - * trying to post the signal. - */ - if (lp->lwp_vkernel && lp->lwp_vkernel->ve) { - lp->lwp_md.md_regs->tf_trapno = 0; - vkernel_trap(lp, lp->lwp_md.md_regs); - } - - /* - * Get the upcall data structure - */ - if (copyin(lp->lwp_upcall, &upcall, sizeof(upcall)) || - copyin((char *)upcall.upc_uthread + upcall.upc_critoff, &crit_count, sizeof(int)) - ) { - vu->vu_pending = 0; - kprintf("bad upcall address\n"); - return; - } - - /* - * If the data structure is already marked pending or has a critical - * section count, mark the data structure as pending and return - * without doing an upcall. vu_pending is left set. - */ - if (upcall.upc_pending || crit_count >= vu->vu_pending) { - if (upcall.upc_pending < vu->vu_pending) { - upcall.upc_pending = vu->vu_pending; - copyout(&upcall.upc_pending, &lp->lwp_upcall->upc_pending, - sizeof(upcall.upc_pending)); - } - return; - } - - /* - * We can run this upcall now, clear vu_pending. - * - * Bump our critical section count and set or clear the - * user pending flag depending on whether more upcalls are - * pending. The user will be responsible for calling - * upc_dispatch(-1) to process remaining upcalls. - */ - vu->vu_pending = 0; - upcall.upc_pending = morepending; - ++crit_count; - copyout(&upcall.upc_pending, &lp->lwp_upcall->upc_pending, - sizeof(upcall.upc_pending)); - copyout(&crit_count, (char *)upcall.upc_uthread + upcall.upc_critoff, - sizeof(int)); - - /* - * Construct a stack frame and issue the upcall - */ - regs = lp->lwp_md.md_regs; - upc_frame.rax = regs->tf_rax; - upc_frame.rcx = regs->tf_rcx; - upc_frame.rdx = regs->tf_rdx; - upc_frame.flags = regs->tf_rflags; - upc_frame.oldip = regs->tf_rip; - if (copyout(&upc_frame, (void *)(regs->tf_rsp - sizeof(upc_frame)), - sizeof(upc_frame)) != 0) { - kprintf("bad stack on upcall\n"); - } else { - regs->tf_rax = (register_t)vu->vu_func; - regs->tf_rcx = (register_t)vu->vu_data; - regs->tf_rdx = (register_t)lp->lwp_upcall; - regs->tf_rip = (register_t)vu->vu_ctx; - regs->tf_rsp -= sizeof(upc_frame); - } -} - -/* - * fetchupcall occurs in the context of a system call, which means that - * we have to return EJUSTRETURN in order to prevent eax and edx from - * being overwritten by the syscall return value. - * - * if vu is not NULL we return the new context in %edx, the new data in %ecx, - * and the function pointer in %eax. - */ -int -fetchupcall(struct vmupcall *vu, int morepending, void *rsp) -{ - struct upc_frame upc_frame; - struct lwp *lp = curthread->td_lwp; - struct trapframe *regs; - int error; - struct upcall upcall; - int crit_count; - - regs = lp->lwp_md.md_regs; - - error = copyout(&morepending, &lp->lwp_upcall->upc_pending, sizeof(int)); - if (error == 0) { - if (vu) { - /* - * This jumps us to the next ready context. - */ - vu->vu_pending = 0; - error = copyin(lp->lwp_upcall, &upcall, sizeof(upcall)); - crit_count = 0; - if (error == 0) - error = copyin((char *)upcall.upc_uthread + upcall.upc_critoff, &crit_count, sizeof(int)); - ++crit_count; - if (error == 0) - error = copyout(&crit_count, (char *)upcall.upc_uthread + upcall.upc_critoff, sizeof(int)); - regs->tf_rax = (register_t)vu->vu_func; - regs->tf_rcx = (register_t)vu->vu_data; - regs->tf_rdx = (register_t)lp->lwp_upcall; - regs->tf_rip = (register_t)vu->vu_ctx; - regs->tf_rsp = (register_t)rsp; - } else { - /* - * This returns us to the originally interrupted code. - */ - error = copyin(rsp, &upc_frame, sizeof(upc_frame)); - regs->tf_rax = upc_frame.rax; - regs->tf_rcx = upc_frame.rcx; - regs->tf_rdx = upc_frame.rdx; - regs->tf_rflags = (regs->tf_rflags & ~PSL_USERCHANGE) | - (upc_frame.flags & PSL_USERCHANGE); - regs->tf_rip = upc_frame.oldip; - regs->tf_rsp = (register_t)((char *)rsp + sizeof(upc_frame)); - } - } - if (error == 0) - error = EJUSTRETURN; - return(error); -} - -/* * cpu_idle() represents the idle LWKT. You cannot return from this function * (unless you want to blow things up!). Instead we look for runnable threads * and loop or halt as appropriate. Giant is not held on entry to the thread. diff --git a/sys/platform/vkernel64/x86_64/trap.c b/sys/platform/vkernel64/x86_64/trap.c index 7d794e8..adef419 100644 --- a/sys/platform/vkernel64/x86_64/trap.c +++ b/sys/platform/vkernel64/x86_64/trap.c @@ -65,7 +65,6 @@ #include #endif #include -#include #include #include #include @@ -192,7 +191,7 @@ userenter(struct thread *curtd, struct proc *curp) } /* - * Handle signals, upcalls, profiling, and other AST's and/or tasks that + * Handle signals, profiling, and other AST's and/or tasks that * must be completed before we can return to or try to return to userland. * * Note that td_sticks is a 64 bit quantity, but there's no point doing 64 @@ -237,7 +236,7 @@ recheck: * Post any pending upcalls. If running a virtual kernel be sure * to restore the virtual kernel's vmspace before posting the upcall. */ - if (p->p_flags & (P_SIGVTALRM | P_SIGPROF | P_UPCALLPEND)) { + if (p->p_flags & (P_SIGVTALRM | P_SIGPROF)) { lwkt_gettoken(&p->p_token); if (p->p_flags & P_SIGVTALRM) { p->p_flags &= ~P_SIGVTALRM; @@ -247,10 +246,6 @@ recheck: p->p_flags &= ~P_SIGPROF; ksignal(p, SIGPROF); } - if (p->p_flags & P_UPCALLPEND) { - p->p_flags &= ~P_UPCALLPEND; - postupcall(lp); - } lwkt_reltoken(&p->p_token); goto recheck; } diff --git a/sys/sys/globaldata.h b/sys/sys/globaldata.h index b9aff89..ca97a64 100644 --- a/sys/sys/globaldata.h +++ b/sys/sys/globaldata.h @@ -180,7 +180,7 @@ typedef struct globaldata *globaldata_t; #define RQB_AST_SIGNAL 3 /* 0008 */ #define RQB_AST_USER_RESCHED 4 /* 0010 */ #define RQB_AST_LWKT_RESCHED 5 /* 0020 */ -#define RQB_AST_UPCALL 6 /* 0040 */ +#define RQB_UNUSED6 6 /* 0040 */ #define RQB_TIMER 7 /* 0080 */ #define RQB_RUNNING 8 /* 0100 */ #define RQB_SPINNING 9 /* 0200 */ @@ -193,14 +193,12 @@ typedef struct globaldata *globaldata_t; #define RQF_AST_SIGNAL (1 << RQB_AST_SIGNAL) #define RQF_AST_USER_RESCHED (1 << RQB_AST_USER_RESCHED) #define RQF_AST_LWKT_RESCHED (1 << RQB_AST_LWKT_RESCHED) -#define RQF_AST_UPCALL (1 << RQB_AST_UPCALL) #define RQF_RUNNING (1 << RQB_RUNNING) #define RQF_SPINNING (1 << RQB_SPINNING) #define RQF_QUICKRET (1 << RQB_QUICKRET) #define RQF_AST_MASK (RQF_AST_OWEUPC|RQF_AST_SIGNAL|\ - RQF_AST_USER_RESCHED|RQF_AST_LWKT_RESCHED|\ - RQF_AST_UPCALL) + RQF_AST_USER_RESCHED|RQF_AST_LWKT_RESCHED) #define RQF_IDLECHECK_MASK (RQF_IPIQ|RQF_INTPEND|RQF_TIMER) #define RQF_IDLECHECK_WK_MASK (RQF_IDLECHECK_MASK|RQF_AST_LWKT_RESCHED) diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 5269bdc..5d86b07 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -64,7 +64,6 @@ #include /* For struct sysentvec */ #include #include -#include #include #ifdef _KERNEL #include @@ -221,7 +220,7 @@ struct lwp { struct mdproc lwp_md; /* Any machine-dependent fields. */ struct thread *lwp_thread; /* backpointer to proc's thread */ - struct upcall *lwp_upcall; /* REGISTERED USERLAND POINTER! */ + void *lwp_unused01; /* for future fields */ struct kqueue lwp_kqueue; /* for select/poll */ u_int lwp_kqueue_serial; struct lwkt_token lwp_token; /* per-lwp token for signal/state */ @@ -360,7 +359,7 @@ struct proc { #define P_CONTINUED 0x08000 /* Proc has continued from a stopped state */ #define P_UNUSED16 0x00010000 -#define P_UPCALLPEND 0x00020000 /* an upcall is pending */ +#define P_UNUSED17 0x00020000 #define P_SWAPWAIT 0x00040000 /* Waiting for a swapin */ #define P_UNUSED19 0x00080000 /* was: Now in a zombied state */ @@ -375,7 +374,7 @@ struct proc { #define P_SIGPROF 0x04000000 /* signal SIGPROF pending due to itimer */ #define P_INEXEC 0x08000000 /* Process is in execve(). */ #define P_UNUSED28 0x10000000 -#define P_UPCALLWAIT 0x20000000 /* Wait for upcall or signal */ +#define P_UNUSED29 0x20000000 #define P_XCPU 0x40000000 /* SIGXCPU */ #define LWP_ALTSTACK 0x0000001 /* have alternate signal stack */ diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 5f2067e..42f54b2 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -32,7 +32,6 @@ * * @(#)signalvar.h 8.6 (Berkeley) 2/19/95 * $FreeBSD: src/sys/sys/signalvar.h,v 1.34.2.1 2000/05/16 06:58:05 dillon Exp $ - * $DragonFly: src/sys/sys/signalvar.h,v 1.23 2008/04/21 15:47:58 dillon Exp $ */ #ifndef _SYS_SIGNALVAR_H_ /* tmp for user.h */ @@ -182,7 +181,6 @@ typedef void (*proc_func_t)(struct proc *); struct pgrp; struct proc; struct sigio; -struct vmupcall; extern int sugid_coredump; /* Sysctl variable kern.sugid_coredump */ @@ -206,8 +204,6 @@ void trapsignal (struct lwp *p, int sig, u_long code); * Machine-dependent functions: */ void sendsig (sig_t action, int sig, sigset_t *retmask, u_long code); -void sendupcall (struct vmupcall *vu, int morepending); -int fetchupcall (struct vmupcall *vu, int morepending, void *rsp); void sigexit (struct lwp *lp, int sig); int checkpoint_signal_handler(struct lwp *p); diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 921b055..f76d189 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -293,8 +293,8 @@ #define SYS_varsym_set 450 #define SYS_varsym_get 451 #define SYS_varsym_list 452 -#define SYS_upc_register 453 -#define SYS_upc_control 454 + /* 453 is obsolete upc_register */ + /* 454 is obsolete upc_control */ /* 455 is obsolete caps_sys_service */ /* 456 is obsolete caps_sys_client */ /* 457 is obsolete caps_sys_close */ diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index 16b4a03..83c6879 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -233,8 +233,6 @@ MIASM = \ varsym_set.o \ varsym_get.o \ varsym_list.o \ - upc_register.o \ - upc_control.o \ exec_sys_register.o \ exec_sys_unregister.o \ sys_checkpoint.o \ diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 37a1ab2..8607e0a 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -1729,23 +1729,6 @@ struct varsym_list_args { int maxsize; char maxsize_[PAD_(int)]; int * marker; char marker_[PAD_(int *)]; }; -struct upc_register_args { -#ifdef _KERNEL - struct sysmsg sysmsg; -#endif - struct upcall * upc; char upc_[PAD_(struct upcall *)]; - void * ctxfunc; char ctxfunc_[PAD_(void *)]; - void * func; char func_[PAD_(void *)]; - void * data; char data_[PAD_(void *)]; -}; -struct upc_control_args { -#ifdef _KERNEL - struct sysmsg sysmsg; -#endif - int cmd; char cmd_[PAD_(int)]; - int upcid; char upcid_[PAD_(int)]; - void * data; char data_[PAD_(void *)]; -}; struct exec_sys_register_args { #ifdef _KERNEL struct sysmsg sysmsg; @@ -2838,8 +2821,6 @@ int sys_sendfile (struct sendfile_args *); int sys_varsym_set (struct varsym_set_args *); int sys_varsym_get (struct varsym_get_args *); int sys_varsym_list (struct varsym_list_args *); -int sys_upc_register (struct upc_register_args *); -int sys_upc_control (struct upc_control_args *); int sys_exec_sys_register (struct exec_sys_register_args *); int sys_exec_sys_unregister (struct exec_sys_unregister_args *); int sys_sys_checkpoint (struct sys_checkpoint_args *); diff --git a/sys/sys/sysunion.h b/sys/sys/sysunion.h index aaab8c0..5384702 100644 --- a/sys/sys/sysunion.h +++ b/sys/sys/sysunion.h @@ -340,8 +340,6 @@ union sysunion { struct varsym_set_args varsym_set; struct varsym_get_args varsym_get; struct varsym_list_args varsym_list; - struct upc_register_args upc_register; - struct upc_control_args upc_control; struct exec_sys_register_args exec_sys_register; struct exec_sys_unregister_args exec_sys_unregister; struct sys_checkpoint_args sys_checkpoint; diff --git a/sys/sys/upcall.h b/sys/sys/upcall.h deleted file mode 100644 index 324871f..0000000 --- a/sys/sys/upcall.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2003,2004 The DragonFly Project. All rights reserved. - * - * This code is derived from software contributed to The DragonFly Project - * by Matthew Dillon - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of The DragonFly Project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific, prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $DragonFly: src/sys/sys/upcall.h,v 1.11 2006/09/10 21:35:11 dillon Exp $ - */ - -#ifndef _SYS_UPCALL_H_ -#define _SYS_UPCALL_H_ - -struct thread; -struct lwp; - -typedef void (*upcall_func_t)(void *); - -struct upcall { - int upc_magic; - int upc_critoff; /* offset of crit_count in uthread */ - int upc_pending; /* must follow crit_count */ - struct thread *upc_uthread; /* pointer to user thread (opaque) */ -}; - -#define UPCALL_MAGIC 0x55504331 -#define UPCALL_MAXCOUNT 32 - -#define UPC_CONTROL_DISPATCH 1 -#define UPC_CONTROL_NEXT 2 -#define UPC_CONTROL_DELETE 3 -#define UPC_CONTROL_POLL 4 -#define UPC_CONTROL_POLLANDCLEAR 5 -#define UPC_CONTROL_WAIT 6 - -#define UPC_RESERVED 32 /* # of reserved id's */ - -#if defined(_KERNEL) -/* - * Kernel protoypes - */ - -struct vmspace; - -void upc_release(struct vmspace *vm, struct lwp *lp); -void postupcall(struct lwp *lp); - -#else -/* - * Userland prototypes - */ -int upc_register(struct upcall *, upcall_func_t, upcall_func_t, void *); -int upc_control(int, int, void *); -void upc_callused_wrapper(void *); - -#endif - -#endif - diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 9db4855..6cfc488 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -364,7 +364,6 @@ vmspace_terminate(struct vmspace *vm) vm->vm_flags |= VMSPACE_EXIT2; cpu_vmspace_free(vm); shmexit(vm); - KKASSERT(vm->vm_upcalls == NULL); /* * Lock the map, to wait out all other references to it. @@ -3264,9 +3263,6 @@ vmspace_fork(struct vmspace *vm1) lwkt_gettoken(&vm1->vm_map.token); vm_map_lock(old_map); - /* - * XXX Note: upcalls are not copied. - */ vm2 = vmspace_alloc(old_map->min_offset, old_map->max_offset); lwkt_gettoken(&vm2->vm_map.token); bcopy(&vm1->vm_startcopy, &vm2->vm_startcopy, @@ -3676,8 +3672,8 @@ vmspace_exec(struct proc *p, struct vmspace *vmcopy) /* * If we are execing a resident vmspace we fork it, otherwise - * we create a new vmspace. Note that exitingcnt and upcalls - * are not copied to the new vmspace. + * we create a new vmspace. Note that exitingcnt is not + * copied to the new vmspace. */ lwkt_gettoken(&oldvmspace->vm_map.token); if (vmcopy) { diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h index e1780a6..3c54e87 100644 --- a/sys/vm/vm_map.h +++ b/sys/vm/vm_map.h @@ -62,7 +62,6 @@ * rights to redistribute these changes. * * $FreeBSD: src/sys/vm/vm_map.h,v 1.54.2.5 2003/01/13 22:51:17 dillon Exp $ - * $DragonFly: src/sys/vm/vm_map.h,v 1.30 2007/04/29 18:25:41 dillon Exp $ */ /* @@ -245,21 +244,6 @@ struct vm_map { */ #define MAP_WIREFUTURE 0x0001 /* wire all future pages */ -/* - * Registered upcall - */ -struct upcall; - -struct vmupcall { - struct vmupcall *vu_next; - void *vu_func; /* user upcall function */ - void *vu_data; /* user data */ - void *vu_ctx; /* user context function */ - struct lwp *vu_lwp; /* process that registered upcall */ - int vu_id; /* upcall identifier */ - int vu_pending; /* upcall request pending */ -}; - /* * Shareable process virtual address space. * @@ -283,10 +267,10 @@ struct vmspace { caddr_t vm_minsaddr; /* user VA at max stack growth */ #define vm_endcopy vm_exitingcnt int vm_exitingcnt; /* exit/wait context reaping */ - int vm_upccount; /* number of registered upcalls */ + int vm_unused01; /* for future fields */ int vm_pagesupply; u_int vm_holdcount; - struct vmupcall *vm_upcalls; /* registered upcalls */ + void *vm_unused02; /* for future fields */ struct sysref vm_sysref; /* sysref, refcnt, etc */ }; diff --git a/test/sysperf/Makefile b/test/sysperf/Makefile index 20a7800..a77c282 100644 --- a/test/sysperf/Makefile +++ b/test/sysperf/Makefile @@ -1,7 +1,3 @@ -# -# $DragonFly: src/test/sysperf/Makefile,v 1.17 2008/05/09 15:49:42 dillon Exp $ -# - TARGETS=/tmp/sc1 /tmp/sc2 /tmp/sc3 /tmp/sc4 /tmp/sc5 /tmp/sc6 /tmp/sc7 \ /tmp/loop1 /tmp/loop2 /tmp/loop3 /tmp/loop4 \ /tmp/call1 /tmp/call2 /tmp/call3 /tmp/cmp \ @@ -10,7 +6,6 @@ TARGETS=/tmp/sc1 /tmp/sc2 /tmp/sc3 /tmp/sc4 /tmp/sc5 /tmp/sc6 /tmp/sc7 \ /tmp/sp1 \ /tmp/sw1 /tmp/sw2 /tmp/sw3 \ /tmp/mbw1 \ - /tmp/upc1 \ /tmp/exec1 /tmp/exec2 \ /tmp/mem1 /tmp/mem2 \ /tmp/cld1 \ @@ -109,9 +104,6 @@ all: $(TARGETS) /tmp/sw3: quicksw1.c blib.c sw.S $(CC) $(CFLAGS) -DUSE_CALLU2 quicksw1.c blib.c sw.S -o /tmp/sw3 -/tmp/upc1: upcall.S upcall1.c blib.c - $(CC) $(CFLAGS) -DUSE_CALLU2 upcall.S upcall1.c blib.c -o /tmp/upc1 - /tmp/exec1: exec1.c blib.c $(CC) $(CFLAGS) -static -DISSTATIC exec1.c blib.c -o /tmp/exec1 diff --git a/test/sysperf/upcall.S b/test/sysperf/upcall.S deleted file mode 100644 index 66b73ea..0000000 --- a/test/sysperf/upcall.S +++ /dev/null @@ -1,32 +0,0 @@ - /* - * $DragonFly: src/test/sysperf/upcall.S,v 1.2 2003/11/21 08:32:45 dillon Exp $ - */ - .text - .globl callused_wrapper - -#define CRIT_COUNT 4 /* not a good idea to hardwire this XXX */ -#define PENDING 8 /* not a good idea to hardwire this XXX */ - - /* - * On entry: %eax contains function - * %ecx contains data - * Stack: [eax,ecx,eflags,oldip] - */ -callused_wrapper: - pushl %edx /* save %edx (upcall pointer) */ - pushl %ecx /* func(data) */ - call *%eax - addl $4,%esp - popl %edx /* upcall pointer */ - incl PENDING(%edx) /* set pending bit (prevents upcalls) */ - subl $32,CRIT_COUNT(%edx) /* cleanup critical section count */ - pushl %esp /* sp pointing to os supplied frame */ - pushl $-1 /* upcid */ - pushl $2 /* FETCH next */ - call upc_control - popl %eax - popl %ecx - popl %edx - popfl - ret - diff --git a/test/sysperf/upcall1.c b/test/sysperf/upcall1.c deleted file mode 100644 index e5941cb..0000000 --- a/test/sysperf/upcall1.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * UPCALL1.C - * - * Test upcall performance. WARNING! This test does not reflect - * reality... the test is effectively making two system calls for - * each upcall when under normal conditions no system calls should be - * necessary when handling an upcall. - * - * $DragonFly: src/test/sysperf/upcall1.c,v 1.3 2004/01/12 16:48:37 drhodus Exp $ - */ - -#include -#include -#include -#include -#include "blib.h" - -#define MAXCOUNT 10000000 - -struct upcall upc; /* simple single-cpu upcall test */ - -extern void callused_wrapper(void *); /* assembly */ -static void myfunc(void *data); - -int count = MAXCOUNT; -int id; - -int -main(int ac, char **av) -{ - id = upc_register(&upc, callused_wrapper, myfunc, "blah"); - printf("Warning: extra system calls in test means performance\n"); - printf("does not reflect reality. Divide times by 3 for raw\n"); - printf("per-upcall overhead (approximately)\n"); - printf("register upcall %d\n", id); - printf("try to dispatch the upcall\n"); - upc_control(UPC_CONTROL_DISPATCH, id, NULL); - stop_timing(MAXCOUNT, "Full-up upcall test"); - printf("final: %d %d (should be 0 0)\n", upc.upc_critoff, upc.upc_pending); - return 0; -} - -static void -myfunc(void *data) -{ - /* - * Dispatch a reentrant UPC. It should not stack because we are in a - * critical section, but the context code will catch it when it calls - * UPC_CONTROL_NEXT. - */ - if (--count > 0) { - upc_control(UPC_CONTROL_DISPATCH, id, NULL); - } - if (count > MAXCOUNT - 3) { - printf("UPCALL! (%s) upc: %d crit=%d pend=%d (should be 32 1) @sp %p\n", - data, upc.upc_magic, upc.upc_critoff, upc.upc_pending, &data); - if (count == MAXCOUNT - 2) { - printf("(sp should be same as before)\n"); - printf("doing a total of %d upcalls\n", MAXCOUNT); - usleep(20000); - start_timing(); - } - } -} - -- 1.7.7.2