Commit da7000e8 authored by Mike Leach's avatar Mike Leach Committed by Mathieu Poirier
Browse files

coresight: configuration: Update API to introduce load owner concept



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: default avatarMike Leach <mike.leach@linaro.org>
Link: https://lore.kernel.org/r/20211124200038.28662-2-mike.leach@linaro.org


Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
parent 66bd1333
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -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);
}
+4 −1
Original line number Diff line number Diff line
@@ -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;
};

/**
+18 −3
Original line number Diff line number Diff line
@@ -361,13 +361,22 @@ int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc,
 * 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;

+27 −2
Original line number Diff line number Diff line
@@ -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);