Commit 7ec786ad authored by Suzuki K Poulose's avatar Suzuki K Poulose Committed by Greg Kroah-Hartman

coresight: perf: Remove reset_buffer call back for sinks

Right now we issue an update_buffer() and reset_buffer() call backs
in succession when we stop tracing an event. The update_buffer is
supposed to check the status of the buffer and make sure the ring buffer
is updated with the trace data. And we store information about the
size of the data collected only to be consumed by the reset_buffer
callback which always follows the update_buffer. This was originally
designed for handling future IPs which could trigger a buffer overflow
interrupt. This patch gets rid of the reset_buffer callback altogether
and performs the actions in update_buffer, making it return the size
collected. We can always add the support for handling the overflow
interrupt case later.

This removes some not-so pretty hack (storing the new head in the
size field for snapshot mode) and cleans it up a little bit.

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 41a75cdd
...@@ -319,37 +319,7 @@ static int etb_set_buffer(struct coresight_device *csdev, ...@@ -319,37 +319,7 @@ static int etb_set_buffer(struct coresight_device *csdev,
return ret; return ret;
} }
static unsigned long etb_reset_buffer(struct coresight_device *csdev, static unsigned long etb_update_buffer(struct coresight_device *csdev,
struct perf_output_handle *handle,
void *sink_config)
{
unsigned long size = 0;
struct cs_buffers *buf = sink_config;
if (buf) {
/*
* In snapshot mode ->data_size holds the new address of the
* ring buffer's head. The size itself is the whole address
* range since we want the latest information.
*/
if (buf->snapshot)
handle->head = local_xchg(&buf->data_size,
buf->nr_pages << PAGE_SHIFT);
/*
* Tell the tracer PMU how much we got in this run and if
* something went wrong along the way. Nobody else can use
* this cs_buffers instance until we are done. As such
* resetting parameters here and squaring off with the ring
* buffer API in the tracer PMU is fine.
*/
size = local_xchg(&buf->data_size, 0);
}
return size;
}
static void etb_update_buffer(struct coresight_device *csdev,
struct perf_output_handle *handle, struct perf_output_handle *handle,
void *sink_config) void *sink_config)
{ {
...@@ -358,13 +328,13 @@ static void etb_update_buffer(struct coresight_device *csdev, ...@@ -358,13 +328,13 @@ static void etb_update_buffer(struct coresight_device *csdev,
u8 *buf_ptr; u8 *buf_ptr;
const u32 *barrier; const u32 *barrier;
u32 read_ptr, write_ptr, capacity; u32 read_ptr, write_ptr, capacity;
u32 status, read_data, to_read; u32 status, read_data;
unsigned long offset; unsigned long offset, to_read;
struct cs_buffers *buf = sink_config; struct cs_buffers *buf = sink_config;
struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
if (!buf) if (!buf)
return; return 0;
capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS; capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS;
...@@ -469,18 +439,17 @@ static void etb_update_buffer(struct coresight_device *csdev, ...@@ -469,18 +439,17 @@ static void etb_update_buffer(struct coresight_device *csdev,
writel_relaxed(0x0, drvdata->base + ETB_RAM_WRITE_POINTER); writel_relaxed(0x0, drvdata->base + ETB_RAM_WRITE_POINTER);
/* /*
* In snapshot mode all we have to do is communicate to * In snapshot mode we have to update the handle->head to point
* perf_aux_output_end() the address of the current head. In full * to the new location.
* trace mode the same function expects a size to move rb->aux_head
* forward.
*/ */
if (buf->snapshot) if (buf->snapshot) {
local_set(&buf->data_size, (cur * PAGE_SIZE) + offset); handle->head = (cur * PAGE_SIZE) + offset;
else to_read = buf->nr_pages << PAGE_SHIFT;
local_add(to_read, &buf->data_size); }
etb_enable_hw(drvdata); etb_enable_hw(drvdata);
CS_LOCK(drvdata->base); CS_LOCK(drvdata->base);
return to_read;
} }
static const struct coresight_ops_sink etb_sink_ops = { static const struct coresight_ops_sink etb_sink_ops = {
...@@ -489,7 +458,6 @@ static const struct coresight_ops_sink etb_sink_ops = { ...@@ -489,7 +458,6 @@ static const struct coresight_ops_sink etb_sink_ops = {
.alloc_buffer = etb_alloc_buffer, .alloc_buffer = etb_alloc_buffer,
.free_buffer = etb_free_buffer, .free_buffer = etb_free_buffer,
.set_buffer = etb_set_buffer, .set_buffer = etb_set_buffer,
.reset_buffer = etb_reset_buffer,
.update_buffer = etb_update_buffer, .update_buffer = etb_update_buffer,
}; };
......
...@@ -369,15 +369,8 @@ static void etm_event_stop(struct perf_event *event, int mode) ...@@ -369,15 +369,8 @@ static void etm_event_stop(struct perf_event *event, int mode)
if (!sink_ops(sink)->update_buffer) if (!sink_ops(sink)->update_buffer)
return; return;
sink_ops(sink)->update_buffer(sink, handle, size = sink_ops(sink)->update_buffer(sink, handle,
event_data->snk_config); event_data->snk_config);
if (!sink_ops(sink)->reset_buffer)
return;
size = sink_ops(sink)->reset_buffer(sink, handle,
event_data->snk_config);
perf_aux_output_end(handle, size); perf_aux_output_end(handle, size);
} }
......
...@@ -349,36 +349,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev, ...@@ -349,36 +349,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev,
return ret; return ret;
} }
static unsigned long tmc_reset_etf_buffer(struct coresight_device *csdev, static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
struct perf_output_handle *handle,
void *sink_config)
{
long size = 0;
struct cs_buffers *buf = sink_config;
if (buf) {
/*
* In snapshot mode ->data_size holds the new address of the
* ring buffer's head. The size itself is the whole address
* range since we want the latest information.
*/
if (buf->snapshot)
handle->head = local_xchg(&buf->data_size,
buf->nr_pages << PAGE_SHIFT);
/*
* Tell the tracer PMU how much we got in this run and if
* something went wrong along the way. Nobody else can use
* this cs_buffers instance until we are done. As such
* resetting parameters here and squaring off with the ring
* buffer API in the tracer PMU is fine.
*/
size = local_xchg(&buf->data_size, 0);
}
return size;
}
static void tmc_update_etf_buffer(struct coresight_device *csdev,
struct perf_output_handle *handle, struct perf_output_handle *handle,
void *sink_config) void *sink_config)
{ {
...@@ -387,17 +358,17 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, ...@@ -387,17 +358,17 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
const u32 *barrier; const u32 *barrier;
u32 *buf_ptr; u32 *buf_ptr;
u64 read_ptr, write_ptr; u64 read_ptr, write_ptr;
u32 status, to_read; u32 status;
unsigned long offset; unsigned long offset, to_read;
struct cs_buffers *buf = sink_config; struct cs_buffers *buf = sink_config;
struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
if (!buf) if (!buf)
return; return 0;
/* This shouldn't happen */ /* This shouldn't happen */
if (WARN_ON_ONCE(drvdata->mode != CS_MODE_PERF)) if (WARN_ON_ONCE(drvdata->mode != CS_MODE_PERF))
return; return 0;
CS_UNLOCK(drvdata->base); CS_UNLOCK(drvdata->base);
...@@ -486,18 +457,14 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, ...@@ -486,18 +457,14 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
} }
} }
/* /* In snapshot mode we have to update the head */
* In snapshot mode all we have to do is communicate to if (buf->snapshot) {
* perf_aux_output_end() the address of the current head. In full handle->head = (cur * PAGE_SIZE) + offset;
* trace mode the same function expects a size to move rb->aux_head to_read = buf->nr_pages << PAGE_SHIFT;
* forward. }
*/
if (buf->snapshot)
local_set(&buf->data_size, (cur * PAGE_SIZE) + offset);
else
local_add(to_read, &buf->data_size);
CS_LOCK(drvdata->base); CS_LOCK(drvdata->base);
return to_read;
} }
static const struct coresight_ops_sink tmc_etf_sink_ops = { static const struct coresight_ops_sink tmc_etf_sink_ops = {
...@@ -506,7 +473,6 @@ static const struct coresight_ops_sink tmc_etf_sink_ops = { ...@@ -506,7 +473,6 @@ static const struct coresight_ops_sink tmc_etf_sink_ops = {
.alloc_buffer = tmc_alloc_etf_buffer, .alloc_buffer = tmc_alloc_etf_buffer,
.free_buffer = tmc_free_etf_buffer, .free_buffer = tmc_free_etf_buffer,
.set_buffer = tmc_set_etf_buffer, .set_buffer = tmc_set_etf_buffer,
.reset_buffer = tmc_reset_etf_buffer,
.update_buffer = tmc_update_etf_buffer, .update_buffer = tmc_update_etf_buffer,
}; };
......
...@@ -186,7 +186,6 @@ struct coresight_device { ...@@ -186,7 +186,6 @@ struct coresight_device {
* @alloc_buffer: initialises perf's ring buffer for trace collection. * @alloc_buffer: initialises perf's ring buffer for trace collection.
* @free_buffer: release memory allocated in @get_config. * @free_buffer: release memory allocated in @get_config.
* @set_buffer: initialises buffer mechanic before a trace session. * @set_buffer: initialises buffer mechanic before a trace session.
* @reset_buffer: finalises buffer mechanic after a trace session.
* @update_buffer: update buffer pointers after a trace session. * @update_buffer: update buffer pointers after a trace session.
*/ */
struct coresight_ops_sink { struct coresight_ops_sink {
...@@ -198,10 +197,7 @@ struct coresight_ops_sink { ...@@ -198,10 +197,7 @@ struct coresight_ops_sink {
int (*set_buffer)(struct coresight_device *csdev, int (*set_buffer)(struct coresight_device *csdev,
struct perf_output_handle *handle, struct perf_output_handle *handle,
void *sink_config); void *sink_config);
unsigned long (*reset_buffer)(struct coresight_device *csdev, unsigned long (*update_buffer)(struct coresight_device *csdev,
struct perf_output_handle *handle,
void *sink_config);
void (*update_buffer)(struct coresight_device *csdev,
struct perf_output_handle *handle, struct perf_output_handle *handle,
void *sink_config); void *sink_config);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment