coresight: configuration: Update API to introduce load owner concept
authorMike Leach <mike.leach@linaro.org>
Wed, 24 Nov 2021 20:00:33 +0000 (20:00 +0000)
committerMathieu Poirier <mathieu.poirier@linaro.org>
Fri, 26 Nov 2021 18:27:21 +0000 (11:27 -0700)
Update the existing load API to introduce a "load owner" concept.

This allows the tracking of the loaded configurations and features against
the loading owner type, to allow later unload according to owner.

A list of loaded configurations by owner is created.

The load owner infrastructure will be used in following patches
to implement dynanic load and unload, alongside dependency tracking.

Signed-off-by: Mike Leach <mike.leach@linaro.org>
Link: https://lore.kernel.org/r/20211124200038.28662-2-mike.leach@linaro.org
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
drivers/hwtracing/coresight/coresight-cfg-preload.c
drivers/hwtracing/coresight/coresight-config.h
drivers/hwtracing/coresight/coresight-syscfg.c
drivers/hwtracing/coresight/coresight-syscfg.h

index 751af37..e237a4e 100644 (file)
@@ -24,8 +24,13 @@ static struct cscfg_config_desc *preload_cfgs[] = {
        NULL
 };
 
+static struct cscfg_load_owner_info preload_owner = {
+       .type = CSCFG_OWNER_PRELOAD,
+};
+
 /* preload called on initialisation */
-int cscfg_preload(void)
+int cscfg_preload(void *owner_handle)
 {
-       return cscfg_load_config_sets(preload_cfgs, preload_feats);
+       preload_owner.owner_handle = owner_handle;
+       return cscfg_load_config_sets(preload_cfgs, preload_feats, &preload_owner);
 }
index 25eb6c6..6e0d439 100644 (file)
@@ -97,6 +97,7 @@ struct cscfg_regval_desc {
  * @params_desc: array of parameters used.
  * @nr_regs:    number of registers used.
  * @regs_desc:  array of registers used.
+ * @load_owner:         handle to load owner for dynamic load and unload of features.
  */
 struct cscfg_feature_desc {
        const char *name;
@@ -107,6 +108,7 @@ struct cscfg_feature_desc {
        struct cscfg_parameter_desc *params_desc;
        int nr_regs;
        struct cscfg_regval_desc *regs_desc;
+       void *load_owner;
 };
 
 /**
@@ -128,7 +130,7 @@ struct cscfg_feature_desc {
  * @presets:           Array of preset values.
  * @event_ea:          Extended attribute for perf event value
  * @active_cnt:                ref count for activate on this configuration.
- *
+ * @load_owner:                handle to load owner for dynamic load and unload of configs.
  */
 struct cscfg_config_desc {
        const char *name;
@@ -141,6 +143,7 @@ struct cscfg_config_desc {
        const u64 *presets; /* nr_presets * nr_total_params */
        struct dev_ext_attribute *event_ea;
        atomic_t active_cnt;
+       void *load_owner;
 };
 
 /**
index 4305456..021f509 100644 (file)
@@ -361,13 +361,22 @@ unlock_exit:
  * descriptors and load into the system.
  * Features are loaded first to ensure configuration dependencies can be met.
  *
+ * To facilitate dynamic loading and unloading, features and configurations
+ * have a "load_owner", to allow later unload by the same owner. An owner may
+ * be a loadable module or configuration dynamically created via configfs.
+ * As later loaded configurations can use earlier loaded features, creating load
+ * dependencies, a load order list is maintained. Unload is strictly in the
+ * reverse order to load.
+ *
  * @config_descs: 0 terminated array of configuration descriptors.
  * @feat_descs:   0 terminated array of feature descriptors.
+ * @owner_info:          Information on the owner of this set.
  */
 int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
-                          struct cscfg_feature_desc **feat_descs)
+                          struct cscfg_feature_desc **feat_descs,
+                          struct cscfg_load_owner_info *owner_info)
 {
-       int err, i = 0;
+       int err = 0, i = 0;
 
        mutex_lock(&cscfg_mutex);
 
@@ -382,6 +391,7 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
                                       feat_descs[i]->name);
                                goto exit_unlock;
                        }
+                       feat_descs[i]->load_owner = owner_info;
                        i++;
                }
        }
@@ -398,10 +408,14 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
                                       config_descs[i]->name);
                                goto exit_unlock;
                        }
+                       config_descs[i]->load_owner = owner_info;
                        i++;
                }
        }
 
+       /* add the load owner to the load order list */
+       list_add_tail(&owner_info->item, &cscfg_mgr->load_order_list);
+
 exit_unlock:
        mutex_unlock(&cscfg_mutex);
        return err;
@@ -827,10 +841,11 @@ int __init cscfg_init(void)
        INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list);
        INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list);
        INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
+       INIT_LIST_HEAD(&cscfg_mgr->load_order_list);
        atomic_set(&cscfg_mgr->sys_active_cnt, 0);
 
        /* preload built-in configurations */
-       err = cscfg_preload();
+       err = cscfg_preload(THIS_MODULE);
        if (err)
                goto exit_err;
 
index 8d018ef..08067e8 100644 (file)
@@ -25,6 +25,7 @@
  * @csdev_desc_list:   List of coresight devices registered with the configuration manager.
  * @feat_desc_list:    List of feature descriptors to load into registered devices.
  * @config_desc_list:  List of system configuration descriptors to load into registered devices.
+ * @load_order_list:    Ordered list of owners for dynamically loaded configurations.
  * @sys_active_cnt:    Total number of active config descriptor references.
  * @cfgfs_subsys:      configfs subsystem used to manage configurations.
  */
@@ -33,6 +34,7 @@ struct cscfg_manager {
        struct list_head csdev_desc_list;
        struct list_head feat_desc_list;
        struct list_head config_desc_list;
+       struct list_head load_order_list;
        atomic_t sys_active_cnt;
        struct configfs_subsystem cfgfs_subsys;
 };
@@ -56,10 +58,32 @@ struct cscfg_registered_csdev {
        struct list_head item;
 };
 
+/* owner types for loading and unloading of config and feature sets */
+enum cscfg_load_owner_type {
+       CSCFG_OWNER_PRELOAD,
+};
+
+/**
+ * Load item - item to add to the load order list allowing dynamic load and
+ *             unload of configurations and features. Caller loading a config
+ *            set provides a context handle for unload. API ensures that
+ *            items unloaded strictly in reverse order from load to ensure
+ *            dependencies are respected.
+ *
+ * @item:              list entry for load order list.
+ * @type:              type of owner - allows interpretation of owner_handle.
+ * @owner_handle:      load context - handle for owner of loaded configs.
+ */
+struct cscfg_load_owner_info {
+       struct list_head item;
+       int type;
+       void *owner_handle;
+};
+
 /* internal core operations for cscfg */
 int __init cscfg_init(void);
 void cscfg_exit(void);
-int cscfg_preload(void);
+int cscfg_preload(void *owner_handle);
 const struct cscfg_feature_desc *cscfg_get_named_feat_desc(const char *name);
 int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc,
                                int param_idx, u64 value);
@@ -67,7 +91,8 @@ int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc,
 
 /* syscfg manager external API */
 int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
-                          struct cscfg_feature_desc **feat_descs);
+                          struct cscfg_feature_desc **feat_descs,
+                          struct cscfg_load_owner_info *owner_info);
 int cscfg_register_csdev(struct coresight_device *csdev, u32 match_flags,
                         struct cscfg_csdev_feat_ops *ops);
 void cscfg_unregister_csdev(struct coresight_device *csdev);