I am currently working on a project involving modifying the way linux priorities are implemented.
To do so I have :
a custom syscall : That modifies the task_struct of a process to change its priority
modified kernel/sched/fair.c
modified the standard task_struct to add new fields
While the custom syscall works : it gets correctly called and prints to dmesg the fair.c file doesn't seem to take into account the changes.
Changes to fair.c :
/*
* move_task - move a task from one runqueue to another runqueue.
* Both runqueues must be locked.
*/
static void move_task(struct task_struct *p, struct lb_env *env)
{
deactivate_task(env->src_rq, p, 0);
if (p->prio_per_cpu)
{
p->rt_priority = p->smp_prio[env->dst_cpu];
printk(KERN_EMERG "We are in move_task function");
}
set_task_cpu(p, env->dst_cpu);
activate_task(env->dst_rq, p, 0);
check_preempt_curr(env->dst_rq, p, 0);
}
p->prio_per_cpu is set to 1 in the syscall, but move_task function doesn't seem to see it.
The syscall :
/* system call to set the new field in
* task struct 'smp_prio' that allows
* one priority per processor on SMP machines
*/
asmlinkage long sys_set_smp_prio(pid_t pid, const char *smp_prio)
{
struct pid *pid_struct;
struct task_struct *p;
pid_struct = find_get_pid(pid);
p = pid_task(pid_struct,PIDTYPE_PID);
p->prio_per_cpu = 1;
p->smp_prio = (char*) smp_prio;
printk(KERN_EMERG "SMP priorities are correctly set \n");
return 1;
}
I get the syscall printk message.
The original task_struct
The modified task_struct :
#define INIT_TASK(tsk) \
{ \
.state = 0, \
.stack = &init_thread_info, \
.usage = ATOMIC_INIT(2), \
.flags = PF_KTHREAD, \
.prio_per_cpu = 0, \
.smp_prio = NULL, \
.prio = MAX_PRIO-20, \
.static_prio = MAX_PRIO-20, \
.normal_prio = MAX_PRIO-20, \
.policy = SCHED_NORMAL, \
.cpus_allowed = CPU_MASK_ALL, \
.nr_cpus_allowed= NR_CPUS, \
.mm = NULL, \
.active_mm = &init_mm, \
.se = { \
.group_node = LIST_HEAD_INIT(tsk.se.group_node), \
}, \
.rt = { \
.run_list = LIST_HEAD_INIT(tsk.rt.run_list), \
.time_slice = RR_TIMESLICE, \
},
[...]
When I modified move_task() to print a message unconditionally it did print that message.
I am sure move_task gets called with the task_struct argument of the thread modified by the syscall because I manually force thread migration by setting cpusets (bitmask) and move_task is the very bit of code that performs migration from one cpu to another.
Why aren't the changes done by the custom syscall not effective in the move_task() function ?
Thank you for any help!
if (p->prio_per_cpu)
to see what the value ofp->prio_per_cpu
is at the time of evaluation. If it is0
, it never gets to the print function. – ryykerdeactivate_task(env->src_rq, p, 0);
do top
? – ryykerp
is has local scope tosys_set_smp_prio()
True? – ryyker