Skip to content

Commit

Permalink
[CPUFREQ] CPU frequency display in /proc/cpuinfo
Browse files Browse the repository at this point in the history
What is the value shown in "cpu MHz" of /proc/cpuinfo when CPUs are capable of
changing frequency?

Today the answer is: It depends.
On i386:
SMP kernel - It is always the boot frequency
UP kernel - Scales with the frequency change and shows that was last set.

On x86_64:
There is one single variable cpu_khz that gets written by all the CPUs. So,
the frequency set by last CPU will be seen on /proc/cpuinfo of all the
CPUs in the system. What you see also depends on whether you have constant_tsc
capable CPU or not.

On ia64:
It is always boot time frequency of a particular CPU that gets displayed.

The patch below changes this to:
Show the last known frequency of the particular CPU, when cpufreq is present. If
cpu doesnot support changing of frequency through cpufreq, then boot frequency
will be shown. The patch affects i386, x86_64 and ia64 architectures.

Signed-off-by: Venkatesh Pallipadi<[email protected]>
Signed-off-by: Dave Jones <[email protected]>
  • Loading branch information
Venkatesh Pallipadi authored and Dave Jones committed Dec 7, 2005
1 parent 9a7d82a commit 95235ca
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 3 deletions.
6 changes: 5 additions & 1 deletion arch/i386/kernel/cpu/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <linux/string.h>
#include <asm/semaphore.h>
#include <linux/seq_file.h>
#include <linux/cpufreq.h>

/*
* Get CPU information for use by the procfs.
Expand Down Expand Up @@ -86,8 +87,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "stepping\t: unknown\n");

if ( cpu_has(c, X86_FEATURE_TSC) ) {
unsigned int freq = cpufreq_quick_get(n);
if (!freq)
freq = cpu_khz;
seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
cpu_khz / 1000, (cpu_khz % 1000));
freq / 1000, (freq % 1000));
}

/* Cache size */
Expand Down
8 changes: 7 additions & 1 deletion arch/ia64/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <linux/initrd.h>
#include <linux/platform.h>
#include <linux/pm.h>
#include <linux/cpufreq.h>

#include <asm/ia32.h>
#include <asm/machvec.h>
Expand Down Expand Up @@ -517,6 +518,7 @@ show_cpuinfo (struct seq_file *m, void *v)
char family[32], features[128], *cp, sep;
struct cpuinfo_ia64 *c = v;
unsigned long mask;
unsigned int proc_freq;
int i;

mask = c->features;
Expand Down Expand Up @@ -549,6 +551,10 @@ show_cpuinfo (struct seq_file *m, void *v)
sprintf(cp, " 0x%lx", mask);
}

proc_freq = cpufreq_quick_get(cpunum);
if (!proc_freq)
proc_freq = c->proc_freq / 1000;

seq_printf(m,
"processor : %d\n"
"vendor : %s\n"
Expand All @@ -565,7 +571,7 @@ show_cpuinfo (struct seq_file *m, void *v)
"BogoMIPS : %lu.%02lu\n",
cpunum, c->vendor, family, c->model, c->revision, c->archrev,
features, c->ppn, c->number,
c->proc_freq / 1000000, c->proc_freq % 1000000,
proc_freq / 1000, proc_freq % 1000,
c->itc_freq / 1000000, c->itc_freq % 1000000,
lpj*HZ/500000, (lpj*HZ/5000) % 100);
#ifdef CONFIG_SMP
Expand Down
6 changes: 5 additions & 1 deletion arch/x86_64/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <linux/edd.h>
#include <linux/mmzone.h>
#include <linux/kexec.h>
#include <linux/cpufreq.h>

#include <asm/mtrr.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -1256,8 +1257,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "stepping\t: unknown\n");

if (cpu_has(c,X86_FEATURE_TSC)) {
unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
if (!freq)
freq = cpu_khz;
seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
cpu_khz / 1000, (cpu_khz % 1000));
freq / 1000, (freq % 1000));
}

/* Cache size */
Expand Down
24 changes: 24 additions & 0 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,30 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigne
}


/**
* cpufreq_quick_get - get the CPU frequency (in kHz) frpm policy->cur
* @cpu: CPU number
*
* This is the last known freq, without actually getting it from the driver.
* Return value will be same as what is shown in scaling_cur_freq in sysfs.
*/
unsigned int cpufreq_quick_get(unsigned int cpu)
{
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
unsigned int ret = 0;

if (policy) {
down(&policy->lock);
ret = policy->cur;
up(&policy->lock);
cpufreq_cpu_put(policy);
}

return (ret);
}
EXPORT_SYMBOL(cpufreq_quick_get);


/**
* cpufreq_get - get the current CPU frequency (in kHz)
* @cpu: CPU number
Expand Down
10 changes: 10 additions & 0 deletions include/linux/cpufreq.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,16 @@ int cpufreq_update_policy(unsigned int cpu);
/* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */
unsigned int cpufreq_get(unsigned int cpu);

/* query the last known CPU freq (in kHz). If zero, cpufreq couldn't detect it */
#ifdef CONFIG_CPU_FREQ
unsigned int cpufreq_quick_get(unsigned int cpu);
#else
static inline unsigned int cpufreq_quick_get(unsigned int cpu)
{
return 0;
}
#endif


/*********************************************************************
* CPUFREQ DEFAULT GOVERNOR *
Expand Down

0 comments on commit 95235ca

Please sign in to comment.