Add/remove process from kernel runqueue

2k views Asked by At

I am trying to add my own policy to the linux kernel scheduler. every process has int my_policy in his task_struct, and my demand is that only the process with the highest policy can run at a time(process without policy set i.e my_policy = -1 can run regularly). I tried to add/remove process from the runqueue accordingly every scheduler_tick(), and most of the time it works, but the other time it gets stuck!

This is my code: (inside the scheduler_tick() function)

struct task_struct *it;
int max_policy = -1;

for_each_task(it) {
    if (it->my_policy != -1 && (it->state == TASK_RUNNING || (it->state == TASK_UNINTERRUPTIBLE && it->is_waiting_policy == 1))) {
        if (it->my_policy > max_policy)
            max_policy = it->my_policy;
    }
}

if (max_policy > -1) {
    for_each_task(it) {
        /* don't look at process without policy */
        if (it->my_policy == -1)
            continue;
        if (it->state == TASK_RUNNING && it->my_policy < max_policy) {
            it->is_waiting_policy = 1;
            it->state = TASK_UNINTERRUPTIBLE;
            deactivate_task(it, rq);
        } else if (it->state == TASK_UNINTERRUPTIBLE && it->is_waiting_policy == 1 && it->my_policy == max_policy) {
            it->is_waiting_policy = 0;
            it->state = TASK_RUNNING;
            activate_task(it, rq);
        }
    }
}

Like I said, sometime it doesn't work :( What am I doing wrong? Thanks.

1

There are 1 answers

5
Paul Ogilvie On

I have gone through your logic. I have written some assumptions around it that you can check. The logic seems OK and either the currently running process will continue to run, or another process will be activated to run, however, in your logic it is possible that a task is activated before the currently running task is deactivated. That occurrs when the task to activate is before the task to deactivate in the for_each_task loop. How will activate_task handle this?

The assumptions are:

  • there is currently one process running (i.e. scheduled to use the CPU). (The logic lets this process continue to run if no other process has been determined to have a higher priority.)

  • all other processes have is_waiting_policy == 1.

  • it->state is {TASK_RUNNING | TASK_UNINTERRUPTIBLE }; there are no other states.