我目前正致力于一个涉及修改linux优先级实现方式的项目。
为此,我有:
自定义系统调用:修改进程的task_struct以更改其优先级
修改了kernel / 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消息。
original 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 使用syscall修改的线程的task_struct参数调用,因为我通过设置cpusets(bitmask)手动强制执行线程迁移,而move_task是执行从一个cpu到另一个cpu的迁移的代码。
为什么自定义系统调用所做的更改在move_task()函数中无效?
感谢您的帮助!
答案 0 :(得分:0)
此函数中本地定义的struct task_struct *p;
:
asmlinkage long sys_set_smp_prio(pid_t pid, const char *smp_prio)
{
struct pid *pid_struct;
struct task_struct *p; //THIS COPY OF task_struct *p HAS NO CONNECTION...
pid_struct = find_get_pid(pid);
task = 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;
}
与传递struct task_struct *p
的参数(至少在提供的代码中)没有明显的关系
static void move_task(struct task_struct *p, struct lb_env *env) //TO THIS ONE
{
deactivate_task(env->src_rq, p, 0);
if (p->prio_per_cpu) //If this value is zero, printk will never be called.
{
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);
}
也就是说,我没有在move_task()
内看到sys_set_smp_prio()
与p->prio_per_cpu = 1;
的更新值。这可能是问题吗?
答案 1 :(得分:0)
我很久以前就找到了解决方案,但仅仅是为了记录:我正在使用实时线程测试这个新的内核工具。它们不是由CFS调度程序(fair.c)安排的