s390/cpuinfo: show dynamic and static cpu mhz
Show the dynamic and static cpu mhz of each cpu. Since these values are per cpu this requires a fundamental extension of the format of /proc/cpuinfo. Historically we had only a single line per cpu and a summary at the top of the file. This format is hardly extendible if we want to add more per cpu information. Therefore this patch adds per cpu blocks at the end of /proc/cpuinfo: cpu : 0 cpu Mhz dynamic : 5504 cpu Mhz static : 5504 cpu : 1 cpu Mhz dynamic : 5504 cpu Mhz static : 5504 cpu : 2 cpu Mhz dynamic : 5504 cpu Mhz static : 5504 cpu : 3 cpu Mhz dynamic : 5504 cpu Mhz static : 5504 Right now each block contains only the dynamic and static cpu mhz, but it can be easily extended like on every other architecture. This extension is supposed to be compatible with the old format. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Acked-by: Sascha Silbe <silbe@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
219a21b3b0
commit
097a116c7e
|
@ -77,7 +77,10 @@ static inline void get_cpu_id(struct cpuid *ptr)
|
|||
asm volatile("stidp %0" : "=Q" (*ptr));
|
||||
}
|
||||
|
||||
extern void s390_adjust_jiffies(void);
|
||||
void s390_adjust_jiffies(void);
|
||||
void s390_update_cpu_mhz(void);
|
||||
void cpu_detect_mhz_feature(void);
|
||||
|
||||
extern const struct seq_operations cpuinfo_op;
|
||||
extern int sysctl_ieee_emulation_warnings;
|
||||
extern void execve_tail(void);
|
||||
|
@ -233,6 +236,18 @@ void cpu_relax(void);
|
|||
|
||||
#define cpu_relax_lowlatency() barrier()
|
||||
|
||||
#define ECAG_CACHE_ATTRIBUTE 0
|
||||
#define ECAG_CPU_ATTRIBUTE 1
|
||||
|
||||
static inline unsigned long __ecag(unsigned int asi, unsigned char parm)
|
||||
{
|
||||
unsigned long val;
|
||||
|
||||
asm volatile(".insn rsy,0xeb000000004c,%0,0,0(%1)" /* ecag */
|
||||
: "=d" (val) : "a" (asi << 8 | parm));
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void psw_set_key(unsigned int key)
|
||||
{
|
||||
asm volatile("spka 0(%0)" : : "d" (key));
|
||||
|
|
|
@ -99,12 +99,7 @@ static inline enum cache_type get_cache_type(struct cache_info *ci, int level)
|
|||
|
||||
static inline unsigned long ecag(int ai, int li, int ti)
|
||||
{
|
||||
unsigned long cmd, val;
|
||||
|
||||
cmd = ai << 4 | li << 1 | ti;
|
||||
asm volatile(".insn rsy,0xeb000000004c,%0,0,0(%1)" /* ecag */
|
||||
: "=d" (val) : "a" (cmd));
|
||||
return val;
|
||||
return __ecag(ECAG_CACHE_ATTRIBUTE, ai << 4 | li << 1 | ti);
|
||||
}
|
||||
|
||||
static void ci_leaf_init(struct cacheinfo *this_leaf, int private,
|
||||
|
|
|
@ -13,12 +13,45 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <asm/diag.h>
|
||||
#include <asm/facility.h>
|
||||
#include <asm/elf.h>
|
||||
#include <asm/lowcore.h>
|
||||
#include <asm/param.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
static DEFINE_PER_CPU(struct cpuid, cpu_id);
|
||||
struct cpu_info {
|
||||
unsigned int cpu_mhz_dynamic;
|
||||
unsigned int cpu_mhz_static;
|
||||
struct cpuid cpu_id;
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct cpu_info, cpu_info);
|
||||
|
||||
static bool machine_has_cpu_mhz;
|
||||
|
||||
void __init cpu_detect_mhz_feature(void)
|
||||
{
|
||||
if (test_facility(34) && __ecag(ECAG_CPU_ATTRIBUTE, 0) != -1UL)
|
||||
machine_has_cpu_mhz = 1;
|
||||
}
|
||||
|
||||
static void update_cpu_mhz(void *arg)
|
||||
{
|
||||
unsigned long mhz;
|
||||
struct cpu_info *c;
|
||||
|
||||
mhz = __ecag(ECAG_CPU_ATTRIBUTE, 0);
|
||||
c = this_cpu_ptr(&cpu_info);
|
||||
c->cpu_mhz_dynamic = mhz >> 32;
|
||||
c->cpu_mhz_static = mhz & 0xffffffff;
|
||||
}
|
||||
|
||||
void s390_update_cpu_mhz(void)
|
||||
{
|
||||
s390_adjust_jiffies();
|
||||
if (machine_has_cpu_mhz)
|
||||
on_each_cpu(update_cpu_mhz, NULL, 0);
|
||||
}
|
||||
|
||||
void notrace cpu_relax(void)
|
||||
{
|
||||
|
@ -35,9 +68,11 @@ EXPORT_SYMBOL(cpu_relax);
|
|||
*/
|
||||
void cpu_init(void)
|
||||
{
|
||||
struct cpuid *id = this_cpu_ptr(&cpu_id);
|
||||
struct cpuid *id = this_cpu_ptr(&cpu_info.cpu_id);
|
||||
|
||||
get_cpu_id(id);
|
||||
if (machine_has_cpu_mhz)
|
||||
update_cpu_mhz(NULL);
|
||||
atomic_inc(&init_mm.mm_count);
|
||||
current->active_mm = &init_mm;
|
||||
BUG_ON(current->mm);
|
||||
|
@ -64,7 +99,6 @@ static void show_cpu_summary(struct seq_file *m, void *v)
|
|||
};
|
||||
int i, cpu;
|
||||
|
||||
s390_adjust_jiffies();
|
||||
seq_printf(m, "vendor_id : IBM/S390\n"
|
||||
"# processors : %i\n"
|
||||
"bogomips per cpu: %lu.%02lu\n",
|
||||
|
@ -80,7 +114,7 @@ static void show_cpu_summary(struct seq_file *m, void *v)
|
|||
seq_puts(m, "\n");
|
||||
show_cacheinfo(m);
|
||||
for_each_online_cpu(cpu) {
|
||||
struct cpuid *id = &per_cpu(cpu_id, cpu);
|
||||
struct cpuid *id = &per_cpu(cpu_info.cpu_id, cpu);
|
||||
|
||||
seq_printf(m, "processor %d: "
|
||||
"version = %02X, "
|
||||
|
@ -90,6 +124,14 @@ static void show_cpu_summary(struct seq_file *m, void *v)
|
|||
}
|
||||
}
|
||||
|
||||
static void show_cpu_mhz(struct seq_file *m, unsigned long n)
|
||||
{
|
||||
struct cpu_info *c = per_cpu_ptr(&cpu_info, n);
|
||||
|
||||
seq_printf(m, "cpu MHz dynamic : %d\n", c->cpu_mhz_dynamic);
|
||||
seq_printf(m, "cpu MHz static : %d\n", c->cpu_mhz_static);
|
||||
}
|
||||
|
||||
/*
|
||||
* show_cpuinfo - Get information on one CPU for use by procfs.
|
||||
*/
|
||||
|
@ -99,6 +141,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
|||
|
||||
if (!n)
|
||||
show_cpu_summary(m, v);
|
||||
if (!machine_has_cpu_mhz)
|
||||
return 0;
|
||||
seq_printf(m, "\ncpu : %ld\n", n);
|
||||
show_cpu_mhz(m, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -132,4 +178,3 @@ const struct seq_operations cpuinfo_op = {
|
|||
.stop = c_stop,
|
||||
.show = show_cpuinfo,
|
||||
};
|
||||
|
||||
|
|
|
@ -901,6 +901,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
setup_vmcoreinfo();
|
||||
setup_lowcore();
|
||||
smp_fill_possible_mask();
|
||||
cpu_detect_mhz_feature();
|
||||
cpu_init();
|
||||
numa_setup();
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ static void sclp_cpu_capability_notify(struct work_struct *work)
|
|||
int cpu;
|
||||
struct device *dev;
|
||||
|
||||
s390_adjust_jiffies();
|
||||
s390_update_cpu_mhz();
|
||||
pr_info("CPU capability may have changed\n");
|
||||
get_online_cpus();
|
||||
for_each_online_cpu(cpu) {
|
||||
|
|
Loading…
Reference in New Issue