[PATCH V4 33/38] x86/intel_rdt: Create resctrl debug area

From: Reinette Chatre
Date: Tue May 22 2018 - 14:40:28 EST


In preparation for support of debugging of RDT sub features the user can
now enable a RDT debugfs region.

Introduce the Kconfig option to enable this debug area and the subsequent
creation of the resctrl debugfs directory.

Signed-off-by: Reinette Chatre <reinette.chatre@xxxxxxxxx>
---
arch/x86/Kconfig | 10 ++++++++
arch/x86/kernel/cpu/intel_rdt.h | 4 ++++
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 41 ++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c07f492b871a..4fa24d0cce5a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -448,6 +448,16 @@ config INTEL_RDT

Say N if unsure.

+config INTEL_RDT_DEBUGFS
+ bool "Intel RDT debugfs interface"
+ depends on INTEL_RDT
+ select DEBUG_FS
+ help
+ Enable the creation of Intel RDT debugfs files. In support of
+ debugging and validation of Intel RDT sub-features that use it.
+
+ Say N if unsure.
+
if X86_32
config X86_BIGSMP
bool "Support for big SMP systems with more than 8 CPUs"
diff --git a/arch/x86/kernel/cpu/intel_rdt.h b/arch/x86/kernel/cpu/intel_rdt.h
index c948266d59c8..c4ff638e3bc6 100644
--- a/arch/x86/kernel/cpu/intel_rdt.h
+++ b/arch/x86/kernel/cpu/intel_rdt.h
@@ -432,6 +432,10 @@ extern struct rdt_resource rdt_resources_all[];
extern struct rdtgroup rdtgroup_default;
DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key);

+#ifdef CONFIG_INTEL_RDT_DEBUGFS
+extern struct dentry *debugfs_resctrl;
+#endif
+
enum {
RDT_RESOURCE_L3,
RDT_RESOURCE_L3DATA,
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
index e3380cbca914..da9d470294aa 100644
--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
+++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
@@ -22,6 +22,7 @@

#include <linux/cacheinfo.h>
#include <linux/cpu.h>
+#include <linux/debugfs.h>
#include <linux/fs.h>
#include <linux/sysfs.h>
#include <linux/kernfs.h>
@@ -56,6 +57,10 @@ static struct kernfs_node *kn_mondata;
static struct seq_buf last_cmd_status;
static char last_cmd_status_buf[512];

+#ifdef CONFIG_INTEL_RDT_DEBUGFS
+struct dentry *debugfs_resctrl;
+#endif
+
void rdt_last_cmd_clear(void)
{
lockdep_assert_held(&rdtgroup_mutex);
@@ -2764,8 +2769,41 @@ int __init rdtgroup_init(void)
if (ret)
goto cleanup_mountpoint;

+ /*
+ * Adding the resctrl debugfs directory here may not be ideal since
+ * it would let the resctrl debugfs directory appear on the debugfs
+ * filesystem before the resctrl filesystem is mounted.
+ * It may also be ok since that would enable debugging of RDT before
+ * resctrl is mounted.
+ * The reason why the debugfs directory is created here and not in
+ * rdt_mount() is because rdt_mount() takes rdtgroup_mutex and
+ * during the debugfs directory creation also &sb->s_type->i_mutex_key
+ * (the lockdep class of inode->i_rwsem). Other filesystem
+ * interactions (eg. SyS_getdents) have the lock ordering:
+ * &sb->s_type->i_mutex_key --> &mm->mmap_sem
+ * During mmap(), called with &mm->mmap_sem, the rdtgroup_mutex
+ * is taken, thus creating dependency:
+ * &mm->mmap_sem --> rdtgroup_mutex for the latter that can cause
+ * issues considering the other two lock dependencies.
+ * By creating the debugfs directory here we avoid a dependency
+ * that may cause deadlock (even though file operations cannot
+ * occur until the filesystem is mounted, but I do not know how to
+ * tell lockdep that).
+ */
+#ifdef CONFIG_INTEL_RDT_DEBUGFS
+ debugfs_resctrl = debugfs_create_dir("resctrl", NULL);
+ if (IS_ERR(debugfs_resctrl)) {
+ ret = PTR_ERR(debugfs_resctrl);
+ goto cleanup_register;
+ }
+#endif
+
return 0;

+#ifdef CONFIG_INTEL_RDT_DEBUGFS
+cleanup_register:
+ unregister_filesystem(&rdt_fs_type);
+#endif
cleanup_mountpoint:
sysfs_remove_mount_point(fs_kobj, "resctrl");
cleanup_root:
@@ -2776,6 +2814,9 @@ int __init rdtgroup_init(void)

void __exit rdtgroup_exit(void)
{
+#ifdef CONFIG_INTEL_RDT_DEBUGFS
+ debugfs_remove_recursive(debugfs_resctrl);
+#endif
unregister_filesystem(&rdt_fs_type);
sysfs_remove_mount_point(fs_kobj, "resctrl");
kernfs_destroy_root(rdt_root);
--
2.13.6