Breaks up sys_resource_req (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 1 Mar 2012 00:17:07 +0000 (16:17 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 1 Mar 2012 00:34:04 +0000 (16:34 -0800)
sys_resource_req() did both a transition to _M as well as poking the
ksched.  This splits that into two separate syscalls.  At this point,
the way to do resource requests is to write into procdata and optionally
poke the ksched.

Reinstall your kernel header.

14 files changed:
kern/include/process.h
kern/include/ros/bits/syscall.h
kern/src/process.c
kern/src/resource.c
kern/src/schedule.c
kern/src/syscall.c
tests/mhello.c
tests/msr_cycling_vcores.c
user/c3po/threads/vcore.c
user/parlib/include/parlib.h
user/parlib/include/vcore.h
user/parlib/syscall.c
user/parlib/uthread.c
user/parlib/vcore.c

index c0f44d9..bfbb7b2 100644 (file)
@@ -73,8 +73,8 @@ void proc_run_s(struct proc *p);
 void __proc_run_m(struct proc *p);
 void proc_restartcore(void);
 void proc_destroy(struct proc *SAFE p);
-void __proc_switch_to_m(struct proc *p);
-void __proc_switch_to_s(struct proc *p); /* don't call this */
+void __proc_change_to_m(struct proc *p);
+void __proc_change_to_s(struct proc *p); /* don't call this */
 void __proc_yield_s(struct proc *p, struct trapframe *tf);
 void proc_yield(struct proc *SAFE p, bool being_nice);
 void proc_notify(struct proc *p, uint32_t vcoreid);
index b462388..45c67c4 100644 (file)
@@ -37,9 +37,9 @@
 #define SYS_notify                                     25
 #define SYS_self_notify                                26
 #define SYS_halt_core                          27
-
-/* ARSC call init */
 #define SYS_init_arsc                          28
+#define SYS_change_to_m                                29
+#define SYS_poke_ksched                                30
 
 /* Platform specific syscalls */
 #define SYS_serial_read                                75
index c71ebd1..6240825 100644 (file)
@@ -706,7 +706,7 @@ void proc_destroy(struct proc *p)
 /* Turns *p into an MCP.  Needs to be called from a local syscall of a RUNNING_S
  * process.  Currently, this ignores whether or not you are an _M already.  You
  * should hold the lock before calling. */
-void __proc_switch_to_m(struct proc *p)
+void __proc_change_to_m(struct proc *p)
 {
        int8_t state = 0;
        switch (p->state) {
@@ -766,7 +766,7 @@ void __proc_switch_to_m(struct proc *p)
 
 /* Old code to turn a RUNNING_M to a RUNNING_S, with the calling context
  * becoming the new 'thread0'.  Don't use this. */
-void __proc_switch_to_s(struct proc *p)
+void __proc_change_to_s(struct proc *p)
 {
        int8_t state = 0;
        printk("[kernel] trying to transition _M -> _S (deprecated)!\n");
index dfe23a2..27168b4 100644 (file)
@@ -103,18 +103,7 @@ error_t resource_req(struct proc *p, int type, size_t amt_wanted,
 
        switch (type) {
                case RES_CORES:
-                       spin_lock(&p->proc_lock);
-                       if (p->state == PROC_RUNNING_S) {
-                               __proc_switch_to_m(p);  /* will later be a separate syscall */
-                               /* tell the ksched about us */
-                               register_mcp(p);
-                               spin_unlock(&p->proc_lock);
-                       } else {
-                               /* _M */
-                               spin_unlock(&p->proc_lock);
-                               poke_ksched(p, RES_CORES); /* will be a separate syscall */
-                       }
-                       return 0;
+                       return -EFAIL;
                        break;
                case RES_MEMORY:
                        // not clear if we should be in RUNNABLE_M or not
index bd89a6a..63da8de 100644 (file)
@@ -166,6 +166,10 @@ void poke_ksched(struct proc *p, int res_type)
        /* Consider races with core_req called from other pokes or schedule */
        switch (res_type) {
                case RES_CORES:
+                       /* ignore core requests from non-mcps (note we have races if we ever
+                        * allow procs to switch back). */
+                       if (!__proc_is_mcp(p))
+                               break;
                        /* TODO: issues with whether or not they are RUNNING.  Need to
                         * change core_request / give_cores. */
                        core_request(p);
index 0386bf9..ba89259 100644 (file)
@@ -731,6 +731,37 @@ static int sys_halt_core(struct proc *p, unsigned int usec)
        return 0;
 }
 
+/* Changes a process into _M mode, or -EINVAL if it already is an mcp */
+static int sys_change_to_m(struct proc *p)
+{
+       int retval = 0;
+       spin_lock(&p->proc_lock);
+       if (!__proc_is_mcp(p)) {
+               /* Catch user bugs */
+               if (!p->procdata->res_req[RES_CORES].amt_wanted) {
+                       printk("[kernel] process needs to specify amt_wanted\n");
+                       p->procdata->res_req[RES_CORES].amt_wanted = 1;
+               }
+               __proc_change_to_m(p);
+               /* Tell the ksched about us */
+               register_mcp(p);
+       } else {
+               set_errno(EINVAL);
+               retval = -1;
+       }
+       spin_unlock(&p->proc_lock);
+       return retval;
+}
+
+/* Not sure what people will need.  For now, they can send in the resource they
+ * want.  Up to the ksched to support this, and other things (like -1 for all
+ * resources).  Might have this info go in via procdata instead. */
+static int sys_poke_ksched(struct proc *p, int res_type)
+{
+       poke_ksched(p, res_type);
+       return 0;
+}
+
 /************** Platform Specific Syscalls **************/
 
 //Read a buffer over the serial port
@@ -1347,6 +1378,8 @@ const static struct sys_table_entry syscall_table[] = {
 #ifdef __CONFIG_ARSC_SERVER__
        [SYS_init_arsc] = {(syscall_t)sys_init_arsc, "init_arsc"},
 #endif
+       [SYS_change_to_m] = {(syscall_t)sys_change_to_m, "change_to_m"},
+       [SYS_poke_ksched] = {(syscall_t)sys_poke_ksched, "poke_ksched"},
        [SYS_read] = {(syscall_t)sys_read, "read"},
        [SYS_write] = {(syscall_t)sys_write, "write"},
        [SYS_open] = {(syscall_t)sys_open, "open"},
index 7b532cc..088f586 100644 (file)
@@ -82,7 +82,6 @@ int main(int argc, char** argv)
                printf("Hello from vcore %d with temp addr = %p and temp = %p\n",
                       vcoreid, &temp, temp);
                printf("Multi-Goodbye, world, from PID: %d!\n", sys_getpid());
-               //retval = sys_resource_req(RES_CORES, 2, 0);
                printf("Requesting %d vcores\n", max_vcores() - 1);
                retval = vcore_request(max_vcores() - 1); /* since we already have 1 */
                //retval = vcore_request(5);
index ae59e35..eb71aea 100644 (file)
@@ -21,11 +21,10 @@ uint64_t begin = 0, end = 0;
 
 int main(int argc, char** argv)
 {
+       printf("Good chance this doesn't work anymore!\n");
        mcs_barrier_init(&b, max_vcores());
 
        vcore_request(max_vcores());
-       printf("not enough vcores, going to try it manually\n");
-       sys_resource_req(RES_CORES, max_vcores(), 1, REQ_SOFT);
        printf("We're screwed!\n");
 
        /* should never make it here */
@@ -49,7 +48,7 @@ void vcore_entry(void)
                        udelay(15000000);
                        printf("Proc %d requesting its cores again\n", getpid());
                        begin = read_tsc();
-                       sys_resource_req(RES_CORES, max_vcores(), 1, REQ_SOFT);
+                       vcore_request(max_vcores() - 1); /* since we already have 1 */
                        mcs_barrier_wait(&b, vcoreid);
                        end = read_tsc();
                        printf("Took %llu usec (%llu nsec) to get my yielded cores back.\n",
index 65bb95b..48524f5 100644 (file)
@@ -98,8 +98,8 @@ void vcore_startup()
        /* Jump into multi-core mode! */
        /* The next line of code that will run is inside vcore_entry().  When this
         * thread is resumed, it will continue directly after this call to
-        * vcore_request() */
-       vcore_request(1);
+        * vcore_change_to_m() */
+       vcore_change_to_m();
 }
 
 /**
index b8cc743..b4227b6 100644 (file)
@@ -52,6 +52,8 @@ int         sys_halt_core(unsigned int usec);
 void*          sys_init_arsc();
 int         sys_block(unsigned int usec);
 void        sys_change_vcore(uint32_t vcoreid, bool enable_my_notif);
+int         sys_change_to_m(void);
+int         sys_poke_ksched(int res_type);
 
 #endif // !ASSEMBLER
 
index 3308bbd..a05ecc7 100644 (file)
@@ -52,6 +52,7 @@ static inline struct preempt_data *vcpd_of(uint32_t vcoreid);
 static inline bool preempt_is_pending(uint32_t vcoreid);
 static inline bool __preempt_is_pending(uint32_t vcoreid);
 int vcore_init(void);
+void vcore_change_to_m(void);
 int vcore_request(long nr_new_vcores);
 void vcore_yield(bool preempt_pending);
 bool clear_notif_pending(uint32_t vcoreid);
index e340572..d835fa1 100644 (file)
@@ -148,3 +148,13 @@ void sys_change_vcore(uint32_t vcoreid, bool enable_my_notif)
 {
        ros_syscall(SYS_change_vcore, vcoreid, enable_my_notif, 0, 0, 0, 0);
 }
+
+int sys_change_to_m(void)
+{
+       return ros_syscall(SYS_change_to_m, 0, 0, 0, 0, 0, 0);
+}
+
+int sys_poke_ksched(int res_type)
+{
+       return ros_syscall(SYS_poke_ksched, res_type, 0, 0, 0, 0, 0);
+}
index d3c17af..00ec37d 100644 (file)
@@ -67,11 +67,7 @@ int uthread_lib_init(struct uthread *uthread)
        printd("[user] registered %08p (flags %08p) for preempt messages\n",
               preempt_ev_q, preempt_ev_q->ev_flags);
        /* Get ourselves into _M mode.  Could consider doing this elsewhere... */
-       while (!in_multi_mode()) {
-               vcore_request(1);
-               /* TODO: consider blocking */
-               cpu_relax();
-       }
+       vcore_change_to_m();
        return 0;
 }
 
index ae105d6..644d43f 100644 (file)
@@ -163,6 +163,18 @@ vcore_init_fail:
        return -1;
 }
 
+/* Helper, picks some sane defaults and changes the process into an MCP */
+void vcore_change_to_m(void)
+{
+       __procdata.res_req[RES_CORES].amt_wanted = 1;
+       __procdata.res_req[RES_CORES].amt_wanted_min = 1;       /* whatever */
+       assert(!in_multi_mode());
+       assert(!in_vcore_context());
+       assert(!sys_change_to_m());
+       assert(in_multi_mode());
+       assert(!in_vcore_context());
+}
+
 /* Returns -1 with errno set on error, or 0 on success.  This does not return
  * the number of cores actually granted (though some parts of the kernel do
  * internally).
@@ -252,17 +264,13 @@ try_handle_it:
        cmb();  /* force a reread of num_vcores() */
        /* Update amt_wanted if we now want *more* than what the kernel already
         * knows.  See notes in the func doc. */
-       if (nr_vcores_wanted > __procdata.res_req[RES_CORES].amt_wanted) {
+       if (nr_vcores_wanted > __procdata.res_req[RES_CORES].amt_wanted)
                __procdata.res_req[RES_CORES].amt_wanted = nr_vcores_wanted;
-               __procdata.res_req[RES_CORES].amt_wanted_min = 1;       /* whatever */
-       }
        /* If num_vcores isn't what we want, we can poke the ksched.  Due to some
         * races with yield, our desires may be old.  Not a big deal; any vcores
         * that pop up will just end up yielding (or get preempt messages.)  */
-       if (nr_vcores_wanted > num_vcores()) {
-               /* res_req just transitions to MCP or pokes the ksched now */
-               sys_resource_req(RES_CORES, nr_vcores_wanted, 1, 0);
-       }
+       if (nr_vcores_wanted > num_vcores())
+               sys_poke_ksched(RES_CORES);
        /* Unlock, (which lets someone else work), and check to see if more work
         * needs to be done.  If so, we'll make sure it gets handled. */
        atomic_set(&vc_req_being_handled, 0);   /* unlock, to allow others to try */