Syscall messaging work 2: Continue with the implementation of sendsys(),
authorMatthew Dillon <dillon@dragonflybsd.org>
Thu, 24 Jul 2003 23:52:39 +0000 (23:52 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Thu, 24 Jul 2003 23:52:39 +0000 (23:52 +0000)
using int 0x81.  This entry point will be responsible for sending system
call messages or waiting for messages / port activity.

With this commit system call messages can be run through 0x81 but at the
moment they will always run synchronously. Here's the core interface
code for IA32:

    static __inline int
    sendsys(void *port, void *msg, int msgsize)
    {
int error;
__asm __volatile("int $0x81" : "=a"(error) :
"a"(port), "c"(msg), "d"(msgsize) : "memory");
return(error);
    }

Performance verses a direct system call is currently excellent considering
that this is my initial attempt.

600MHzC3 1.2GHzP3x2(SMP)

getuid() 1300 ns  909 ns
getuid_msg() 1700 ns 1077 ns

20 files changed:
sys/i386/i386/exception.s
sys/i386/i386/machdep.c
sys/i386/i386/trap.c
sys/kern/init_sysent.c
sys/kern/kern_device.c
sys/kern/lwkt_msgport.c
sys/kern/makesyscalls.sh
sys/kern/syscalls.c
sys/platform/pc32/i386/exception.s
sys/platform/pc32/i386/machdep.c
sys/platform/pc32/i386/trap.c
sys/sys/errno.h
sys/sys/globaldata.h
sys/sys/msgport.h
sys/sys/syscall-hide.h
sys/sys/syscall.h
sys/sys/syscall.mk
sys/sys/sysproto.h
sys/sys/sysunion.h
sys/sys/thread.h

index 1125676..20ebc80 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/i386/exception.s,v 1.65.2.3 2001/08/15 01:23:49 peter Exp $
- * $DragonFly: src/sys/i386/i386/Attic/exception.s,v 1.16 2003/07/24 01:41:16 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/exception.s,v 1.17 2003/07/24 23:52:36 dillon Exp $
  */
 
 #include "npx.h"
@@ -304,7 +304,6 @@ IDTVEC(int0x80_syscall)
        movl    $1,PCPU(intr_nesting_level)
        jmp     doreti
 
-#if 0
 /*
  * Trap gate entry for FreeBSD syscall messaging interface (int 0x81).
  * Arguments are passed in registers, the return value is placed in %eax.
@@ -338,8 +337,6 @@ IDTVEC(int0x81_syscall)
        movl    $1,PCPU(intr_nesting_level)
        jmp     doreti
 
-#endif
-
 /*
  * This function is what cpu_heavy_restore jumps to after a new process
  * is created.  The LWKT subsystem switches while holding a critical
index d13daad..f9cadac 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     from: @(#)machdep.c     7.4 (Berkeley) 6/3/91
  * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $
- * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.27 2003/07/24 01:41:16 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.28 2003/07/24 23:52:36 dillon Exp $
  */
 
 #include "apm.h"
@@ -1964,10 +1964,8 @@ init386(int first)
        setidt(19, &IDTVEC(xmm), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
        setidt(0x80, &IDTVEC(int0x80_syscall),
                        SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
-#if 0
        setidt(0x81, &IDTVEC(int0x81_syscall),
                        SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
-#endif
 
        r_idt.rd_limit = sizeof(idt0) - 1;
        r_idt.rd_base = (int) idt;
index 4f2f495..f088191 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     from: @(#)trap.c        7.4 (Berkeley) 5/13/91
  * $FreeBSD: src/sys/i386/i386/trap.c,v 1.147.2.11 2003/02/27 19:09:59 luoqi Exp $
- * $DragonFly: src/sys/i386/i386/Attic/trap.c,v 1.26 2003/07/24 01:41:16 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/trap.c,v 1.27 2003/07/24 23:52:36 dillon Exp $
  */
 
 /*
@@ -61,6 +61,7 @@
 #include <sys/sysent.h>
 #include <sys/uio.h>
 #include <sys/vmmeter.h>
+#include <sys/malloc.h>
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
@@ -166,6 +167,8 @@ static int slow_release;
 SYSCTL_INT(_machdep, OID_AUTO, slow_release, CTLFLAG_RW,
        &slow_release, 0, "Passive Release was nonoptimal");
 
+MALLOC_DEFINE(M_SYSMSG, "sysmsg", "sysmsg structure");
+
 /*
  * USER->KERNEL transition.  Do not transition us out of userland from the
  * point of view of the userland scheduler unless we actually have to
@@ -1359,8 +1362,6 @@ bad:
 #endif
 }
 
-#if 0  /* work in progress */
-
 /*
  *     sendsys2 -      MP aware system message request C handler
  */
@@ -1369,12 +1370,14 @@ sendsys2(struct trapframe frame)
 {
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
+       register_t orig_tf_eflags;
        struct sysent *callp;
-       sysunion_t sysmsg;
+       sysmsg_t sysmsg;
+       lwkt_msg_t umsg;
        u_quad_t sticks;
        int error;
        int narg;
-       u_int code;
+       u_int code = 0;
        int msgsize;
 
 #ifdef DIAGNOSTIC
@@ -1400,52 +1403,74 @@ sendsys2(struct trapframe frame)
        crit_exit();
 
        p->p_md.md_regs = &frame;
+       orig_tf_eflags = frame.tf_eflags;
 
        /*
         * Extract the system call message.  If msgsize is zero we are 
-        * blocking on a message and/or message port.
+        * blocking on a message and/or message port. YYY
         */
        if ((msgsize = frame.tf_edx) == 0) {
-               ... handle waiting ...
+               printf("waitport %08x msg %08x\n", frame.tf_eax, frame.tf_ecx);
+               error = ENOSYS;
+               goto bad2;
        }
 
        /*
         * Bad message size
         */
-       if (msgsize < 0 || msgsize > sizeof(*sysmsg)) {
+       if (msgsize < sizeof(struct lwkt_msg) || msgsize > sizeof(*sysmsg)) {
                error = ENOSYS;
-               goto bad;
+               goto bad2;
        }
 
        /*
-        * Obtain a sysunion structure from our per-cpu cache or allocate
-        * one.  This per-cpu cache may be accessed by interrupts returning
-        * a message.
+        * Obtain a sysmsg from our per-cpu cache or allocate a new one.  Use
+        * the opaque field to store the original (user) message pointer.
+        * A critical section is necessary to interlock against interrupts
+        * returning system messages to the thread cache.
         */
        crit_enter();
-       if ((sysmsg = TAILQ_FIRST(&mycpu->gd_sysmsgq)) != NULL) {
-               TAILQ_REMOVE(&mycpu->gd_sysmsgq, sysmsg, lmsg.ms_node);
-               crit_exit();
+       if ((sysmsg = mycpu->gd_freesysmsg) != NULL) {
+           mycpu->gd_freesysmsg = sysmsg->lmsg.opaque.ms_sysnext;
+           crit_exit();
        } else {
-               crit_exit();
-               sysmsg = malloc(sizeof(*sysmsg), M_SYSMSG, M_WAITOK);
+           crit_exit();
+           sysmsg = malloc(sizeof(*sysmsg), M_SYSMSG, M_WAITOK);
        }
+
+       /*
+        * Copy the user request in.  YYY if the userland lwkt_msg is
+        * different from the kernel lwkt_msg, this is where we deal with
+        * it.
+        */
        umsg = (void *)frame.tf_ecx;
        if ((error = copyin(umsg, sysmsg, msgsize)) != 0)
-               goto bad;
+               goto bad1;
 
-       code = sysmsg->lmsg.ms_cmd;
+       /*
+        * Initialize the parts of the message required for kernel sanity.
+        */
+       sysmsg->lmsg.opaque.ms_umsg = umsg;
+       sysmsg->lmsg.ms_reply_port = &td->td_msgport;
+       sysmsg->lmsg.ms_flags &= MSGF_ASYNC;
 
+       /*
+        * Extract the system call number, lookup the system call, and
+        * set the default return value.
+        */
+       code = (u_int)sysmsg->lmsg.ms_cmd;
        if (code >= p->p_sysent->sv_size) {
                error = ENOSYS;
-               goto bad;
+               goto bad1;
        }
 
        callp = &p->p_sysent->sv_table[code];
 
+       narg = (msgsize - sizeof(sysmsg->lmsg)) / sizeof(register_t);
+
 #ifdef KTRACE
        if (KTRPOINT(td, KTR_SYSCALL)) {
-               ktrsyscall(p->p_tracep, code, narg, (void *)(&args + 1));
+               ktrsyscall(p->p_tracep, code, narg, (void *)(&sysmsg->lmsg + 1));
        }
 #endif
        p->p_retval[0] = 0;
@@ -1455,19 +1480,33 @@ sendsys2(struct trapframe frame)
 
        /*
         * Make the system call.  An error code is always returned, results
-        * are copied back via ms_result32 or ms_result64.
+        * are copied back via ms_result32 or ms_result64.  YYY temporary
+        * stage copy p_retval[] into ms_result32/64
         *
         * NOTE!  XXX if this is a child returning from a fork curproc
-        * might be different.
+        * might be different.  YYY huh? a child returning from a fork
+        * should never 'return' from this call, it should go right to the
+        * fork_trampoline function.
         */
        error = (*callp->sy_call)(sysmsg);
 
+bad1:
        /*
-        * If a synchronous return copy p_retval to ms_result64.
+        * If a synchronous return copy p_retval to ms_result64 and return
+        * the sysmsg to the free pool.
         */
        if (error != EASYNC) {
-               error = copyout(p->p_retval, &umsg->ms_result64, sizeof(umsg->ms_result64));
+               crit_enter();
+               sysmsg->lmsg.opaque.ms_sysnext = mycpu->gd_freesysmsg;
+               mycpu->gd_freesysmsg = sysmsg;
+               crit_exit();
+               if (error == 0) {
+                       error = suword(&umsg->u.ms_result32 + 0, p->p_retval[0]);
+                       error = suword(&umsg->u.ms_result32 + 1, p->p_retval[1]);
+                       /*error = copyout(p->p_retval, &umsg->u.ms_result64, sizeof(umsg->u.ms_result64));*/
+               }
        }
+bad2:
        frame.tf_eax = error;
 
        /*
@@ -1506,8 +1545,6 @@ sendsys2(struct trapframe frame)
 #endif
 }
 
-#endif
-
 /*
  * Simplified back end of syscall(), used when returning from fork()
  * directly into user mode.  MP lock is held on entry and should be
index ac8b92b..fa3e18e 100644 (file)
@@ -2,7 +2,7 @@
  * System call switch table.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/kern/init_sysent.c,v 1.4 2003/07/24 01:41:24 dillon Exp $
+ * $DragonFly: src/sys/kern/init_sysent.c,v 1.5 2003/07/24 23:52:38 dillon Exp $
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
index 9bfc0e2..f457dc2 100644 (file)
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/kern/kern_device.c,v 1.2 2003/07/23 02:30:20 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_device.c,v 1.3 2003/07/24 23:52:38 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -88,7 +88,7 @@ cdevsw_putport(lwkt_port_t port, lwkt_msg_t lmsg)
 
     /*
      * Run the device switch function synchronously in the context of the
-     * caller and return a synchronous error code (anything not EINPROGRESS).
+     * caller and return a synchronous error code (anything not EASYNC).
      */
     switch(msg->am_lmsg.ms_cmd) {
     case CDEV_CMD_OPEN:
@@ -160,7 +160,7 @@ cdevsw_putport(lwkt_port_t port, lwkt_msg_t lmsg)
        error = ENOSYS;
        break;
     }
-    KKASSERT(error != EINPROGRESS);
+    KKASSERT(error != EASYNC);
     return(error);
 }
 
index 32bc92d..6d882b3 100644 (file)
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/kern/lwkt_msgport.c,v 1.2 2003/07/22 17:03:33 dillon Exp $
+ * $DragonFly: src/sys/kern/lwkt_msgport.c,v 1.3 2003/07/24 23:52:38 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -65,6 +65,13 @@ static void lwkt_replyport_remote(lwkt_msg_t msg);
 static void lwkt_putport_remote(lwkt_msg_t msg);
 static void lwkt_abortport_remote(lwkt_port_t port);
 
+void
+lwkt_initmsg_td(lwkt_msg_t msg, thread_t td)
+{
+    lwkt_initmsg(msg, 0);
+    msg->ms_reply_port = &td->td_msgport;
+}
+
 /*
  * lwkt_sendmsg()
  *
@@ -87,7 +94,7 @@ lwkt_sendmsg(lwkt_port_t port, lwkt_msg_t msg)
     msg->ms_flags &= ~(MSGF_REPLY | MSGF_QUEUED);
     msg->ms_reply_port = &curthread->td_msgport;
     msg->ms_abortreq = 0;
-    if ((error = lwkt_beginmsg(port, msg)) != EINPROGRESS) {
+    if ((error = lwkt_beginmsg(port, msg)) != EASYNC) {
        lwkt_replymsg(msg, error);
     }
 }
@@ -116,7 +123,7 @@ lwkt_domsg(lwkt_port_t port, lwkt_msg_t msg)
     msg->ms_flags &= ~(MSGF_ASYNC | MSGF_REPLY | MSGF_QUEUED);
     msg->ms_reply_port = &curthread->td_msgport;
     msg->ms_abortreq = 0;
-    if ((error = lwkt_beginmsg(port, msg)) == EINPROGRESS) {
+    if ((error = lwkt_beginmsg(port, msg)) == EASYNC) {
        error = lwkt_waitmsg(msg);
     }
     return(error);
@@ -253,7 +260,7 @@ lwkt_replyport(lwkt_port_t port, lwkt_msg_t msg)
  *     This function is typically assigned to the mp_beginmsg port vector.
  *
  *     Queue a message to the target port and wakeup the thread owning it.
- *     This function always returns EINPROGRESS and may be assigned to a
+ *     This function always returns EASYNC and may be assigned to a
  *     message port's mp_beginmsg function vector.
  */
 static
@@ -287,7 +294,7 @@ lwkt_putport(lwkt_port_t port, lwkt_msg_t msg)
     crit_enter();
     _lwkt_putport(port, msg);
     crit_exit();
-    return(EINPROGRESS);
+    return(EASYNC);
 }
 
 /*
index acdad61..6131cc2 100644 (file)
@@ -1,7 +1,7 @@
 #! /bin/sh -
 #      @(#)makesyscalls.sh     8.1 (Berkeley) 6/10/93
 # $FreeBSD: src/sys/kern/makesyscalls.sh,v 1.39.2.4 2001/10/20 09:01:24 marcel Exp $
-# $DragonFly: src/sys/kern/makesyscalls.sh,v 1.5 2003/07/24 01:41:25 dillon Exp $
+# $DragonFly: src/sys/kern/makesyscalls.sh,v 1.6 2003/07/24 23:52:38 dillon Exp $
 
 set -e
 
@@ -106,6 +106,8 @@ s/\$//g
                printf "/*\n * Union of syscall args for messaging.\n *\n" > sysun
                printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysun
                printf " * \$\DragonFly\$\n" > sysun
+               printf "\n#ifdef _KERNEL\n\n" > sysdcl
+               printf "\n#ifdef _KERNEL\n\n" > syscompatdcl
        }
        NR == 1 {
                gsub("[$]DragonFly: ", "", $0)
@@ -441,6 +443,7 @@ s/\$//g
                        printf "#endif\n" > sysinc
                }
 
+               printf("\n#endif /* _KERNEL */\n") > syscompatdcl
                printf("\n#endif /* %s */\n\n", compat) > syscompatdcl
                printf("#undef PAD_\n") > syscompatdcl
                printf("\n#endif /* !%s */\n", sysproto_h) > syscompatdcl
@@ -449,6 +452,7 @@ s/\$//g
                printf("};\n") > sysent
                printf("};\n") > sysnames
                printf("};\n") > sysun
+               printf("\n#endif /* _KERNEL */\n") > sysdcl
                printf("\ntypedef union sysunion *sysmsg_t;\n") > sysun
                printf("#define\t%sMAXSYSCALL\t%d\n", syscallprefix, syscall) \
                    > syshdr
index 6001abf..b0fc133 100644 (file)
@@ -2,7 +2,7 @@
  * System call names.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/kern/syscalls.c,v 1.4 2003/07/24 01:41:25 dillon Exp $
+ * $DragonFly: src/sys/kern/syscalls.c,v 1.5 2003/07/24 23:52:38 dillon Exp $
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
index 76b4089..9e959c4 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/i386/exception.s,v 1.65.2.3 2001/08/15 01:23:49 peter Exp $
- * $DragonFly: src/sys/platform/pc32/i386/exception.s,v 1.16 2003/07/24 01:41:16 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/exception.s,v 1.17 2003/07/24 23:52:36 dillon Exp $
  */
 
 #include "npx.h"
@@ -304,7 +304,6 @@ IDTVEC(int0x80_syscall)
        movl    $1,PCPU(intr_nesting_level)
        jmp     doreti
 
-#if 0
 /*
  * Trap gate entry for FreeBSD syscall messaging interface (int 0x81).
  * Arguments are passed in registers, the return value is placed in %eax.
@@ -338,8 +337,6 @@ IDTVEC(int0x81_syscall)
        movl    $1,PCPU(intr_nesting_level)
        jmp     doreti
 
-#endif
-
 /*
  * This function is what cpu_heavy_restore jumps to after a new process
  * is created.  The LWKT subsystem switches while holding a critical
index 460c428..2a2588b 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     from: @(#)machdep.c     7.4 (Berkeley) 6/3/91
  * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $
- * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.27 2003/07/24 01:41:16 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/machdep.c,v 1.28 2003/07/24 23:52:36 dillon Exp $
  */
 
 #include "apm.h"
@@ -1964,10 +1964,8 @@ init386(int first)
        setidt(19, &IDTVEC(xmm), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
        setidt(0x80, &IDTVEC(int0x80_syscall),
                        SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
-#if 0
        setidt(0x81, &IDTVEC(int0x81_syscall),
                        SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
-#endif
 
        r_idt.rd_limit = sizeof(idt0) - 1;
        r_idt.rd_base = (int) idt;
index 58f6136..68d8436 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     from: @(#)trap.c        7.4 (Berkeley) 5/13/91
  * $FreeBSD: src/sys/i386/i386/trap.c,v 1.147.2.11 2003/02/27 19:09:59 luoqi Exp $
- * $DragonFly: src/sys/platform/pc32/i386/trap.c,v 1.26 2003/07/24 01:41:16 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/trap.c,v 1.27 2003/07/24 23:52:36 dillon Exp $
  */
 
 /*
@@ -61,6 +61,7 @@
 #include <sys/sysent.h>
 #include <sys/uio.h>
 #include <sys/vmmeter.h>
+#include <sys/malloc.h>
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
@@ -166,6 +167,8 @@ static int slow_release;
 SYSCTL_INT(_machdep, OID_AUTO, slow_release, CTLFLAG_RW,
        &slow_release, 0, "Passive Release was nonoptimal");
 
+MALLOC_DEFINE(M_SYSMSG, "sysmsg", "sysmsg structure");
+
 /*
  * USER->KERNEL transition.  Do not transition us out of userland from the
  * point of view of the userland scheduler unless we actually have to
@@ -1359,8 +1362,6 @@ bad:
 #endif
 }
 
-#if 0  /* work in progress */
-
 /*
  *     sendsys2 -      MP aware system message request C handler
  */
@@ -1369,12 +1370,14 @@ sendsys2(struct trapframe frame)
 {
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
+       register_t orig_tf_eflags;
        struct sysent *callp;
-       sysunion_t sysmsg;
+       sysmsg_t sysmsg;
+       lwkt_msg_t umsg;
        u_quad_t sticks;
        int error;
        int narg;
-       u_int code;
+       u_int code = 0;
        int msgsize;
 
 #ifdef DIAGNOSTIC
@@ -1400,52 +1403,74 @@ sendsys2(struct trapframe frame)
        crit_exit();
 
        p->p_md.md_regs = &frame;
+       orig_tf_eflags = frame.tf_eflags;
 
        /*
         * Extract the system call message.  If msgsize is zero we are 
-        * blocking on a message and/or message port.
+        * blocking on a message and/or message port. YYY
         */
        if ((msgsize = frame.tf_edx) == 0) {
-               ... handle waiting ...
+               printf("waitport %08x msg %08x\n", frame.tf_eax, frame.tf_ecx);
+               error = ENOSYS;
+               goto bad2;
        }
 
        /*
         * Bad message size
         */
-       if (msgsize < 0 || msgsize > sizeof(*sysmsg)) {
+       if (msgsize < sizeof(struct lwkt_msg) || msgsize > sizeof(*sysmsg)) {
                error = ENOSYS;
-               goto bad;
+               goto bad2;
        }
 
        /*
-        * Obtain a sysunion structure from our per-cpu cache or allocate
-        * one.  This per-cpu cache may be accessed by interrupts returning
-        * a message.
+        * Obtain a sysmsg from our per-cpu cache or allocate a new one.  Use
+        * the opaque field to store the original (user) message pointer.
+        * A critical section is necessary to interlock against interrupts
+        * returning system messages to the thread cache.
         */
        crit_enter();
-       if ((sysmsg = TAILQ_FIRST(&mycpu->gd_sysmsgq)) != NULL) {
-               TAILQ_REMOVE(&mycpu->gd_sysmsgq, sysmsg, lmsg.ms_node);
-               crit_exit();
+       if ((sysmsg = mycpu->gd_freesysmsg) != NULL) {
+           mycpu->gd_freesysmsg = sysmsg->lmsg.opaque.ms_sysnext;
+           crit_exit();
        } else {
-               crit_exit();
-               sysmsg = malloc(sizeof(*sysmsg), M_SYSMSG, M_WAITOK);
+           crit_exit();
+           sysmsg = malloc(sizeof(*sysmsg), M_SYSMSG, M_WAITOK);
        }
+
+       /*
+        * Copy the user request in.  YYY if the userland lwkt_msg is
+        * different from the kernel lwkt_msg, this is where we deal with
+        * it.
+        */
        umsg = (void *)frame.tf_ecx;
        if ((error = copyin(umsg, sysmsg, msgsize)) != 0)
-               goto bad;
+               goto bad1;
 
-       code = sysmsg->lmsg.ms_cmd;
+       /*
+        * Initialize the parts of the message required for kernel sanity.
+        */
+       sysmsg->lmsg.opaque.ms_umsg = umsg;
+       sysmsg->lmsg.ms_reply_port = &td->td_msgport;
+       sysmsg->lmsg.ms_flags &= MSGF_ASYNC;
 
+       /*
+        * Extract the system call number, lookup the system call, and
+        * set the default return value.
+        */
+       code = (u_int)sysmsg->lmsg.ms_cmd;
        if (code >= p->p_sysent->sv_size) {
                error = ENOSYS;
-               goto bad;
+               goto bad1;
        }
 
        callp = &p->p_sysent->sv_table[code];
 
+       narg = (msgsize - sizeof(sysmsg->lmsg)) / sizeof(register_t);
+
 #ifdef KTRACE
        if (KTRPOINT(td, KTR_SYSCALL)) {
-               ktrsyscall(p->p_tracep, code, narg, (void *)(&args + 1));
+               ktrsyscall(p->p_tracep, code, narg, (void *)(&sysmsg->lmsg + 1));
        }
 #endif
        p->p_retval[0] = 0;
@@ -1455,19 +1480,33 @@ sendsys2(struct trapframe frame)
 
        /*
         * Make the system call.  An error code is always returned, results
-        * are copied back via ms_result32 or ms_result64.
+        * are copied back via ms_result32 or ms_result64.  YYY temporary
+        * stage copy p_retval[] into ms_result32/64
         *
         * NOTE!  XXX if this is a child returning from a fork curproc
-        * might be different.
+        * might be different.  YYY huh? a child returning from a fork
+        * should never 'return' from this call, it should go right to the
+        * fork_trampoline function.
         */
        error = (*callp->sy_call)(sysmsg);
 
+bad1:
        /*
-        * If a synchronous return copy p_retval to ms_result64.
+        * If a synchronous return copy p_retval to ms_result64 and return
+        * the sysmsg to the free pool.
         */
        if (error != EASYNC) {
-               error = copyout(p->p_retval, &umsg->ms_result64, sizeof(umsg->ms_result64));
+               crit_enter();
+               sysmsg->lmsg.opaque.ms_sysnext = mycpu->gd_freesysmsg;
+               mycpu->gd_freesysmsg = sysmsg;
+               crit_exit();
+               if (error == 0) {
+                       error = suword(&umsg->u.ms_result32 + 0, p->p_retval[0]);
+                       error = suword(&umsg->u.ms_result32 + 1, p->p_retval[1]);
+                       /*error = copyout(p->p_retval, &umsg->u.ms_result64, sizeof(umsg->u.ms_result64));*/
+               }
        }
+bad2:
        frame.tf_eax = error;
 
        /*
@@ -1506,8 +1545,6 @@ sendsys2(struct trapframe frame)
 #endif
 }
 
-#endif
-
 /*
  * Simplified back end of syscall(), used when returning from fork()
  * directly into user mode.  MP lock is held on entry and should be
index 60c47f7..3c26fc9 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)errno.h     8.5 (Berkeley) 1/21/94
  * $FreeBSD: src/sys/sys/errno.h,v 1.14.2.2 2002/01/22 10:46:56 keramida Exp $
- * $DragonFly: src/sys/sys/errno.h,v 1.2 2003/06/17 04:28:58 dillon Exp $
+ * $DragonFly: src/sys/sys/errno.h,v 1.3 2003/07/24 23:52:39 dillon Exp $
  */
 
 #ifndef _SYS_ERRNO_H_
@@ -168,7 +168,20 @@ __END_DECLS
 #define        EOVERFLOW       84              /* Value too large to be stored in data type */
 #define        ECANCELED       85              /* Operation canceled */
 #define        EILSEQ          86              /* Illegal byte sequence */
-#define        ELAST           86              /* Must be equal largest errno */
+#define ENOATTR                87              /* (from FreeBSD-5.x) */
+#define EDOOFUS                88              /* (from FreeBSD-5.x) */
+#define EUNUSED89      89
+#define EUNUSED90      90
+#define EUNUSED91      91
+#define EUNUSED92      92
+#define EUNUSED93      93
+#define EUNUSED94      94
+#define EUNUSED95      95
+#define EUNUSED96      96
+#define EUNUSED97      97
+#define EUNUSED98      98
+#define EASYNC         99
+#define        ELAST           99              /* Must be equal largest errno */
 
 #endif /* _POSIX_SOURCE */
 
index db14c56..4b10906 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/include/globaldata.h,v 1.11.2.1 2000/05/16 06:58:10 dillon Exp $
- * $DragonFly: src/sys/sys/globaldata.h,v 1.11 2003/07/12 17:54:36 dillon Exp $
+ * $DragonFly: src/sys/sys/globaldata.h,v 1.12 2003/07/24 23:52:39 dillon Exp $
  */
 
 #ifndef _SYS_GLOBALDATA_H_
@@ -69,6 +69,7 @@ struct globaldata {
        struct thread   *gd_curthread;
        int             gd_tdfreecount;         /* new thread cache */
        u_int32_t       gd_reqflags;            /* (see note above) */
+       union sysunion  *gd_freesysmsg;         /* free syscall messages */
        TAILQ_HEAD(,thread) gd_tdallq;          /* all threads */
        TAILQ_HEAD(,thread) gd_tdfreeq;         /* new thread cache */
        TAILQ_HEAD(,thread) gd_tdrunq[32];      /* runnable threads */
index 720add0..67d1fa9 100644 (file)
@@ -3,7 +3,7 @@
  *
  *     Implements LWKT messages and ports.
  * 
- * $DragonFly: src/sys/sys/msgport.h,v 1.3 2003/07/24 01:41:27 dillon Exp $
+ * $DragonFly: src/sys/sys/msgport.h,v 1.4 2003/07/24 23:52:39 dillon Exp $
  */
 
 #ifndef _SYS_MSGPORT_H_
@@ -31,6 +31,11 @@ typedef TAILQ_HEAD(lwkt_msg_queue, lwkt_msg) lwkt_msg_queue;
  */
 typedef struct lwkt_msg {
     TAILQ_ENTRY(lwkt_msg) ms_node;     /* link node (not always used) */
+    union {
+       struct lwkt_msg *ms_next;       /* chaining / cache */
+       union sysunion  *ms_sysnext;    /* chaining / cache */
+       struct lwkt_msg  *ms_umsg;      /* user message (UVA address) */
+    } opaque;
     lwkt_port_t ms_target_port;                /* only used in certain situations */
     lwkt_port_t        ms_reply_port;          /* asynch replies returned here */
     int                ms_abortreq;            /* set asynchronously */
@@ -69,6 +74,7 @@ typedef struct lwkt_port {
 #ifdef _KERNEL
 
 extern void lwkt_init_port(lwkt_port_t port, struct thread *td);
+extern void lwkt_initmsg_td(lwkt_msg_t msg, struct thread *td);
 extern void lwkt_sendmsg(lwkt_port_t port, lwkt_msg_t msg);
 extern int lwkt_domsg(lwkt_port_t port, lwkt_msg_t msg);
 extern int lwkt_waitmsg(lwkt_msg_t msg);
index 1260105..b099d82 100644 (file)
@@ -2,7 +2,7 @@
  * System call hiders.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/sys/syscall-hide.h,v 1.4 2003/07/24 01:41:27 dillon Exp $
+ * $DragonFly: src/sys/sys/syscall-hide.h,v 1.5 2003/07/24 23:52:39 dillon Exp $
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
index 432f45a..3b292b2 100644 (file)
@@ -2,7 +2,7 @@
  * System call numbers.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/sys/syscall.h,v 1.4 2003/07/24 01:41:27 dillon Exp $
+ * $DragonFly: src/sys/sys/syscall.h,v 1.5 2003/07/24 23:52:39 dillon Exp $
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
index e24c1f9..ea790fa 100644 (file)
@@ -1,6 +1,6 @@
 # DragonFly system call names.
 # DO NOT EDIT-- this file is automatically generated.
-# $DragonFly: src/sys/sys/syscall.mk,v 1.4 2003/07/24 01:41:27 dillon Exp $
+# $DragonFly: src/sys/sys/syscall.mk,v 1.5 2003/07/24 23:52:39 dillon Exp $
 # created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
 MIASM =  \
        syscall.o \
index 151f9a0..7d36afa 100644 (file)
@@ -2,7 +2,7 @@
  * System call prototypes.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/sys/sysproto.h,v 1.4 2003/07/24 01:41:27 dillon Exp $
+ * $DragonFly: src/sys/sys/sysproto.h,v 1.5 2003/07/24 23:52:39 dillon Exp $
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
@@ -1256,6 +1256,9 @@ struct    sendfile_args {
        off_t * sbytes; char sbytes_[PAD_(off_t *)];
        int     flags;  char flags_[PAD_(int)];
 };
+
+#ifdef _KERNEL
+
 int    nosys __P((struct nosys_args *));
 void   sys_exit __P((struct sys_exit_args *));
 int    fork __P((struct fork_args *));
@@ -1488,6 +1491,8 @@ int       kqueue __P((struct kqueue_args *));
 int    kevent __P((struct kevent_args *));
 int    sendfile __P((struct sendfile_args *));
 
+#endif /* _KERNEL */
+
 #ifdef COMPAT_43
 
 struct ocreat_args {
@@ -1658,6 +1663,9 @@ struct    osendfile_args {
        off_t * sbytes; char sbytes_[PAD_(off_t *)];
        int     flags;  char flags_[PAD_(int)];
 };
+
+#ifdef _KERNEL
+
 int    ocreat __P((struct ocreat_args *));
 int    olseek __P((struct olseek_args *));
 int    ostat __P((struct ostat_args *));
@@ -1697,6 +1705,8 @@ int       ogetsockname __P((struct getsockname_args *));
 int    ogetdirentries __P((struct ogetdirentries_args *));
 int    osendfile __P((struct osendfile_args *));
 
+#endif /* _KERNEL */
+
 #endif /* COMPAT_43 */
 
 #undef PAD_
index d0912d9..3fb2ff3 100644 (file)
@@ -2,7 +2,7 @@
  * Union of syscall args for messaging.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $DragonFly: src/sys/sys/sysunion.h,v 1.1 2003/07/24 01:41:27 dillon Exp $
+ * $DragonFly: src/sys/sys/sysunion.h,v 1.2 2003/07/24 23:52:39 dillon Exp $
  * created from DragonFly: src/sys/kern/syscalls.master,v 1.2 2003/06/17 04:28:41 dillon Exp 
  */
 
index 3321e6c..b764c09 100644 (file)
@@ -4,7 +4,7 @@
  *     Implements the architecture independant portion of the LWKT 
  *     subsystem.
  * 
- * $DragonFly: src/sys/sys/thread.h,v 1.26 2003/07/22 17:03:34 dillon Exp $
+ * $DragonFly: src/sys/sys/thread.h,v 1.27 2003/07/24 23:52:39 dillon Exp $
  */
 
 #ifndef _SYS_THREAD_H_
@@ -26,6 +26,7 @@ struct lwkt_cpu_port;
 struct lwkt_rwlock;
 struct lwkt_msg;
 struct lwkt_port;
+union sysunion;
 
 typedef struct lwkt_queue      *lwkt_queue_t;
 typedef struct lwkt_token      *lwkt_token_t;