]> Zhao Yanbai Git Server - minix.git/commitdiff
SMP - Changed prototype of sys_schedule()
authorTomas Hruby <tom@minix3.org>
Wed, 15 Sep 2010 14:10:42 +0000 (14:10 +0000)
committerTomas Hruby <tom@minix3.org>
Wed, 15 Sep 2010 14:10:42 +0000 (14:10 +0000)
- sys_schedule can change only selected values, -1 means that the
  current value should be kept unchanged. For instance we mostly want
  to change the scheduling quantum and priority but we want to keep
  the process at the current cpu

- RS can hand off its processes to scheduler

- service can read the destination cpu from system.conf

- RS can pass the information farther

19 files changed:
include/minix/com.h
include/minix/rs.h
include/minix/sched.h
include/minix/syslib.h
kernel/proto.h
kernel/system.c
kernel/system/do_schedctl.c
kernel/system/do_schedule.c
lib/libsys/sched_start.c
lib/libsys/sys_schedctl.c
lib/libsys/sys_schedule.c
servers/pm/schedule.c
servers/rs/glo.h
servers/rs/main.c
servers/rs/manager.c
servers/rs/request.c
servers/rs/type.h
servers/rs/utility.c
servers/sched/schedule.c

index 04fc74d9559603156c07076b0f6c778e5f7b3271..270e6406f89479f21f6cf451dd535248690437a5 100644 (file)
 #define SCHEDCTL_ENDPOINT      m9_l2   /* endpt of process to be scheduled */
 #define SCHEDCTL_QUANTUM       m9_l3   /* current scheduling quantum */
 #define SCHEDCTL_PRIORITY      m9_s4   /* current scheduling priority */
+#define SCHEDCTL_CPU           m9_l5   /* where to place this process */
 
 /*===========================================================================*
  *                Messages for the Reincarnation Server                     *
 #      define SCHEDULING_ENDPOINT      m9_l1
 #      define SCHEDULING_QUANTUM       m9_l2
 #      define SCHEDULING_PRIORITY      m9_s1
+#      define SCHEDULING_CPU           m9_l4
 
 /* SCHEDULING_START uses _ENDPOINT, _PRIORITY and _QUANTUM from
  * SCHEDULING_NO_QUANTUM */
index 5d64ff7565f79f078d78b95bc4c283d80c27f9e2..f0493dcad090d551ce569933dc8b19bf09f3e7c2 100644 (file)
@@ -33,6 +33,10 @@ Interface to the reincarnation server
 #define RS_NR_PCI_CLASS                 4
 #define RS_MAX_LABEL_LEN       16
 
+/* CPU special values */
+#define RS_CPU_DEFAULT         -1 /* use the default cpu or do not change the current one */
+#define RS_CPU_BSP             -2 /* use the bootstrap cpu */
+
 /* Labels are copied over separately. */
 struct rss_label
 {
index 6134f8a0c32c4c338ae9998add7eb7a926114acc..8a32e30a02feab171a1023bbc42ad6294f334ed0 100644 (file)
@@ -5,7 +5,7 @@
 
 _PROTOTYPE(int sched_stop, (endpoint_t scheduler_e, endpoint_t schedulee_e));
 _PROTOTYPE(int sched_start, (endpoint_t scheduler_e, endpoint_t schedulee_e, 
-       endpoint_t parent_e, unsigned maxprio, unsigned quantum,
+       endpoint_t parent_e, int maxprio, int quantum, int cpu,
        endpoint_t *newscheduler_e));
 _PROTOTYPE(int sched_inherit, (endpoint_t scheduler_e, 
        endpoint_t schedulee_e, endpoint_t parent_e, unsigned maxprio, 
index 36f4a33df5032870875f5459e79ea11fc969dba1..b1a3db1897d220da16719105aba262c6d9a1a145 100644 (file)
@@ -44,9 +44,10 @@ _PROTOTYPE( int sys_clear, (endpoint_t proc_ep));
 _PROTOTYPE( int sys_exit, (void));
 _PROTOTYPE( int sys_trace, (int req, endpoint_t proc_ep, long addr, long *data_p));
 
-_PROTOTYPE( int sys_schedule, (endpoint_t proc_ep, unsigned priority, unsigned quantum));
+_PROTOTYPE( int sys_schedule, (endpoint_t proc_ep, int priority,
+                                               int quantum, int cpu));
 _PROTOTYPE( int sys_schedctl, (unsigned flags, endpoint_t proc_ep,
-       unsigned priority, unsigned quantum));
+       int priority, int quantum, int cpu));
 
 /* Shorthands for sys_runctl() system call. */
 #define sys_stop(proc_ep) sys_runctl(proc_ep, RC_STOP, 0)
index 0ac33a28c2c9a90ee5fc98f95cb7486978d8e64a..aa2d4413d87cdc4a0763d6dc9da60b2b30ac2ca5 100644 (file)
@@ -84,7 +84,7 @@ _PROTOTYPE( void clear_ipc_refs, (struct proc *rc, int caller_ret)    );
 _PROTOTYPE( phys_bytes umap_bios, (vir_bytes vir_addr, vir_bytes bytes));
 _PROTOTYPE( void kernel_call_resume, (struct proc *p));
 _PROTOTYPE( int sched_proc, (struct proc *rp,
-       unsigned priority, unsigned quantum));
+       int priority, int quantum, int cpu));
 
 /* system/do_newmap.c */
 _PROTOTYPE( int newmap, (struct proc * caller, struct proc *rp,
index 3f18a3187090ca7c4c3ff231e22c38ebb573e9a0..6e02000dac243ad7f28080061fb702d7a1300d78 100644 (file)
@@ -638,29 +638,51 @@ PUBLIC void kernel_call_resume(struct proc *caller)
 /*===========================================================================*
  *                               sched_proc                                  *
  *===========================================================================*/
-PUBLIC int sched_proc(struct proc *rp, unsigned priority, unsigned quantum)
+PUBLIC int sched_proc(struct proc *p,
+                       int priority,
+                       int quantum,
+                       int cpu)
 {
-       /* Make sure the priority number given is within the allowed range.*/
-       if (priority < TASK_Q || priority > NR_SCHED_QUEUES)
-               return EINVAL;
+       /* Make sure the values given are within the allowed range.*/
+       if ((priority < TASK_Q && priority != -1) || priority > NR_SCHED_QUEUES)
+               return(EINVAL);
 
-       /* Make sure the quantum given is within the allowed range.*/
-       if(quantum <= 0)
-               return EINVAL;
+       if (quantum < 1 && quantum != -1)
+               return(EINVAL);
+
+       if ((cpu < 0 && cpu != -1) || (cpu > 0 && (unsigned) cpu >= ncpus))
+               return(EINVAL);
 
        /* In some cases, we might be rescheduling a runnable process. In such
         * a case (i.e. if we are updating the priority) we set the NO_QUANTUM
         * flag before the generic unset to dequeue/enqueue the process
         */
-       if (proc_is_runnable(rp))
-               RTS_SET(rp, RTS_NO_QUANTUM);
 
-       /* Clear the scheduling bit and enqueue the process */
-       rp->p_priority = priority;
-       rp->p_quantum_size_ms = quantum;
-       rp->p_cpu_time_left = ms_2_cpu_time(quantum);
+       /* FIXME this preempts the process, do we really want to do that ?*/
+
+       /* FIXME this is a problem for SMP if the processes currently runs on a
+        * different CPU */
+       if (proc_is_runnable(p) && p->p_cpu != cpuid &&
+                       (cpu != -1 || cpu != p->p_cpu)) {
+               printf("WARNING : changing cpu of a runnable process %d "
+                               "on a different cpu!\n", p->p_endpoint);
+               return(EINVAL);
+       }
 
-       RTS_UNSET(rp, RTS_NO_QUANTUM);
+       if (proc_is_runnable(p))
+               RTS_SET(p, RTS_NO_QUANTUM);
+
+       if (priority != -1)
+               p->p_priority = priority;
+       if (quantum != -1) {
+               p->p_quantum_size_ms = quantum;
+               p->p_cpu_time_left = ms_2_cpu_time(quantum);
+       }
+       if (cpu != -1)
+               p->p_cpu = cpu;
+
+       /* Clear the scheduling bit and enqueue the process */
+       RTS_UNSET(p, RTS_NO_QUANTUM);
 
        return OK;
 }
index 8a40e1e09ee7cf48306b50dfdc6b87807ee0af2f..b2e4563a3f522f014e3d6e0d2436a7ba702f861f 100644 (file)
@@ -8,7 +8,7 @@ PUBLIC int do_schedctl(struct proc * caller, message * m_ptr)
 {
        struct proc *p;
        unsigned flags;
-       unsigned priority, quantum;
+       int priority, quantum, cpu;
        int proc_nr;
        int r;
 
@@ -29,11 +29,12 @@ PUBLIC int do_schedctl(struct proc * caller, message * m_ptr)
                /* the kernel becomes the scheduler and starts 
                 * scheduling the process.
                 */
-               priority = (unsigned) m_ptr->SCHEDCTL_PRIORITY;
-               quantum = (unsigned) m_ptr->SCHEDCTL_QUANTUM;
+               priority = (int) m_ptr->SCHEDCTL_PRIORITY;
+               quantum = (int) m_ptr->SCHEDCTL_QUANTUM;
+               cpu = (int) m_ptr->SCHEDCTL_CPU;
 
                /* Try to schedule the process. */
-               if((r = sched_proc(p, priority, quantum) != OK))
+               if((r = sched_proc(p, priority, quantum, cpu) != OK))
                        return r;
                p->p_scheduler = NULL;
        } else {
index d4935c755d9c610c5bf3c047d4ecf69f7812bb36..436f8147dbc67ee68e3c40c01e78260f0912fd1b 100644 (file)
@@ -9,7 +9,7 @@ PUBLIC int do_schedule(struct proc * caller, message * m_ptr)
 {
        struct proc *p;
        int proc_nr;
-       unsigned priority, quantum;
+       int priority, quantum, cpu;
 
        if (!isokendpt(m_ptr->SCHEDULING_ENDPOINT, &proc_nr))
                return EINVAL;
@@ -21,7 +21,9 @@ PUBLIC int do_schedule(struct proc * caller, message * m_ptr)
                return(EPERM);
 
        /* Try to schedule the process. */
-       priority = (unsigned) m_ptr->SCHEDULING_PRIORITY;
-       quantum = (unsigned) m_ptr->SCHEDULING_QUANTUM;
-       return sched_proc(p, priority, quantum);
+       priority = (int) m_ptr->SCHEDULING_PRIORITY;
+       quantum = (int) m_ptr->SCHEDULING_QUANTUM;
+       cpu = (int) m_ptr->SCHEDULING_CPU;
+
+       return sched_proc(p, priority, quantum, cpu);
 }
index 4a41b013a0690e8e46c63211ffcd0298db8dc4af..0f8f2402de7a1ba07de5dae9c12b99dab7d020e1 100644 (file)
@@ -46,9 +46,13 @@ PUBLIC int sched_inherit(endpoint_t scheduler_e,
 /*===========================================================================*
  *                             sched_start                                  *
  *===========================================================================*/
-PUBLIC int sched_start(endpoint_t scheduler_e, endpoint_t schedulee_e, 
-       endpoint_t parent_e, unsigned maxprio, unsigned quantum,
-       endpoint_t *newscheduler_e)
+PUBLIC int sched_start(endpoint_t scheduler_e,
+                       endpoint_t schedulee_e, 
+                       endpoint_t parent_e,
+                       int maxprio,
+                       int quantum,
+                       int cpu,
+                       endpoint_t *newscheduler_e)
 {
        int rv;
        message m;
@@ -68,7 +72,7 @@ PUBLIC int sched_start(endpoint_t scheduler_e, endpoint_t schedulee_e,
        /* The KERNEL must schedule this process. */
        if(scheduler_e == KERNEL) {
                if ((rv = sys_schedctl(SCHEDCTL_FLAG_KERNEL, 
-                       schedulee_e, maxprio, quantum)) != OK) {
+                       schedulee_e, maxprio, quantum, cpu)) != OK) {
                        return rv;
                }
                *newscheduler_e = scheduler_e;
index 46ef5f1bbf4cbf5c4af167fe7f3d46f189101724..b7b975e4c8b6cb0a53ac1bb15c308668ec415d6c 100644 (file)
@@ -1,7 +1,10 @@
 #include "syslib.h"
 
-PUBLIC int sys_schedctl(unsigned flags, endpoint_t proc_ep, unsigned priority,
-       unsigned quantum)
+PUBLIC int sys_schedctl(unsigned flags,
+                       endpoint_t proc_ep,
+                       int priority,
+                       int quantum,
+                       int cpu)
 {
        message m;
 
@@ -9,5 +12,6 @@ PUBLIC int sys_schedctl(unsigned flags, endpoint_t proc_ep, unsigned priority,
        m.SCHEDCTL_ENDPOINT = proc_ep;
        m.SCHEDCTL_PRIORITY = priority;
        m.SCHEDCTL_QUANTUM = quantum;
+       m.SCHEDCTL_CPU = cpu;
        return(_kernel_call(SYS_SCHEDCTL, &m));
 }
index 94354ed96b461688c25657a1c0f741c91e677cf8..f7664c47c707eaacccacd2f8814205d3cb12ec3d 100644 (file)
@@ -1,11 +1,15 @@
 #include "syslib.h"
 
-PUBLIC int sys_schedule(endpoint_t proc_ep, unsigned priority, unsigned quantum)
+PUBLIC int sys_schedule(endpoint_t proc_ep,
+                       int priority,
+                       int quantum,
+                       int cpu)
 {
        message m;
 
        m.SCHEDULING_ENDPOINT = proc_ep;
        m.SCHEDULING_PRIORITY = priority;
        m.SCHEDULING_QUANTUM  = quantum;
+       m.SCHEDULING_CPU = cpu;
        return(_kernel_call(SYS_SCHEDULE, &m));
 }
index aa0d0bdf8477726e8ea7f64b0ed88ca06ba40a47..e94c20eb2599a21a02ce84edd9d71a142833097f 100644 (file)
@@ -39,6 +39,7 @@ PUBLIC void sched_init(void)
                                parent_e,               /* parent_e */
                                USER_Q,                 /* maxprio */
                                USER_QUANTUM,           /* quantum */
+                               -1,                     /* don't change cpu */
                                &trmp->mp_scheduler);   /* *newsched_e */
                        if (s != OK) {
                                printf("PM: SCHED denied taking over scheduling of %s: %d\n",
index d4db45227ddbf78adf85c51e731326a3879bc111..4c883ad21f76b1896f4783d7d172427058db2dc7 100644 (file)
@@ -50,5 +50,7 @@ EXTERN int shutting_down;
 
 EXTERN unsigned system_hz;
 
+EXTERN struct machine machine;         /* machine info */
+
 #endif /* RS_GLO_H */
 
index a5293e3faa7421b224693a43f5973936d97fe0c5..21bdedf835f2b6ffa271a7a15c24c0ac1738f140 100644 (file)
@@ -33,6 +33,7 @@ FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
 FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
 FORWARD _PROTOTYPE( int sef_cb_signal_manager, (endpoint_t target, int signo) );
 
+
 /*===========================================================================*
  *                             main                                         *
  *===========================================================================*/
@@ -46,9 +47,13 @@ PUBLIC int main(void)
   int ipc_status;                              /* status code */
   int call_nr, who_e,who_p;                    /* call number and caller */
   int result;                                  /* result to return */
+  int s;
 
   /* SEF local startup. */
   sef_local_startup();
+  
+  if (OK != (s=sys_getmachine(&machine)))
+         panic("couldn't get machine info: %d", s);
 
   /* Main loop - get work and do it, forever. */         
   while (TRUE) {              
index 3e778c0ec668a3050b1618a65f092b4ab9d8dd38..4897e8d1a15ab25990cb3449c0b421ddf0df6ed5 100644 (file)
@@ -1361,6 +1361,7 @@ endpoint_t source;
       rp->r_scheduler = rs_start->rss_scheduler;
       rp->r_priority = rs_start->rss_priority;
       rp->r_quantum = rs_start->rss_quantum;
+      rp->r_cpu = rs_start->rss_cpu;
   }
 
   /* Update command and arguments. */
index 0282a351002d96c020f05039bad5cdada1c07943..eccf60ed5566cb1693406408bf694ec6ee7be7a2 100755 (executable)
@@ -958,6 +958,18 @@ PRIVATE int check_request(struct rs_start *rs_start)
        return EINVAL;
   }
 
+  if (rs_start->rss_cpu == RS_CPU_BSP)
+         rs_start->rss_cpu = machine.bsp_id;
+  else if (rs_start->rss_cpu == RS_CPU_DEFAULT) {
+         /* keep the default value */
+  } else if (rs_start->rss_cpu < 0)
+         return EINVAL;
+  else if (rs_start->rss_cpu > machine.processors_count) {
+         printf("RS: cpu number %d out of range 0-%d, using BSP\n",
+                         rs_start->rss_cpu, machine.processors_count);
+         rs_start->rss_cpu = machine.bsp_id;
+  }
+
   /* Verify signal manager. */
   if (rs_start->rss_sigmgr != SELF && 
        (rs_start->rss_sigmgr < 0 || 
index b9eee86d070da12b9b9754abea72a1d81c5db788..8deb541e1a5d66661fde18eadbc6a34c20d69aad 100644 (file)
@@ -62,8 +62,9 @@ struct rproc {
                                 */
   uid_t r_uid;
   endpoint_t r_scheduler;      /* scheduler */
-  unsigned r_priority;
-  unsigned r_quantum;
+  int r_priority;              /* negative values are reserved for special meanings */
+  int r_quantum;
+  int r_cpu;
 
   char r_ipc_list[MAX_IPC_LIST];
   int r_nr_control;
index dbbedc2147ac312684d455de7a8af17a2fba6503..c32ecbd22b72ce6625ddcbd0fb6faeecc9e1f20f 100644 (file)
@@ -205,7 +205,7 @@ PUBLIC int sched_init_proc(struct rproc *rp)
 
   /* Start scheduling for the given process. */
   if ((s = sched_start(rp->r_scheduler, rp->r_pub->endpoint, 
-      RS_PROC_NR, rp->r_priority, rp->r_quantum, 
+      RS_PROC_NR, rp->r_priority, rp->r_quantum, rp->r_cpu,
       &rp->r_scheduler)) != OK) {
       return s;
   }
index 142cfad32da8230ce69e7a9f41b2d279bcbe42f9..97e9674f940af464ce9c635fb4c940ed47968561 100644 (file)
@@ -189,7 +189,7 @@ PUBLIC int do_start_scheduling(message *m_ptr)
 
        /* Take over scheduling the process. The kernel reply message populates
         * the processes current priority and its time slice */
-       if ((rv = sys_schedctl(0, rmp->endpoint, 0, 0)) != OK) {
+       if ((rv = sys_schedctl(0, rmp->endpoint, 0, 0, 0)) != OK) {
                printf("Sched: Error taking over scheduling for %d, kernel said %d\n",
                        rmp->endpoint, rv);
                return rv;
@@ -268,7 +268,7 @@ PRIVATE int schedule_process(struct schedproc * rmp)
        pick_cpu(rmp);
 
        if ((rv = sys_schedule(rmp->endpoint, rmp->priority,
-                       rmp->time_slice)) != OK) {
+                       rmp->time_slice, rmp->cpu)) != OK) {
                printf("SCHED: An error occurred when trying to schedule %d: %d\n",
                rmp->endpoint, rv);
        }