SMP - Changed prototype of sys_schedule()

- 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
This commit is contained in:
Tomas Hruby 2010-09-15 14:10:42 +00:00
parent c554aef0e1
commit 06b6e5624a
19 changed files with 104 additions and 38 deletions

View file

@ -676,6 +676,7 @@
#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 *
@ -1141,6 +1142,7 @@
# 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 */

View 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
{

View 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,

View 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)

View 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,

View 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);
/* 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);
}
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 */
rp->p_priority = priority;
rp->p_quantum_size_ms = quantum;
rp->p_cpu_time_left = ms_2_cpu_time(quantum);
RTS_UNSET(rp, RTS_NO_QUANTUM);
RTS_UNSET(p, RTS_NO_QUANTUM);
return OK;
}

View 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 {

View 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);
}

View 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;

View 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));
}

View 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));
}

View 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",

View file

@ -50,5 +50,7 @@ EXTERN int shutting_down;
EXTERN unsigned system_hz;
EXTERN struct machine machine; /* machine info */
#endif /* RS_GLO_H */

View 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) {

View 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. */

View file

@ -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 ||

View 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;

View 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;
}

View 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);
}