📄 smp.c
字号:
/* * arch/sh/kernel/smp.c * * SMP support for the SuperH processors. * * Copyright (C) 2002, 2003 Paul Mundt * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */#include <linux/config.h>#include <linux/cache.h>#include <linux/cpumask.h>#include <linux/delay.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/spinlock.h>#include <linux/threads.h>#include <linux/module.h>#include <linux/time.h>#include <linux/timex.h>#include <linux/sched.h>#include <linux/module.h>#include <asm/atomic.h>#include <asm/processor.h>#include <asm/system.h>#include <asm/mmu_context.h>#include <asm/smp.h>/* * This was written with the Sega Saturn (SMP SH-2 7604) in mind, * but is designed to be usable regardless if there's an MMU * present or not. */struct sh_cpuinfo cpu_data[NR_CPUS];extern void per_cpu_trap_init(void);cpumask_t cpu_possible_map;EXPORT_SYMBOL(cpu_possible_map);cpumask_t cpu_online_map;static atomic_t cpus_booted = ATOMIC_INIT(0);/* These are defined by the board-specific code. *//* * Cause the function described by call_data to be executed on the passed * cpu. When the function has finished, increment the finished field of * call_data. */void __smp_send_ipi(unsigned int cpu, unsigned int action);/* * Find the number of available processors */unsigned int __smp_probe_cpus(void);/* * Start a particular processor */void __smp_slave_init(unsigned int cpu);/* * Run specified function on a particular processor. */void __smp_call_function(unsigned int cpu);static inline void __init smp_store_cpu_info(unsigned int cpu){ cpu_data[cpu].loops_per_jiffy = loops_per_jiffy;}void __init smp_prepare_cpus(unsigned int max_cpus){ unsigned int cpu = smp_processor_id(); int i; atomic_set(&cpus_booted, 1); smp_store_cpu_info(cpu); for (i = 0; i < __smp_probe_cpus(); i++) cpu_set(i, cpu_possible_map);}void __devinit smp_prepare_boot_cpu(void){ unsigned int cpu = smp_processor_id(); cpu_set(cpu, cpu_online_map); cpu_set(cpu, cpu_possible_map);}int __cpu_up(unsigned int cpu){ struct task_struct *tsk; tsk = fork_idle(cpu); if (IS_ERR(tsk)) panic("Failed forking idle task for cpu %d\n", cpu); tsk->thread_info->cpu = cpu; cpu_set(cpu, cpu_online_map); return 0;}int start_secondary(void *unused){ unsigned int cpu; cpu = smp_processor_id(); atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; smp_store_cpu_info(cpu); __smp_slave_init(cpu); preempt_disable(); per_cpu_trap_init(); atomic_inc(&cpus_booted); cpu_idle(); return 0;}void __init smp_cpus_done(unsigned int max_cpus){ smp_mb();}void smp_send_reschedule(int cpu){ __smp_send_ipi(cpu, SMP_MSG_RESCHEDULE);}static void stop_this_cpu(void *unused){ cpu_clear(smp_processor_id(), cpu_online_map); local_irq_disable(); for (;;) cpu_relax();}void smp_send_stop(void){ smp_call_function(stop_this_cpu, 0, 1, 0);}struct smp_fn_call_struct smp_fn_call = { .lock = SPIN_LOCK_UNLOCKED, .finished = ATOMIC_INIT(0),};/* * The caller of this wants the passed function to run on every cpu. If wait * is set, wait until all cpus have finished the function before returning. * The lock is here to protect the call structure. * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */int smp_call_function(void (*func)(void *info), void *info, int retry, int wait){ unsigned int nr_cpus = atomic_read(&cpus_booted); int i; if (nr_cpus < 2) return 0; /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); spin_lock(&smp_fn_call.lock); atomic_set(&smp_fn_call.finished, 0); smp_fn_call.fn = func; smp_fn_call.data = info; for (i = 0; i < nr_cpus; i++) if (i != smp_processor_id()) __smp_call_function(i); if (wait) while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1)); spin_unlock(&smp_fn_call.lock); return 0;}/* Not really SMP stuff ... */int setup_profiling_timer(unsigned int multiplier){ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -