One, one CPU runs the specified function on another CPU
int smp_call_function_single (int cpu, smp_call_func_t func, void *info, int wait) Smp_call_function_single () function,
Run a function on a guided CPU.
else {if ((unsigned) CPU < Nr_cpu_ids && Cpu_online (CPU)) { struct Call_single_data *CSD = &d;
Each CPU in the system has a struct call_single_data structure if (!wait)
CSD = &__get_cpu_var (csd_data);
Csd_lock (CSD);
Csd->func = func;
Csd->info = info; Generic_exec_single (CPU, CSD, wait);
Hang to the per-CPU queue Call_single_queue and send IPI interrupts to the specified CPU else { Err =-Enxio; /* CPU not online */} void Generic_exec_single (int cpu, struct call_s Ingle_data *CSD, int wait) {//find each CPU variable call_single_queue queue struct Call_single_queue *dst = &per_c for the CPU to run the Func
PU (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//hook the CSD structure to the tail call_single_queue queue of each CPU variable List_add_tail (&
Csd->list, &dst->list);
Raw_spin_unlock_irqrestore (&dst->lock, flags); If the queue is empty, it sends a IPI interrupt to the CPU to read its CSD structure on the call_single_queue of each CPU queue, thereby executing the Func function if (IPI) arch_send_call_function_single_i
Pi (CPU);
If the wait sign is set, wait for the IF (waiting) csd_lock_wait (CSD); static void csd_lock_wait (struct call_single_data *CSD) {//If the CSD flag is set to a csd_flag_lock bit, wait here to loop.
The flag while (Csd->flags & Csd_flag_lock) Cpu_relax () is not set at the front; }