[PATCH v1 2/2] powerpc/pseries: Add debugfs interface to retrieve VPHN info
Naveen N. Rao
naveen.n.rao at linux.ibm.com
Tue Dec 11 05:14:47 AEDT 2018
Add debugfs interface to retrieve associativity information for lpar
vcpus (debugfs/vphn/lpar) and the hypervisor cpus (debugfs/vphn/hyp).
This information is useful to derive various metrics, including the vcpu
dispatch statistics in a SPLPAR environment.
Signed-off-by: Naveen N. Rao <naveen.n.rao at linux.ibm.com>
---
arch/powerpc/mm/numa.c | 105 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 105 insertions(+)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 6677a578f18d..f0b0e87016e6 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -40,6 +40,7 @@
#include <asm/setup.h>
#include <asm/vdso.h>
#include <asm/drmem.h>
+#include <asm/debugfs.h>
static int numa_enabled = 1;
@@ -1089,6 +1090,107 @@ static long hcall_vphn(unsigned long cpu, u64 flags, __be32 *associativity)
return rc;
}
+#ifdef CONFIG_DEBUG_FS
+static ssize_t vphn_lpar_cpu_file_read(struct file *filp, char __user *buf,
+ size_t len, loff_t *pos)
+{
+ int cpu = (long)filp->private_data;
+ __be32 associativity[VPHN_ASSOC_BUFSIZE] = {0};
+ int hwcpu = get_hard_smp_processor_id(cpu);
+ long int rc;
+
+ if (len != sizeof(associativity))
+ return -EINVAL;
+
+ rc = hcall_vphn(hwcpu, 1, associativity);
+ if (rc)
+ return -EFAULT;
+
+ rc = copy_to_user(buf, &associativity, sizeof(associativity));
+ if (rc)
+ return -EFAULT;
+
+ return sizeof(associativity);
+}
+
+static ssize_t vphn_hyp_cpu_file_read(struct file *filp, char __user *buf,
+ size_t len, loff_t *pos)
+{
+ int cpu = (long)filp->private_data;
+ __be32 associativity[VPHN_ASSOC_BUFSIZE] = {0};
+ long int rc;
+
+ if (len != sizeof(associativity))
+ return -EINVAL;
+
+ rc = hcall_vphn(cpu, 2, associativity);
+ if (rc)
+ return -EFAULT;
+
+ rc = copy_to_user(buf, &associativity, sizeof(associativity));
+ if (rc)
+ return -EFAULT;
+
+ return sizeof(associativity);
+}
+
+static const struct file_operations vphn_lpar_cpu_fops = {
+ .open = simple_open,
+ .read = vphn_lpar_cpu_file_read,
+ .llseek = no_llseek,
+};
+
+static const struct file_operations vphn_hyp_cpu_fops = {
+ .open = simple_open,
+ .read = vphn_hyp_cpu_file_read,
+ .llseek = no_llseek,
+};
+
+static int debug_init_vphn_entries(void)
+{
+ struct dentry *vphn_dir, *vphn_lpar_dir, *vphn_hyp_dir;
+ struct dentry *vphn_lpar_cpu_file, *vphn_hyp_cpu_file;
+ long cpu;
+ char name[10];
+
+ if (!firmware_has_feature(FW_FEATURE_SPLPAR))
+ return 0;
+
+ vphn_dir = debugfs_create_dir("vphn", powerpc_debugfs_root);
+ if (!vphn_dir) {
+ pr_warn("%s: can't create vphn debugfs root dir\n", __func__);
+ return -ENOMEM;
+ }
+
+ vphn_lpar_dir = debugfs_create_dir("lpar", vphn_dir);
+ vphn_hyp_dir = debugfs_create_dir("hyp", vphn_dir);
+ if (!vphn_lpar_dir || !vphn_hyp_dir) {
+ pr_warn("%s: can't create vphn dir\n", __func__);
+ goto err_remove_dir;
+ }
+
+ for_each_possible_cpu(cpu) {
+ sprintf(name, "cpu-%ld", cpu);
+ vphn_lpar_cpu_file = debugfs_create_file(name, 0400,
+ vphn_lpar_dir, (void *)cpu, &vphn_lpar_cpu_fops);
+ vphn_hyp_cpu_file = debugfs_create_file(name, 0400,
+ vphn_hyp_dir, (void *)cpu, &vphn_hyp_cpu_fops);
+ if (!vphn_lpar_cpu_file || !vphn_hyp_cpu_file) {
+ pr_warn("%s: can't create vphn cpu file\n", __func__);
+ goto err_remove_dir;
+ }
+ }
+
+ return 0;
+
+err_remove_dir:
+ debugfs_remove_recursive(vphn_dir);
+ return -ENOMEM;
+}
+#else
+static int debug_init_vphn_entries(void) { return 0; }
+#endif /* CONFIG_DEBUG_FS */
+
/*
* Change polling interval for associativity changes.
*/
@@ -1619,6 +1721,9 @@ static int topology_update_init(void)
if (!proc_create("powerpc/topology_updates", 0644, NULL, &topology_ops))
return -ENOMEM;
+ if (!debug_init_vphn_entries())
+ return -ENOMEM;
+
topology_inited = 1;
return 0;
}
--
2.19.2
More information about the Linuxppc-dev
mailing list