一,一个cpu在另外一个cpu上运行指定的函数
int smp_call_function_single(int cpu, smp_call_func_t func, void *info, int wait)
smp_call_function_single()函数,在一个指导的cpu上运行一个函数。
} else {
if ((unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) {
struct call_single_data *csd = &d; //系统中每个CPU都有一个struct call_single_data结构
if (!wait)
csd = &__get_cpu_var(csd_data);
csd_lock(csd);
csd->func = func;
csd->info = info;
generic_exec_single(cpu, csd, wait); //挂到每cpu队列call_single_queue中,并向指定cpu发送IPI中断
} else {
err = -ENXIO; /* CPU not online */
}
}
void generic_exec_single(int cpu, struct call_single_data *csd, int wait)
{
//找到要运行该func的cpu的每cpu变量call_single_queue队列
struct call_single_queue *dst = &per_cpu(call_single_queue, cpu);
unsigned long flags;
int ipi;
raw_spin_lock_irqsave(&dst->lock, flags);
ipi = list_empty(&dst->list);//if empty return 1
//把该csd结构挂入每cpu变量call_single_queue队列尾部
list_add_tail(&csd->list, &dst->list);
raw_spin_unlock_irqrestore(&dst->lock, flags);
//队列为空,就向该cpu发送IPI中断,让其读取其每cpu队列call_single_queue上的csd结构,进而去执行func函数
if (ipi)
arch_send_call_function_single_ipi(cpu);
//若设置了等待标志,则进行等待
if (wait)
csd_lock_wait(csd);
}
static void csd_lock_wait(struct call_single_data *csd)
{
//若csd标志设置了CSD_FLAG_LOCK位,则在这里循环等待。前边并没有设置该标志
while (csd->flags & CSD_FLAG_LOCK)
cpu_relax();
}