Rename RCU CB context to 'cannot block' context
[akaros.git] / kern / src / kthread.c
index e1010ca..ea56d27 100644 (file)
@@ -127,6 +127,8 @@ void restart_kthread(struct kthread *kthread)
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
        uintptr_t current_stacktop;
        struct kthread *cur_kth;
+       struct proc *old_proc;
+
        /* Avoid messy complications.  The kthread will enable_irqsave() when it
         * comes back up. */
        disable_irq();
@@ -164,11 +166,12 @@ void restart_kthread(struct kthread *kthread)
                        lcr3(kthread->proc->env_cr3);
                        /* Might have to clear out an existing current.  If they need to be
                         * set later (like in restartcore), it'll be done on demand. */
-                       if (pcpui->cur_proc)
-                               proc_decref(pcpui->cur_proc);
+                       old_proc = pcpui->cur_proc;
                        /* Transfer our counted ref from kthread->proc to cur_proc. */
                        pcpui->cur_proc = kthread->proc;
                        kthread->proc = 0;
+                       if (old_proc)
+                               proc_decref(old_proc);
                }
        }
        /* Finally, restart our thread */
@@ -183,8 +186,6 @@ static void __launch_kthread(uint32_t srcid, long a0, long a1, long a2)
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
        struct proc *cur_proc = pcpui->cur_proc;
 
-       /* Make sure we are a routine kmsg */
-       assert(in_early_rkmsg_ctx(pcpui));
        if (pcpui->owning_proc && pcpui->owning_proc != kthread->proc) {
                /* Some process should be running here that is not the same as the
                 * kthread.  This means the _M is getting interrupted or otherwise
@@ -198,9 +199,7 @@ static void __launch_kthread(uint32_t srcid, long a0, long a1, long a2)
        }
        /* o/w, just run the kthread.  any trapframes that are supposed to run or
         * were interrupted will run whenever the kthread smp_idles() or otherwise
-        * finishes.  We also need to clear the RKMSG context since we will not
-        * return from restart_kth. */
-       clear_rkmsg(pcpui);
+        * finishes. */
        restart_kthread(kthread);
        assert(0);
 }
@@ -227,21 +226,13 @@ void kthread_runnable(struct kthread *kthread)
                            KMSG_ROUTINE);
 }
 
-/* Kmsg helper for kthread_yield */
-static void __wake_me_up(uint32_t srcid, long a0, long a1, long a2)
-{
-       struct semaphore *sem = (struct semaphore*)a0;
-       assert(sem_up(sem));
-}
-
 /* Stop the current kthread.  It'll get woken up next time we run routine kmsgs,
  * after all existing kmsgs are processed. */
 void kthread_yield(void)
 {
        struct semaphore local_sem, *sem = &local_sem;
        sem_init(sem, 0);
-       send_kernel_message(core_id(), __wake_me_up, (long)sem, 0, 0,
-                           KMSG_ROUTINE);
+       run_as_rkm(sem_up, sem);
        sem_down(sem);
 }
 
@@ -426,9 +417,8 @@ void sem_down(struct semaphore *sem)
         *
         * Normal kthreads need to stay in the process context, but we want the core
         * (which could be a vcore) to stay in the context too. */
-       if (kthread->flags & KTH_SAVE_ADDR_SPACE) {
+       if ((kthread->flags & KTH_SAVE_ADDR_SPACE) && current) {
                kthread->proc = current;
-               assert(kthread->proc);
                /* In the future, we could check owning_proc. If it isn't set, we could
                 * clear current and transfer the refcnt to kthread->proc.  If so, we'll
                 * need to reset the cr3 to something (boot_cr3 or owning_proc's cr3),