title: How to modify task_struct in Linux Kernel 3.8.0
body: <p>I am currently working on a project involving modifying the way linux priorities are implemented.</p>
  
  <p>To do so I have :</p>
  
  <ul>
  <li><p><strong>a custom syscall</strong> : That modifies the task_struct of a process to change its priority</p></li>
  <li><p><strong>modified kernel/sched/fair.c</strong></p></li>
  <li><p><strong>modified the standard task_struct to add new fields</strong></p>
  
  <p>While the custom syscall works : it gets correctly called and prints to dmesg the <strong>fair.c</strong> file doesn't seem to take into account the changes.</p></li>
  </ul>
  
  <p><a href="http://lxr.free-electrons.com/source/kernel/sched/fair.c?v=3.8#L3833" rel="nofollow">original fair.c</a></p>
  
  <p>Changes to fair.c :</p>
  
  <pre><code> /*
    * 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-&gt;src_rq, p, 0);
           if (p-&gt;prio_per_cpu)
           {            
              p-&gt;rt_priority = p-&gt;smp_prio[env-&gt;dst_cpu];
              printk(KERN_EMERG "We are in move_task function");
           }
           set_task_cpu(p, env-&gt;dst_cpu);
           activate_task(env-&gt;dst_rq, p, 0);
           check_preempt_curr(env-&gt;dst_rq, p, 0);
   }
  </code></pre>
  
  <p>p->prio_per_cpu is set to 1 in the syscall, but move_task function doesn't seem to see it.</p>
  
  <p>The syscall :</p>
  
  <pre><code>/* 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-&gt;prio_per_cpu = 1;
   p-&gt;smp_prio = (char*) smp_prio;
   printk(KERN_EMERG "SMP priorities are correctly set \n");
   return 1;
  }
  </code></pre>
  
  <p>I get the syscall printk message.</p>
  
  <p>The <a href="http://lxr.free-electrons.com/source/include/linux/init_task.h?v=3.8#L150" rel="nofollow">original</a> task_struct</p>
  
  <p>The modified task_struct :</p>
  
  <pre><code>#define INIT_TASK(tsk)  \
   {                                                                       \
       .state          = 0,                                            \
       .stack          = &amp;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      = &amp;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,                         \
       },         
       [...]
  </code></pre>
  
  <p>When I modified move_task() to print a message unconditionally it did print that message.</p>
  
  <p>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.</p>
  
  <p>Why aren't the changes done by the custom syscall not effective in the move_task() function ? </p>
  
  <p>Thank you for any help!</p>