Use a kthread flag to save the address space
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 7 Dec 2015 20:46:42 +0000 (15:46 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 10 Dec 2015 15:40:20 +0000 (10:40 -0500)
Previously, it was assumed that ktasks never care about their address
space.  This is not true - some ktasks (full ktasks with names, RKMs,
things executing in the kernel on their own, etc) may want to send an
event.

Now, with this flag, we can fix switch_to for ktasks.

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

index 23fe481..f719d93 100644 (file)
@@ -27,8 +27,9 @@ 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_SAVE_ADDR_SPACE            (1 << 1)
 #define KTH_KTASK_FLAGS                        (KTH_IS_KTASK)
-#define KTH_DEFAULT_FLAGS (0)
+#define KTH_DEFAULT_FLAGS              (KTH_SAVE_ADDR_SPACE)
 
 /* 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 c360f4f..193a6af 100644 (file)
@@ -366,16 +366,18 @@ void sem_down(struct semaphore *sem)
 #endif /* CONFIG_KTHREAD_POISON */
        /* Kthreads that are ktasks are not related to any process, and do not need
         * to work in a process's address space.  They can operate in any address
-        * space that has the kernel mapped (like boot_pgdir, or any pgdir).
+        * space that has the kernel mapped (like boot_pgdir, or any pgdir).  Some
+        * ktasks may switch_to, at which point they do care about the address
+        * space and must maintain a reference.
         *
-        * Other kthreads need to stay in the process context (if there is one), but
-        * we want the core (which could be a vcore) to stay in the context too.  In
-        * 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. */
-       if (!is_ktask(kthread)) {
+        * 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) {
                kthread->proc = current;
-               if (kthread->proc)      /* still could be none, like during init */
-                       proc_incref(kthread->proc, 1);
+               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. */
+               proc_incref(kthread->proc, 1);
        } else {
                kthread->proc = 0;
        }