Coresight: Introduce a new struct coresight_path
Introduce a new strcuture, 'struct coresight_path', to store the data that utilized by the devices in the path. The coresight_path will be built/released by coresight_build_path/coresight_release_path functions. Signed-off-by: Jie Gan <quic_jiegan@quicinc.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20250303032931.2500935-5-quic_jiegan@quicinc.com
This commit is contained in:
parent
182e8c7079
commit
3c03c49b2f
@ -670,7 +670,7 @@ static void coresight_drop_device(struct coresight_device *csdev)
|
||||
static int _coresight_build_path(struct coresight_device *csdev,
|
||||
struct coresight_device *source,
|
||||
struct coresight_device *sink,
|
||||
struct list_head *path)
|
||||
struct coresight_path *path)
|
||||
{
|
||||
int i, ret;
|
||||
bool found = false;
|
||||
@ -723,25 +723,25 @@ static int _coresight_build_path(struct coresight_device *csdev,
|
||||
return -ENOMEM;
|
||||
|
||||
node->csdev = csdev;
|
||||
list_add(&node->link, path);
|
||||
list_add(&node->link, &path->path_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct list_head *coresight_build_path(struct coresight_device *source,
|
||||
struct coresight_path *coresight_build_path(struct coresight_device *source,
|
||||
struct coresight_device *sink)
|
||||
{
|
||||
struct list_head *path;
|
||||
struct coresight_path *path;
|
||||
int rc;
|
||||
|
||||
if (!sink)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
path = kzalloc(sizeof(struct list_head), GFP_KERNEL);
|
||||
path = kzalloc(sizeof(struct coresight_path), GFP_KERNEL);
|
||||
if (!path)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
INIT_LIST_HEAD(path);
|
||||
INIT_LIST_HEAD(&path->path_list);
|
||||
|
||||
rc = _coresight_build_path(source, source, sink, path);
|
||||
if (rc) {
|
||||
@ -759,12 +759,12 @@ struct list_head *coresight_build_path(struct coresight_device *source,
|
||||
* Go through all the elements of a path and 1) removed it from the list and
|
||||
* 2) free the memory allocated for each node.
|
||||
*/
|
||||
void coresight_release_path(struct list_head *path)
|
||||
void coresight_release_path(struct coresight_path *path)
|
||||
{
|
||||
struct coresight_device *csdev;
|
||||
struct coresight_node *nd, *next;
|
||||
|
||||
list_for_each_entry_safe(nd, next, path, link) {
|
||||
list_for_each_entry_safe(nd, next, &path->path_list, link) {
|
||||
csdev = nd->csdev;
|
||||
|
||||
coresight_drop_device(csdev);
|
||||
|
||||
@ -136,13 +136,13 @@ static const struct attribute_group *etm_pmu_attr_groups[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static inline struct list_head **
|
||||
static inline struct coresight_path **
|
||||
etm_event_cpu_path_ptr(struct etm_event_data *data, int cpu)
|
||||
{
|
||||
return per_cpu_ptr(data->path, cpu);
|
||||
}
|
||||
|
||||
static inline struct list_head *
|
||||
static inline struct coresight_path *
|
||||
etm_event_cpu_path(struct etm_event_data *data, int cpu)
|
||||
{
|
||||
return *etm_event_cpu_path_ptr(data, cpu);
|
||||
@ -197,6 +197,7 @@ static void free_sink_buffer(struct etm_event_data *event_data)
|
||||
int cpu;
|
||||
cpumask_t *mask = &event_data->mask;
|
||||
struct coresight_device *sink;
|
||||
struct coresight_path *path;
|
||||
|
||||
if (!event_data->snk_config)
|
||||
return;
|
||||
@ -205,7 +206,8 @@ static void free_sink_buffer(struct etm_event_data *event_data)
|
||||
return;
|
||||
|
||||
cpu = cpumask_first(mask);
|
||||
sink = coresight_get_sink(etm_event_cpu_path(event_data, cpu));
|
||||
path = etm_event_cpu_path(event_data, cpu);
|
||||
sink = coresight_get_sink(&path->path_list);
|
||||
sink_ops(sink)->free_buffer(event_data->snk_config);
|
||||
}
|
||||
|
||||
@ -226,11 +228,11 @@ static void free_event_data(struct work_struct *work)
|
||||
cscfg_deactivate_config(event_data->cfg_hash);
|
||||
|
||||
for_each_cpu(cpu, mask) {
|
||||
struct list_head **ppath;
|
||||
struct coresight_path **ppath;
|
||||
|
||||
ppath = etm_event_cpu_path_ptr(event_data, cpu);
|
||||
if (!(IS_ERR_OR_NULL(*ppath))) {
|
||||
struct coresight_device *sink = coresight_get_sink(*ppath);
|
||||
struct coresight_device *sink = coresight_get_sink(&((*ppath)->path_list));
|
||||
|
||||
/*
|
||||
* Mark perf event as done for trace id allocator, but don't call
|
||||
@ -276,7 +278,7 @@ static void *alloc_event_data(int cpu)
|
||||
* unused memory when dealing with single CPU trace scenarios is small
|
||||
* compared to the cost of searching through an optimized array.
|
||||
*/
|
||||
event_data->path = alloc_percpu(struct list_head *);
|
||||
event_data->path = alloc_percpu(struct coresight_path *);
|
||||
|
||||
if (!event_data->path) {
|
||||
kfree(event_data);
|
||||
@ -352,7 +354,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages,
|
||||
* CPUs, we can handle it and fail the session.
|
||||
*/
|
||||
for_each_cpu(cpu, mask) {
|
||||
struct list_head *path;
|
||||
struct coresight_path *path;
|
||||
struct coresight_device *csdev;
|
||||
|
||||
csdev = per_cpu(csdev_src, cpu);
|
||||
@ -458,7 +460,7 @@ static void etm_event_start(struct perf_event *event, int flags)
|
||||
struct etm_ctxt *ctxt = this_cpu_ptr(&etm_ctxt);
|
||||
struct perf_output_handle *handle = &ctxt->handle;
|
||||
struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
|
||||
struct list_head *path;
|
||||
struct coresight_path *path;
|
||||
u64 hw_id;
|
||||
u8 trace_id;
|
||||
|
||||
@ -494,12 +496,12 @@ static void etm_event_start(struct perf_event *event, int flags)
|
||||
|
||||
path = etm_event_cpu_path(event_data, cpu);
|
||||
/* We need a sink, no need to continue without one */
|
||||
sink = coresight_get_sink(path);
|
||||
sink = coresight_get_sink(&path->path_list);
|
||||
if (WARN_ON_ONCE(!sink))
|
||||
goto fail_end_stop;
|
||||
|
||||
/* Nothing will happen without a path */
|
||||
if (coresight_enable_path(path, CS_MODE_PERF, handle))
|
||||
if (coresight_enable_path(&path->path_list, CS_MODE_PERF, handle))
|
||||
goto fail_end_stop;
|
||||
|
||||
/* Finally enable the tracer */
|
||||
@ -534,7 +536,7 @@ static void etm_event_start(struct perf_event *event, int flags)
|
||||
return;
|
||||
|
||||
fail_disable_path:
|
||||
coresight_disable_path(path);
|
||||
coresight_disable_path(&path->path_list);
|
||||
fail_end_stop:
|
||||
/*
|
||||
* Check if the handle is still associated with the event,
|
||||
@ -558,7 +560,7 @@ static void etm_event_stop(struct perf_event *event, int mode)
|
||||
struct etm_ctxt *ctxt = this_cpu_ptr(&etm_ctxt);
|
||||
struct perf_output_handle *handle = &ctxt->handle;
|
||||
struct etm_event_data *event_data;
|
||||
struct list_head *path;
|
||||
struct coresight_path *path;
|
||||
|
||||
/*
|
||||
* If we still have access to the event_data via handle,
|
||||
@ -599,7 +601,7 @@ static void etm_event_stop(struct perf_event *event, int mode)
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
sink = coresight_get_sink(path);
|
||||
sink = coresight_get_sink(&path->path_list);
|
||||
if (!sink)
|
||||
return;
|
||||
|
||||
@ -643,7 +645,7 @@ static void etm_event_stop(struct perf_event *event, int mode)
|
||||
}
|
||||
|
||||
/* Disabling the path make its elements available to other sessions */
|
||||
coresight_disable_path(path);
|
||||
coresight_disable_path(&path->path_list);
|
||||
}
|
||||
|
||||
static int etm_event_add(struct perf_event *event, int mode)
|
||||
|
||||
@ -59,7 +59,7 @@ struct etm_event_data {
|
||||
cpumask_t aux_hwid_done;
|
||||
void *snk_config;
|
||||
u32 cfg_hash;
|
||||
struct list_head * __percpu *path;
|
||||
struct coresight_path * __percpu *path;
|
||||
};
|
||||
|
||||
int etm_perf_symlink(struct coresight_device *csdev, bool link);
|
||||
|
||||
@ -139,9 +139,9 @@ struct coresight_device *coresight_get_sink(struct list_head *path);
|
||||
struct coresight_device *coresight_get_sink_by_id(u32 id);
|
||||
struct coresight_device *
|
||||
coresight_find_default_sink(struct coresight_device *csdev);
|
||||
struct list_head *coresight_build_path(struct coresight_device *csdev,
|
||||
struct coresight_device *sink);
|
||||
void coresight_release_path(struct list_head *path);
|
||||
struct coresight_path *coresight_build_path(struct coresight_device *csdev,
|
||||
struct coresight_device *sink);
|
||||
void coresight_release_path(struct coresight_path *path);
|
||||
int coresight_add_sysfs_link(struct coresight_sysfs_link *info);
|
||||
void coresight_remove_sysfs_link(struct coresight_sysfs_link *info);
|
||||
int coresight_create_conns_sysfs_group(struct coresight_device *csdev);
|
||||
|
||||
@ -22,7 +22,7 @@ static DEFINE_IDR(path_idr);
|
||||
* When operating Coresight drivers from the sysFS interface, only a single
|
||||
* path can exist from a tracer (associated to a CPU) to a sink.
|
||||
*/
|
||||
static DEFINE_PER_CPU(struct list_head *, tracer_path);
|
||||
static DEFINE_PER_CPU(struct coresight_path *, tracer_path);
|
||||
|
||||
ssize_t coresight_simple_show_pair(struct device *_dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@ -167,7 +167,7 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
|
||||
{
|
||||
int cpu, ret = 0;
|
||||
struct coresight_device *sink;
|
||||
struct list_head *path;
|
||||
struct coresight_path *path;
|
||||
enum coresight_dev_subtype_source subtype;
|
||||
u32 hash;
|
||||
|
||||
@ -209,7 +209,7 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = coresight_enable_path(path, CS_MODE_SYSFS, NULL);
|
||||
ret = coresight_enable_path(&path->path_list, CS_MODE_SYSFS, NULL);
|
||||
if (ret)
|
||||
goto err_path;
|
||||
|
||||
@ -251,7 +251,7 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
|
||||
return ret;
|
||||
|
||||
err_source:
|
||||
coresight_disable_path(path);
|
||||
coresight_disable_path(&path->path_list);
|
||||
|
||||
err_path:
|
||||
coresight_release_path(path);
|
||||
@ -262,7 +262,7 @@ EXPORT_SYMBOL_GPL(coresight_enable_sysfs);
|
||||
void coresight_disable_sysfs(struct coresight_device *csdev)
|
||||
{
|
||||
int cpu, ret;
|
||||
struct list_head *path = NULL;
|
||||
struct coresight_path *path = NULL;
|
||||
u32 hash;
|
||||
|
||||
mutex_lock(&coresight_mutex);
|
||||
@ -297,7 +297,7 @@ void coresight_disable_sysfs(struct coresight_device *csdev)
|
||||
break;
|
||||
}
|
||||
|
||||
coresight_disable_path(path);
|
||||
coresight_disable_path(&path->path_list);
|
||||
coresight_release_path(path);
|
||||
|
||||
out:
|
||||
|
||||
@ -329,6 +329,16 @@ static struct coresight_dev_list (var) = { \
|
||||
|
||||
#define to_coresight_device(d) container_of(d, struct coresight_device, dev)
|
||||
|
||||
/**
|
||||
* struct coresight_path - data needed by enable/disable path
|
||||
* @path_list: path from source to sink.
|
||||
* @trace_id: trace_id of the whole path.
|
||||
*/
|
||||
struct coresight_path {
|
||||
struct list_head path_list;
|
||||
u8 trace_id;
|
||||
};
|
||||
|
||||
enum cs_mode {
|
||||
CS_MODE_DISABLED,
|
||||
CS_MODE_SYSFS,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user