简体   繁体   中英

Why doesn't sched_setaffinity work as expected on kthread

There is only one kthread and I want to control it to run on specific CPU. Main process creates and wakes up kthread by kthread_create() and wake_up_process() function. When the kthread is created, maie process stores pid of the kthread at global variable. Let it called "thread_pid".

I create function to change the CPU of kthread. It looks like "int change_cpu(int cpu_to_change)". It uses sched_setaffinity() while passing parameter pid as "thread_pid". ie it calls like "sched_setaffinity(thread_pid, cpu_mask_to_change);". And it stores value of parameter "cpu_to_change" to global variable. Let it called "thread_cpu".

The kthread has assertion such as "ASSERT(smc_processor_id() == thread_cpu)". The kthread does not run instead wait for completion usually.

I expect that after change_cpu() function is called, the kthread works well without assertion fail. But it falls to assertion fail, even sched_setaffinity() works successfully. Why doesn't it works as expected? I want to know why this way doesn't work.

Here is dummy code for better understanding.

int thread_cpu;
int thread_pid;

int dummy_kthread(void *args)
{
  while(1) {
    wait_for_completion();

    ASSERT( smc_processor_id() == thread_cpu );

    '''
    do something
    '''

    complete();
  }
}

int change_cpu(int cpu_to_change)
{
  struct cpumask * cpu_mask;

  thread_cpu = cpu_to_change;
  cpu_mask = set_cpumask(cpu_to_change);  // this is not actually exist function.
  return sched_setaffinity(thread_pid, cpu_mask);
}

int main(){
  struct task_struct *dummy;

  dummy = kthread_create(dummy_kthread, NULL, "dummy_kthread");
  thread_pid = get_pid(dummy);  // this is not actually exist function.
}

One possible cause for sched_setaffinity() to appear not to be working correctly is linked to the dynamic power management of cores. When the core powers off, all of the threads running on that core will migrate away from that core. As a result, the cpumask will be updated accordingly.

In order to prevent cores from powering off, you need to choose "no" for HOTPLUG_CPU when configuring your kernel, or you can manually set the default value to 'n' in the Kconfig file (arch/[architecture]/Kconfig) before compiling your kernel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM