linux SMP系统学习笔记

一,一个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();
}


你可能感兴趣的:(linux内核)