Kthreads track cur_sysc and cur_errbuf
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 3 Oct 2013 02:33:38 +0000 (19:33 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 16 Jan 2014 02:17:54 +0000 (18:17 -0800)
Instead of having them sit in pcpui, then copying them to the kthread,
we just put them directly in the kthread.  This matches their intent.
Using pcpui was more of a hack back when we didn't have kthreads at all
times.

Note that set_errno() can be called before we have a kthread set up,
hence the need to check for its existence.

kern/include/smp.h
kern/src/arsc.c
kern/src/kthread.c
kern/src/process.c
kern/src/smp.c
kern/src/syscall.c

index 7b7f765..7a32892 100644 (file)
@@ -37,8 +37,6 @@ struct per_cpu_info {
        struct user_context actual_ctx; /* storage for cur_ctx */
        uint32_t __ctx_depth;           /* don't access directly.  see trap.h. */
        int __lock_checking_enabled;/* == 1, enables spinlock depth checking */
-       struct syscall *cur_sysc;       /* ptr is into cur_proc's address space */
-       void *cur_errbuf;                       /* ptr to current err stack buffer */
        struct kthread *cur_kthread;/* tracks the running kernel context */
        struct kthread *spare;          /* useful when restarting */
        struct timer_chain tchain;      /* for the per-core alarm */
index 424f463..acda958 100644 (file)
@@ -111,7 +111,7 @@ static intreg_t process_generic_syscalls(struct proc *p, size_t max)
                // this assumes we get our answer immediately for the syscall.
                syscall_req_t* req = RING_GET_REQUEST(sysbr, ++sysbr->req_cons);
                
-               pcpui->cur_sysc = req->sc;
+               pcpui->cur_kthread->sysc = req->sc;
                run_local_syscall(req->sc); // TODO: blocking call will block arcs as well.
                
                // need to keep the slot in the ring buffer if it is blocked
index b787e57..11ed469 100644 (file)
@@ -78,6 +78,7 @@ void restart_kthread(struct kthread *kthread)
        }
        current_kthread = pcpui->cur_kthread;
        current_stacktop = current_kthread->stacktop;
+       assert(!current_kthread->sysc); /* catch bugs, prev user should clear */
        /* Set the spare stuff (current kthread, which includes its stacktop) */
        pcpui->spare = current_kthread;
        /* When a kthread runs, its stack is the default kernel stack */
@@ -104,10 +105,6 @@ void restart_kthread(struct kthread *kthread)
                /* We also transfer our counted ref from kthread->proc to cur_proc */
                pcpui->cur_proc = kthread->proc;
        }
-       /* Tell the core which syscall we are running (if any) */
-       assert(!pcpui->cur_sysc);       /* catch bugs, prev user should clear */
-       pcpui->cur_sysc = kthread->sysc;
-       pcpui->cur_errbuf = kthread->errbuf;
        /* Finally, restart our thread */
        pop_kernel_ctx(&kthread->context);
 }
@@ -272,11 +269,6 @@ void sem_down(struct semaphore *sem)
         * the future, we could check owning_proc. If it isn't set, we could leave
         * the process context and transfer the refcnt to kthread->proc. */
        kthread->proc = current;
-       /* kthread tracks the syscall it is working on, which implies errno */
-       kthread->sysc = pcpui->cur_sysc;
-       kthread->errbuf = pcpui->cur_errbuf;
-       pcpui->cur_sysc = 0;                            /* this core no longer works on sysc */
-       pcpui->cur_errbuf = 0;                          /* this core no longer has an errbuf */
        if (kthread->proc)
                proc_incref(kthread->proc, 1);
        /* Save the context, toggle blocking for the reactivation */
index 04daab8..0527f3e 100644 (file)
@@ -643,7 +643,7 @@ void __proc_startcore(struct proc *p, struct user_context *ctx)
 void proc_restartcore(void)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
-       assert(!pcpui->cur_sysc);
+       assert(!pcpui->cur_kthread->sysc);
        /* TODO: can probably remove this enable_irq.  it was an optimization for
         * RKMs */
        /* Try and get any interrupts before we pop back to userspace.  If we didn't
@@ -1628,8 +1628,8 @@ void abandon_core(void)
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
        /* Syscalls that don't return will ultimately call abadon_core(), so we need
         * to make sure we don't think we are still working on a syscall. */
-       pcpui->cur_sysc = 0;
-       pcpui->cur_errbuf = 0;  /* just in case */
+       pcpui->cur_kthread->sysc = 0;
+       pcpui->cur_kthread->errbuf = 0; /* just in case */
        if (pcpui->cur_proc)
                __abandon_core();
 }
index 0ae15b8..8797bd1 100644 (file)
@@ -35,7 +35,7 @@ static void try_run_proc(void)
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
        /* There was a process running here, and we should return to it. */
        if (pcpui->owning_proc) {
-               assert(!pcpui->cur_sysc);
+               assert(!pcpui->cur_kthread->sysc);
                assert(pcpui->cur_ctx);
                __proc_startcore(pcpui->owning_proc, pcpui->cur_ctx);
                assert(0);
index 0991245..9c8e494 100644 (file)
@@ -88,9 +88,9 @@ static void finish_sysc(struct syscall *sysc, struct proc *p)
 static void finish_current_sysc(int retval)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
-       assert(pcpui->cur_sysc);
-       pcpui->cur_sysc->retval = retval;
-       finish_sysc(pcpui->cur_sysc, pcpui->cur_proc);
+       assert(pcpui->cur_kthread->sysc);
+       pcpui->cur_kthread->sysc->retval = retval;
+       finish_sysc(pcpui->cur_kthread->sysc, pcpui->cur_proc);
 }
 
 /* Callable by any function while executing a syscall (or otherwise, actually).
@@ -98,8 +98,8 @@ static void finish_current_sysc(int retval)
 void set_errno(int errno)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
-       if (pcpui->cur_sysc)
-               pcpui->cur_sysc->err = errno;
+       if (pcpui->cur_kthread && pcpui->cur_kthread->sysc)
+               pcpui->cur_kthread->sysc->err = errno;
 }
 
 void set_errstr(char *fmt, ...)
@@ -107,33 +107,33 @@ void set_errstr(char *fmt, ...)
        va_list ap;
        int rc;
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
-       if (!pcpui->cur_sysc)
+       if (!pcpui->cur_kthread || !pcpui->cur_kthread->sysc)
                return;
        va_start(ap, fmt);
-       rc = vsnprintf(pcpui->cur_sysc->errstr, MAX_ERRSTR_LEN, fmt, ap);
+       rc = vsnprintf(pcpui->cur_kthread->sysc->errstr, MAX_ERRSTR_LEN, fmt, ap);
        va_end(ap);
        /* TODO: likely not needed */
-       pcpui->cur_sysc->errstr[MAX_ERRSTR_LEN - 1] = '\0';
+       pcpui->cur_kthread->sysc->errstr[MAX_ERRSTR_LEN - 1] = '\0';
 }
 
 char *current_errstr(void)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
        /* no one should call this that doesn't have a sysc */
-       assert(!pcpui->cur_sysc);
-       return pcpui->cur_sysc->errstr;
+       assert(pcpui->cur_kthread->sysc);
+       return pcpui->cur_kthread->sysc->errstr;
 }
 
 struct errbuf *get_cur_errbuf(void)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
-       return (struct errbuf*)pcpui->cur_errbuf;
+       return (struct errbuf*)pcpui->cur_kthread->errbuf;
 }
 
 void set_cur_errbuf(struct errbuf *ebuf)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
-       pcpui->cur_errbuf = ebuf;
+       pcpui->cur_kthread->errbuf = ebuf;
 }
 
 /************** Utility Syscalls **************/
@@ -407,8 +407,8 @@ static int sys_proc_yield(struct proc *p, bool being_nice)
        /* proc_yield() often doesn't return - we need to set the syscall retval
         * early.  If it doesn't return, it expects to eat our reference (for now).
         */
-       finish_sysc(pcpui->cur_sysc, pcpui->cur_proc);
-       pcpui->cur_sysc = 0;    /* don't touch sysc again */
+       finish_sysc(pcpui->cur_kthread->sysc, pcpui->cur_proc);
+       pcpui->cur_kthread->sysc = 0;   /* don't touch sysc again */
        proc_incref(p, 1);
        proc_yield(p, being_nice);
        proc_decref(p);
@@ -1780,7 +1780,7 @@ void run_local_syscall(struct syscall *sysc)
        if (!user_mem_check(pcpui->cur_proc, sysc, sizeof(struct syscall),
                            sizeof(uintptr_t), PTE_USER_RW))
                return;
-       pcpui->cur_sysc = sysc;                 /* let the core know which sysc it is */
+       pcpui->cur_kthread->sysc = sysc;        /* let the core know which sysc it is */
        sysc->retval = syscall(pcpui->cur_proc, sysc->num, sysc->arg0, sysc->arg1,
                               sysc->arg2, sysc->arg3, sysc->arg4, sysc->arg5);
        /* Need to re-load pcpui, in case we migrated */
@@ -1791,7 +1791,7 @@ void run_local_syscall(struct syscall *sysc)
                sysc->err = EUNSPECIFIED;
        finish_sysc(sysc, pcpui->cur_proc);
        /* Can unpin (UMEM) at this point */
-       pcpui->cur_sysc = 0;    /* no longer working on sysc */
+       pcpui->cur_kthread->sysc = 0;   /* no longer working on sysc */
 }
 
 /* A process can trap and call this function, which will set up the core to