[RFC PATCH 1/7] x86/resctrl: Add register/unregister functions for driver to hook into resctrl

From: Tony Luck
Date: Thu Apr 20 2023 - 18:06:53 EST


Just one callback at the point for the driver to be notified when the
resctrl filesystem is mounted or unmounted. Virtually all drivers
will need this hook to enable/disable their feature(s) as part of
mount/unmount.

Signed-off-by: Tony Luck <tony.luck@xxxxxxxxx>
---
include/linux/resctrl.h | 13 +++++++
arch/x86/kernel/cpu/resctrl/rdtgroup.c | 50 ++++++++++++++++++++++++++
2 files changed, 63 insertions(+)

diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 8334eeacfec5..78513edddca0 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -204,6 +204,19 @@ struct resctrl_schema {
u32 num_closid;
};

+/**
+ * struct resctrl_driver - interface for driver to attach to resctrl
+ * @list: List of registered drivers
+ * @mount: Callback for mount/unmount
+ */
+struct resctrl_driver {
+ struct list_head list;
+ void (*mount)(bool mount);
+};
+
+int resctrl_register_driver(struct resctrl_driver *d);
+void resctrl_unregister_driver(struct resctrl_driver *d);
+
/* The number of closid supported by this resource regardless of CDP */
u32 resctrl_arch_get_num_closid(struct rdt_resource *r);
int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid);
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index 6ad33f355861..3e6778bde427 100644
--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -51,6 +51,9 @@ static struct kernfs_node *kn_mongrp;
/* Kernel fs node for "mon_data" directory under root */
static struct kernfs_node *kn_mondata;

+static LIST_HEAD(drivers);
+static bool resctrl_is_mounted;
+
static struct seq_buf last_cmd_status;
static char last_cmd_status_buf[512];

@@ -2437,6 +2440,42 @@ static int schemata_list_create(void)
return ret;
}

+static void driver_up(struct resctrl_driver *d)
+{
+ if (d->mount)
+ d->mount(true);
+}
+
+static void driver_down(struct resctrl_driver *d)
+{
+ if (d->mount)
+ d->mount(false);
+}
+
+int resctrl_register_driver(struct resctrl_driver *d)
+{
+ mutex_lock(&rdtgroup_mutex);
+ list_add(&d->list, &drivers);
+
+ if (resctrl_is_mounted)
+ driver_up(d);
+ mutex_unlock(&rdtgroup_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(resctrl_register_driver);
+
+void resctrl_unregister_driver(struct resctrl_driver *d)
+{
+ mutex_lock(&rdtgroup_mutex);
+ list_del(&d->list);
+
+ if (resctrl_is_mounted)
+ driver_down(d);
+ mutex_unlock(&rdtgroup_mutex);
+}
+EXPORT_SYMBOL_GPL(resctrl_unregister_driver);
+
static void schemata_list_destroy(void)
{
struct resctrl_schema *s, *tmp;
@@ -2450,6 +2489,7 @@ static void schemata_list_destroy(void)
static int rdt_get_tree(struct fs_context *fc)
{
struct rdt_fs_context *ctx = rdt_fc2context(fc);
+ struct resctrl_driver *d;
struct rdt_domain *dom;
struct rdt_resource *r;
int ret;
@@ -2516,6 +2556,10 @@ static int rdt_get_tree(struct fs_context *fc)
mbm_setup_overflow_handler(dom, MBM_OVERFLOW_INTERVAL);
}

+ list_for_each_entry(d, &drivers, list)
+ driver_up(d);
+ resctrl_is_mounted = true;
+
goto out;

out_psl:
@@ -2761,6 +2805,7 @@ static void rmdir_all_sub(void)

static void rdt_kill_sb(struct super_block *sb)
{
+ struct resctrl_driver *d;
struct rdt_resource *r;

cpus_read_lock();
@@ -2780,6 +2825,11 @@ static void rdt_kill_sb(struct super_block *sb)
static_branch_disable_cpuslocked(&rdt_mon_enable_key);
static_branch_disable_cpuslocked(&rdt_enable_key);
kernfs_kill_sb(sb);
+
+ list_for_each_entry(d, &drivers, list)
+ driver_down(d);
+ resctrl_is_mounted = false;
+
mutex_unlock(&rdtgroup_mutex);
cpus_read_unlock();
}
--
2.39.2