Define a set of default flags for kthreads
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 7 Dec 2015 20:28:27 +0000 (15:28 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 10 Dec 2015 15:40:20 +0000 (10:40 -0500)
The default flags are those for general purpose kthreads: they handle user
space syscalls and IRQs while processes are running.  In contrast, a ktask
is a special case of a kthread.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/kthread.h
kern/src/kthread.c
kern/src/smp.c
kern/src/trap.c

index a31330f..23fe481 100644 (file)
@@ -27,6 +27,8 @@ TAILQ_HEAD(semaphore_tailq, semaphore);
 #define GENBUF_SZ 128  /* plan9 uses this as a scratch space, per syscall */
 
 #define KTH_IS_KTASK                   (1 << 0)
+#define KTH_KTASK_FLAGS                        (KTH_IS_KTASK)
+#define KTH_DEFAULT_FLAGS (0)
 
 /* This captures the essence of a kernel context that we want to suspend.  When
  * a kthread is running, we make sure its stacktop is the default kernel stack,
index cf9dbbd..c360f4f 100644 (file)
@@ -335,17 +335,16 @@ void sem_down(struct semaphore *sem)
                new_kthread = pcpui->spare;
                new_stacktop = new_kthread->stacktop;
                pcpui->spare = 0;
-               /* Based on how we set KTH_IS_KTASK (in PRKM), we'll usually have a
-                * spare with KTH_IS_KTASK set, even though the default setting is off.
-                * The reason is that the launching of blocked kthreads also uses PRKM,
-                * and that KMSG (__launch_kthread) doesn't return.  Thus the soon-to-be
-                * spare kthread, that is launching another, has flags & KTH_IS_KTASK
-                * set. */
-               new_kthread->flags = 0;
+               /* The old flags could have KTH_IS_KTASK set.  The reason is that the
+                * launching of blocked kthreads also uses PRKM, and that KMSG
+                * (__launch_kthread) doesn't return.  Thus the soon-to-be spare
+                * kthread, that is launching another, has flags & KTH_IS_KTASK set. */
+               new_kthread->flags = KTH_DEFAULT_FLAGS;
                new_kthread->proc = 0;
                new_kthread->name = 0;
        } else {
                new_kthread = __kthread_zalloc();
+               new_kthread->flags = KTH_DEFAULT_FLAGS;
                new_stacktop = get_kstack();
                new_kthread->stacktop = new_stacktop;
 #ifdef CONFIG_KTHREAD_POISON
index 6aec89d..12bbd6e 100644 (file)
@@ -61,8 +61,9 @@ static void try_run_proc(void)
 static void __attribute__((noinline, noreturn)) __smp_idle(void)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+
        clear_rkmsg(pcpui);
-       pcpui->cur_kthread->flags &= ~KTH_IS_KTASK;
+       pcpui->cur_kthread->flags = KTH_DEFAULT_FLAGS;
        enable_irq();   /* one-shot change to get any IRQs before we halt later */
        while (1) {
                disable_irq();
@@ -109,7 +110,7 @@ void smp_percpu_init(void)
        /* Treat the startup threads as ktasks.  This will last until smp_idle when
         * they clear it, either in anticipation of being a user-backing kthread or
         * to handle an RKM. */
-       kthread->flags |= KTH_IS_KTASK;
+       kthread->flags = KTH_KTASK_FLAGS;
        per_cpu_info[coreid].spare = 0;
        /* Init relevant lists */
        spinlock_init_irqsave(&per_cpu_info[coreid].immed_amsg_lock);
index 51b5eda..4c156af 100644 (file)
@@ -238,17 +238,14 @@ void process_routine_kmsg(void)
                 * it's not running on behalf of a process, and we're actually spawning
                 * a kernel task.  While we do have a syscall that does work in an RKM
                 * (change_to), it's not really the rest of the syscall context. */
-               pcpui->cur_kthread->flags |= KTH_IS_KTASK;
+               pcpui->cur_kthread->flags = KTH_KTASK_FLAGS;
                pcpui_trace_kmsg(pcpui, (uintptr_t)msg_cp.pc);
                msg_cp.pc(msg_cp.srcid, msg_cp.arg0, msg_cp.arg1, msg_cp.arg2);
-               /* And if we make it back, be sure to unset this.  If we never return,
-                * but the kthread exits via some other way (smp_idle()), then
-                * smp_idle() will deal with the flag.  The default state is "off".  For
-                * an example of an RKM that does this, check out the
-                * monitor->mon_bin_run.  Finally, if the kthread gets swapped out of
-                * pcpui, such as in __launch_kthread(), the next time the kthread is
-                * reused, KTH_IS_KTASK will be reset. */
-               pcpui->cur_kthread->flags &= ~KTH_IS_KTASK;
+               /* And if we make it back, be sure to restore the default flags.  If we
+                * never return, but the kthread exits via some other way (smp_idle()),
+                * then smp_idle() will deal with the flags.  The default state includes
+                * 'not a ktask'. */
+               pcpui->cur_kthread->flags = KTH_DEFAULT_FLAGS;
                /* If we aren't still in early RKM, it is because the KMSG blocked
                 * (thus leaving early RKM, finishing in default context) and then
                 * returned.  This is a 'detached' RKM.  Must idle in this scenario,