1

我目前正在从事一个涉及修改 linux 优先级实施方式的项目。

为此,我有:

  • 自定义系统调用:修改进程的 task_struct 以更改其优先级

  • 修改内核/sched/fair.c

  • 修改了标准 task_struct 以添加新字段

    虽然自定义系统调用有效:它被正确调用并打印到 dmesg,但fair.c文件似乎没有考虑到这些更改。

原创 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() 函数中无效?

感谢您的任何帮助!

4

2 回答 2

1

我很久以前就找到了解决方案,但只是为了记录:我正在使用实时线程测试这个新的内核设施。它们不是由 CFS 调度程序安排的 (fair.c)

于 2014-01-24T17:52:35.137 回答
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;. 这可能是问题吗?

于 2013-10-20T18:14:31.360 回答