MIPS: MT: proc: Add support for printing VPE and TC ids
authorRalf Baechle <ralf@linux-mips.org>
Wed, 16 Oct 2013 15:10:07 +0000 (17:10 +0200)
committerRalf Baechle <ralf@linux-mips.org>
Mon, 31 Mar 2014 16:17:12 +0000 (18:17 +0200)
And there are more CPUs or configurations that want to provide special
per-CPU information in /proc/cpuinfo.  So I think there needs to be a
hook mechanism, such as a notifier.

This is a first cut only; I need to think about what sort of looking
the notifier needs to have.  But I'd appreciate testing on MT hardware!

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Cc: Markos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6066/

arch/mips/include/asm/cpu-info.h
arch/mips/kernel/proc.c
arch/mips/kernel/smp-mt.c
arch/mips/kernel/smtc-proc.c

index 49953f7173342f333f9f84a7756d20248fd5a419..dc2135be2a3a4ed2c044870e3c8c8b24881535f6 100644 (file)
@@ -96,6 +96,27 @@ extern void cpu_report(void);
 extern const char *__cpu_name[];
 #define cpu_name_string()      __cpu_name[smp_processor_id()]
 
+struct seq_file;
+struct notifier_block;
+
+extern int register_proc_cpuinfo_notifier(struct notifier_block *nb);
+extern int proc_cpuinfo_notifier_call_chain(unsigned long val, void *v);
+
+#define proc_cpuinfo_notifier(fn, pri)                                 \
+({                                                                     \
+       static struct notifier_block fn##_nb = {                        \
+               .notifier_call = fn,                                    \
+               .priority = pri                                         \
+       };                                                              \
+                                                                       \
+       register_proc_cpuinfo_notifier(&fn##_nb);                       \
+})
+
+struct proc_cpuinfo_notifier_args {
+       struct seq_file *m;
+       unsigned long n;
+};
+
 #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
 # define cpu_vpe_id(cpuinfo)   ((cpuinfo)->vpe_id)
 #else
index f0df7fde37c508841397ccf56dfeeca147505a00..e40971b51d2f0bf47e3eb217f43c652c732e7a09 100644 (file)
 
 unsigned int vced_count, vcei_count;
 
+/*
+ *  * No lock; only written during early bootup by CPU 0.
+ *   */
+static RAW_NOTIFIER_HEAD(proc_cpuinfo_chain);
+
+int __ref register_proc_cpuinfo_notifier(struct notifier_block *nb)
+{
+       return raw_notifier_chain_register(&proc_cpuinfo_chain, nb);
+}
+
+int proc_cpuinfo_notifier_call_chain(unsigned long val, void *v)
+{
+       return raw_notifier_call_chain(&proc_cpuinfo_chain, val, v);
+}
+
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
+       struct proc_cpuinfo_notifier_args proc_cpuinfo_notifier_args;
        unsigned long n = (unsigned long) v - 1;
        unsigned int version = cpu_data[n].processor_id;
        unsigned int fp_vers = cpu_data[n].fpu_id;
@@ -120,6 +136,13 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                      cpu_has_vce ? "%u" : "not available");
        seq_printf(m, fmt, 'D', vced_count);
        seq_printf(m, fmt, 'I', vcei_count);
+
+       proc_cpuinfo_notifier_args.m = m;
+       proc_cpuinfo_notifier_args.n = n;
+
+       raw_notifier_call_chain(&proc_cpuinfo_chain, 0,
+                               &proc_cpuinfo_notifier_args);
+
        seq_printf(m, "\n");
 
        return 0;
index 0fb8cefc9114b299fd5ed3b73ef3da86abf4da8e..3378c452e5d74b9d548a358d1f91508444372b3a 100644 (file)
@@ -313,3 +313,25 @@ struct plat_smp_ops vsmp_smp_ops = {
        .smp_setup              = vsmp_smp_setup,
        .prepare_cpus           = vsmp_prepare_cpus,
 };
+
+static int proc_cpuinfo_chain_call(struct notifier_block *nfb,
+       unsigned long action_unused, void *data)
+{
+       struct proc_cpuinfo_notifier_args *pcn = data;
+       struct seq_file *m = pcn->m;
+       unsigned long n = pcn->n;
+
+       if (!cpu_has_mipsmt)
+               return NOTIFY_OK;
+
+       seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id);
+
+       return NOTIFY_OK;
+}
+
+static int __init proc_cpuinfo_notifier_init(void)
+{
+       return proc_cpuinfo_notifier(proc_cpuinfo_chain_call, 0);
+}
+
+subsys_initcall(proc_cpuinfo_notifier_init);
index c10aa84c9fa9d4d4d66cc6005ee8c82b7bce495e..38635a996cbfd6a2f883cacb68e8950e9a792b25 100644 (file)
@@ -77,3 +77,26 @@ void init_smtc_stats(void)
 
        proc_create("smtc", 0444, NULL, &smtc_proc_fops);
 }
+
+static int proc_cpuinfo_chain_call(struct notifier_block *nfb,
+       unsigned long action_unused, void *data)
+{
+       struct proc_cpuinfo_notifier_args *pcn = data;
+       struct seq_file *m = pcn->m;
+       unsigned long n = pcn->n;
+
+       if (!cpu_has_mipsmt)
+               return NOTIFY_OK;
+
+       seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id);
+       seq_printf(m, "TC\t\t\t: %d\n", cpu_data[n].tc_id);
+
+       return NOTIFY_OK;
+}
+
+static int __init proc_cpuinfo_notifier_init(void)
+{
+       return proc_cpuinfo_notifier(proc_cpuinfo_chain_call, 0);
+}
+
+subsys_initcall(proc_cpuinfo_notifier_init);