Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/usermode Reimplement userret() to also include AST ...



details:   https://anonhg.NetBSD.org/src/rev/d2d60ceae356
branches:  trunk
changeset: 772745:d2d60ceae356
user:      reinoud <reinoud%NetBSD.org@localhost>
date:      Sat Jan 14 21:45:28 2012 +0000

description:
Reimplement userret() to also include AST for preemption.

Note it would be nice if we could do the check "are we going to userland?" in
a less intrusive way.

diffstat:

 sys/arch/usermode/dev/cpu.c          |   6 ++-
 sys/arch/usermode/usermode/syscall.c |  15 +-------
 sys/arch/usermode/usermode/trap.c    |  60 ++++++++++++++++++++++++++++++++---
 3 files changed, 60 insertions(+), 21 deletions(-)

diffs (204 lines):

diff -r c4d8cce791b6 -r d2d60ceae356 sys/arch/usermode/dev/cpu.c
--- a/sys/arch/usermode/dev/cpu.c       Sat Jan 14 21:42:51 2012 +0000
+++ b/sys/arch/usermode/dev/cpu.c       Sat Jan 14 21:45:28 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.64 2012/01/14 17:42:51 reinoud Exp $ */
+/* $NetBSD: cpu.c,v 1.65 2012/01/14 21:45:28 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -30,7 +30,7 @@
 #include "opt_hz.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.64 2012/01/14 17:42:51 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.65 2012/01/14 21:45:28 reinoud Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -43,6 +43,7 @@
 #include <sys/mbuf.h>
 #include <sys/msgbuf.h>
 #include <sys/kmem.h>
+#include <sys/kernel.h>
 
 #include <dev/cons.h>
 
@@ -155,6 +156,7 @@
 cpu_need_resched(struct cpu_info *ci, int flags)
 {
        ci->ci_want_resched |= flags;
+       aston(ci);
 }
 
 void
diff -r c4d8cce791b6 -r d2d60ceae356 sys/arch/usermode/usermode/syscall.c
--- a/sys/arch/usermode/usermode/syscall.c      Sat Jan 14 21:42:51 2012 +0000
+++ b/sys/arch/usermode/usermode/syscall.c      Sat Jan 14 21:45:28 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: syscall.c,v 1.21 2012/01/14 17:42:52 reinoud Exp $ */
+/* $NetBSD: syscall.c,v 1.22 2012/01/14 21:45:28 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.21 2012/01/14 17:42:52 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.22 2012/01/14 21:45:28 reinoud Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -45,16 +45,6 @@
 #include <machine/thunk.h>
 #include <machine/machdep.h>
 
-
-void userret(struct lwp *l);
-
-void
-userret(struct lwp *l)
-{
-       /* invoke MI userret code */
-       mi_userret(l);
-}
-
 void
 child_return(void *arg)
 {
@@ -161,7 +151,6 @@
        }
        //thunk_printf_debug("end of syscall : return to userland\n");
 //if (code != 4) thunk_printf("userret() code %d\n", code);
-       userret(l);
 }
 
 
diff -r c4d8cce791b6 -r d2d60ceae356 sys/arch/usermode/usermode/trap.c
--- a/sys/arch/usermode/usermode/trap.c Sat Jan 14 21:42:51 2012 +0000
+++ b/sys/arch/usermode/usermode/trap.c Sat Jan 14 21:45:28 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.56 2012/01/14 17:42:52 reinoud Exp $ */
+/* $NetBSD: trap.c,v 1.57 2012/01/14 21:45:28 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <reinoud%netbsd.org@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.56 2012/01/14 17:42:52 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.57 2012/01/14 21:45:28 reinoud Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -50,6 +50,7 @@
 /* forwards and externals */
 void setup_signal_handlers(void);
 void stop_all_signal_handlers(void);
+void userret(struct lwp *l);
 
 static void mem_access_handler(int sig, siginfo_t *info, void *ctx);
 static void illegal_instruction_handler(int sig, siginfo_t *info, void *ctx);
@@ -62,6 +63,7 @@
 
 static stack_t sigstk;
 
+int astpending;
 
 void
 startlwp(void *arg)
@@ -203,6 +205,49 @@
 }
 
 
+/* ast and userret */
+void
+userret(struct lwp *l)
+{
+       struct pcb *pcb;
+       ucontext_t ucp, *nucp;
+       vaddr_t pc;
+       
+       KASSERT(l);
+
+       /* are we going back to userland? */
+       pcb = lwp_getpcb(l);
+       KASSERT(pcb);
+
+       /* where are we going back to ? */
+       thunk_getcontext(&ucp);
+       nucp = (ucontext_t *) ucp.uc_link;
+       pc = md_get_pc(nucp);
+
+       if (pc >= kmem_k_start)
+               return;
+
+       /* ok, going to userland, proceed! */
+       if (astpending) {
+               astpending = 0;
+
+               curcpu()->ci_data.cpu_ntrap++;
+#if 0
+               /* profiling */
+               if (l->l_pflag & LP_OWEUPC) {
+                       l->l_pflag &= ~LP_OWEUPC;
+                       ADDUPROF(l);
+               }
+#endif
+               /* allow a forced task switch */
+               if (l->l_cpu->ci_want_resched)
+                       preempt();
+       }
+
+       /* invoke MI userret code */
+       mi_userret(l);
+}
+
 /* signal handler switching to a illegal instruction context */
 static void
 illegal_instruction_handler(int sig, siginfo_t *info, void *ctx)
@@ -317,10 +362,11 @@
                (void *) pc, (void *) va);
 #endif
 
-       /* can pmap handle it? on its own? (r/m) */
+       /* can pmap handle it? on its own? (r/m) emulation */
        if (pmap_fault(vm_map->pmap, va, &atype)) {
 //             thunk_printf("pagefault leave (pmap)\n");
-               goto out;
+               /* no use doing anything else here */
+               goto out_quick;
        }
 
        /* ask UVM */
@@ -386,10 +432,11 @@
 #else
        trapsignal(l, &ksi);
 #endif
-       mi_userret(l);
 
 //     thunk_printf("pagefault leave\n");
 out:
+       userret(l);
+out_quick:
        thunk_seterrno(lwp_errno);
        pcb->pcb_errno = lwp_errno;
 }
@@ -410,6 +457,7 @@
        if (md_syscall_check_opcode(ucp)) {
                syscall();
 //             thunk_printf("illegal instruction leave\n");
+               userret(l);
                return;
        }
 
@@ -427,6 +475,6 @@
 #else
        trapsignal(l, &ksi);
 #endif
-       mi_userret(l);
+       userret(l);
 }
 



Home | Main Index | Thread Index | Old Index