Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 5494
b: refs/heads/master
c: 3d483f4
h: refs/heads/master
v: v3
  • Loading branch information
Eric W. Biederman authored and Linus Torvalds committed Jul 29, 2005
1 parent 8fffa29 commit e796517
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 94d2ac66c12397e2ca7988dbf59f24a966d275cb
refs/heads/master: 3d483f47579461a4715db33c68ef8752e5a97a2d
63 changes: 63 additions & 0 deletions trunk/arch/x86_64/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,69 @@ void unlock_ipi_call_lock(void)
spin_unlock_irq(&call_lock);
}

/*
* this function sends a 'generic call function' IPI to one other CPU
* in the system.
*/
static void __smp_call_function_single (int cpu, void (*func) (void *info), void *info,
int nonatomic, int wait)
{
struct call_data_struct data;
int cpus = 1;

data.func = func;
data.info = info;
atomic_set(&data.started, 0);
data.wait = wait;
if (wait)
atomic_set(&data.finished, 0);

call_data = &data;
wmb();
/* Send a message to all other CPUs and wait for them to respond */
send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR);

/* Wait for response */
while (atomic_read(&data.started) != cpus)
cpu_relax();

if (!wait)
return;

while (atomic_read(&data.finished) != cpus)
cpu_relax();
}

/*
* smp_call_function_single - Run a function on another CPU
* @func: The function to run. This must be fast and non-blocking.
* @info: An arbitrary pointer to pass to the function.
* @nonatomic: Currently unused.
* @wait: If true, wait until function has completed on other CPUs.
*
* Retrurns 0 on success, else a negative status code.
*
* Does not return until the remote CPU is nearly ready to execute <func>
* or is or has executed.
*/

int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
int nonatomic, int wait)
{
/* prevent preemption and reschedule on another processor */
int me = get_cpu();
if (cpu == me) {
WARN_ON(1);
put_cpu();
return -EBUSY;
}
spin_lock_bh(&call_lock);
__smp_call_function_single(cpu, func, info, nonatomic, wait);
spin_unlock_bh(&call_lock);
put_cpu();
return 0;
}

/*
* this function sends a 'generic call function' IPI to all other CPUs
* in the system.
Expand Down
21 changes: 12 additions & 9 deletions trunk/arch/x86_64/kernel/smpboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,6 @@ static __cpuinit void sync_master(void *arg)
{
unsigned long flags, i;

if (smp_processor_id() != 0)
return;

go[MASTER] = 0;

local_irq_save(flags);
Expand Down Expand Up @@ -262,7 +259,7 @@ get_delta(long *rt, long *master)
return tcenter - best_tm;
}

static __cpuinit void sync_tsc(void)
static __cpuinit void sync_tsc(unsigned int master)
{
int i, done = 0;
long delta, adj, adjust_latency = 0;
Expand All @@ -276,9 +273,17 @@ static __cpuinit void sync_tsc(void)
} t[NUM_ROUNDS] __cpuinitdata;
#endif

printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n",
smp_processor_id(), master);

go[MASTER] = 1;

smp_call_function(sync_master, NULL, 1, 0);
/* It is dangerous to broadcast IPI as cpus are coming up,
* as they may not be ready to accept them. So since
* we only need to send the ipi to the boot cpu direct
* the message, and avoid the race.
*/
smp_call_function_single(master, sync_master, NULL, 1, 0);

while (go[MASTER]) /* wait for master to be ready */
no_cpu_relax();
Expand Down Expand Up @@ -322,16 +327,14 @@ static __cpuinit void sync_tsc(void)
printk(KERN_INFO
"CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, "
"maxerr %lu cycles)\n",
smp_processor_id(), boot_cpu_id, delta, rt);
smp_processor_id(), master, delta, rt);
}

static void __cpuinit tsc_sync_wait(void)
{
if (notscsync || !cpu_has_tsc)
return;
printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", smp_processor_id(),
boot_cpu_id);
sync_tsc();
sync_tsc(boot_cpu_id);
}

static __init int notscsync_setup(char *s)
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/asm-x86_64/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ extern int smp_num_siblings;
extern void smp_send_reschedule(int cpu);
extern void zap_low_mappings(void);
void smp_stop_cpu(void);
extern int smp_call_function_single(int cpuid, void (*func) (void *info),
void *info, int retry, int wait);

extern cpumask_t cpu_sibling_map[NR_CPUS];
extern cpumask_t cpu_core_map[NR_CPUS];
extern u8 phys_proc_id[NR_CPUS];
Expand Down

0 comments on commit e796517

Please sign in to comment.