我目前正在从事一个涉及修改 linux 优先级实施方式的项目。
为此,我有:
自定义系统调用:修改进程的 task_struct 以更改其优先级
修改内核/sched/fair.c
修改了标准 task_struct 以添加新字段
虽然自定义系统调用有效:它被正确调用并打印到 dmesg,但fair.c文件似乎没有考虑到这些更改。
对 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 在系统调用中设置为 1,但 move_task 函数似乎看不到它。
系统调用:
/* 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;
}
我收到系统调用 printk 消息。
原来的task_struct
修改后的 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, \
},
[...]
当我修改 move_task() 以无条件地打印一条消息时,它确实打印了该消息。
我确信 move_task 会被系统调用修改的线程的 task_struct 参数调用,因为我通过设置 cpusets(位掩码)手动强制线程迁移,而 move_task 是执行从一个 cpu 迁移到另一个 cpu 的代码。
为什么自定义系统调用所做的更改在 move_task() 函数中无效?
感谢您的任何帮助!