Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 30211
b: refs/heads/master
c: 539eb11
h: refs/heads/master
i:
  30209: 26b60b2
  30207: 589ad07
v: v3
  • Loading branch information
john stultz authored and Linus Torvalds committed Jun 26, 2006
1 parent 431bc37 commit c655551
Show file tree
Hide file tree
Showing 11 changed files with 390 additions and 218 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: 8d016ef1380a2a9a5ca5742ede04334199868f82
refs/heads/master: 539eb11e6e904f2cd4f62908cc5e44d724879721
2 changes: 1 addition & 1 deletion trunk/arch/i386/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ extra-y := head.o init_task.o vmlinux.lds
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
pci-dma.o i386_ksyms.o i387.o bootflag.o \
quirks.o i8237.o topology.o alternative.o i8253.o
quirks.o i8237.o topology.o alternative.o i8253.o tsc.o

obj-y += cpu/
obj-y += timers/
Expand Down
10 changes: 6 additions & 4 deletions trunk/arch/i386/kernel/numaq.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,12 @@ int __init get_memcfg_numaq(void)
return 1;
}

static int __init numaq_dsc_disable(void)
static int __init numaq_tsc_disable(void)
{
printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
tsc_disable = 1;
if (num_online_nodes() > 1) {
printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
tsc_disable = 1;
}
return 0;
}
core_initcall(numaq_dsc_disable);
arch_initcall(numaq_tsc_disable);
1 change: 1 addition & 0 deletions trunk/arch/i386/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1575,6 +1575,7 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &dummy_con;
#endif
#endif
tsc_init();
}

static __init int add_pcspkr(void)
Expand Down
178 changes: 0 additions & 178 deletions trunk/arch/i386/kernel/timers/timer_tsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ static unsigned long hpet_last;
static struct timer_opts timer_tsc;
#endif

static inline void cpufreq_delayed_get(void);

int tsc_disable __devinitdata = 0;

static int use_tsc;
/* Number of usecs that the last interrupt was delayed */
static int delay_at_last_interrupt;
Expand Down Expand Up @@ -144,30 +140,6 @@ static unsigned long long monotonic_clock_tsc(void)
return base + cycles_2_ns(this_offset - last_offset);
}

/*
* Scheduler clock - returns current time in nanosec units.
*/
unsigned long long sched_clock(void)
{
unsigned long long this_offset;

/*
* In the NUMA case we dont use the TSC as they are not
* synchronized across all CPUs.
*/
#ifndef CONFIG_NUMA
if (!use_tsc)
#endif
/* no locking but a rare wrong value is not a big deal */
return jiffies_64 * (1000000000 / HZ);

/* Read the Time Stamp Counter */
rdtscll(this_offset);

/* return the value in ns */
return cycles_2_ns(this_offset);
}

static void delay_tsc(unsigned long loops)
{
unsigned long bclock, now;
Expand Down Expand Up @@ -231,136 +203,6 @@ static void mark_offset_tsc_hpet(void)
}
#endif


#ifdef CONFIG_CPU_FREQ
#include <linux/workqueue.h>

static unsigned int cpufreq_delayed_issched = 0;
static unsigned int cpufreq_init = 0;
static struct work_struct cpufreq_delayed_get_work;

static void handle_cpufreq_delayed_get(void *v)
{
unsigned int cpu;
for_each_online_cpu(cpu) {
cpufreq_get(cpu);
}
cpufreq_delayed_issched = 0;
}

/* if we notice lost ticks, schedule a call to cpufreq_get() as it tries
* to verify the CPU frequency the timing core thinks the CPU is running
* at is still correct.
*/
static inline void cpufreq_delayed_get(void)
{
if (cpufreq_init && !cpufreq_delayed_issched) {
cpufreq_delayed_issched = 1;
printk(KERN_DEBUG "Losing some ticks... checking if CPU frequency changed.\n");
schedule_work(&cpufreq_delayed_get_work);
}
}

/* If the CPU frequency is scaled, TSC-based delays will need a different
* loops_per_jiffy value to function properly.
*/

static unsigned int ref_freq = 0;
static unsigned long loops_per_jiffy_ref = 0;

#ifndef CONFIG_SMP
static unsigned long fast_gettimeoffset_ref = 0;
static unsigned int cpu_khz_ref = 0;
#endif

static int
time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
void *data)
{
struct cpufreq_freqs *freq = data;

if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE)
write_seqlock_irq(&xtime_lock);
if (!ref_freq) {
if (!freq->old){
ref_freq = freq->new;
goto end;
}
ref_freq = freq->old;
loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy;
#ifndef CONFIG_SMP
fast_gettimeoffset_ref = fast_gettimeoffset_quotient;
cpu_khz_ref = cpu_khz;
#endif
}

if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) ||
(val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
(val == CPUFREQ_RESUMECHANGE)) {
if (!(freq->flags & CPUFREQ_CONST_LOOPS))
cpu_data[freq->cpu].loops_per_jiffy = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
#ifndef CONFIG_SMP
if (cpu_khz)
cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new);
if (use_tsc) {
if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
set_cyc2ns_scale(cpu_khz);
}
}
#endif
}

end:
if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE)
write_sequnlock_irq(&xtime_lock);

return 0;
}

static struct notifier_block time_cpufreq_notifier_block = {
.notifier_call = time_cpufreq_notifier
};


static int __init cpufreq_tsc(void)
{
int ret;
INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL);
ret = cpufreq_register_notifier(&time_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
if (!ret)
cpufreq_init = 1;
return ret;
}
core_initcall(cpufreq_tsc);

#else /* CONFIG_CPU_FREQ */
static inline void cpufreq_delayed_get(void) { return; }
#endif

int recalibrate_cpu_khz(void)
{
#ifndef CONFIG_SMP
unsigned int cpu_khz_old = cpu_khz;

if (cpu_has_tsc) {
local_irq_disable();
init_cpu_khz();
local_irq_enable();
cpu_data[0].loops_per_jiffy =
cpufreq_scale(cpu_data[0].loops_per_jiffy,
cpu_khz_old,
cpu_khz);
return 0;
} else
return -ENODEV;
#else
return -ENODEV;
#endif
}
EXPORT_SYMBOL(recalibrate_cpu_khz);

static void mark_offset_tsc(void)
{
unsigned long lost,delay;
Expand Down Expand Up @@ -451,9 +293,6 @@ static void mark_offset_tsc(void)

clock_fallback();
}
/* ... but give the TSC a fair chance */
if (lost_count > 25)
cpufreq_delayed_get();
} else
lost_count = 0;
/* update the monotonic base value */
Expand Down Expand Up @@ -578,23 +417,6 @@ static int tsc_resume(void)
return 0;
}

#ifndef CONFIG_X86_TSC
/* disable flag for tsc. Takes effect by clearing the TSC cpu flag
* in cpu/common.c */
static int __init tsc_setup(char *str)
{
tsc_disable = 1;
return 1;
}
#else
static int __init tsc_setup(char *str)
{
printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, "
"cannot disable TSC.\n");
return 1;
}
#endif
__setup("notsc", tsc_setup);



Expand Down
Loading

0 comments on commit c655551

Please sign in to comment.