This patch adds a helper to insert barrier packets for a given size (aligned to packet size) at given offset in an etr_buf. This will be used later for perf mode when we try to start in the middle of an SG buffer.
Cc: Mathieu Poirier <mathieu.poir...@linaro.org> Signed-off-by: Suzuki K Poulose <suzuki.poul...@arm.com> --- drivers/hwtracing/coresight/coresight-tmc-etr.c | 53 ++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 7551272..8159e84 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1083,18 +1083,59 @@ static ssize_t tmc_etr_buf_get_data(struct etr_buf *etr_buf, return etr_buf->ops->get_data(etr_buf, (u64)offset, len, bufpp); } +/* + * tmc_etr_buf_insert_barrier_packets : Insert barrier packets at @offset upto + * @size of bytes in the given buffer. @size should be aligned to the barrier + * packet size. + * + * Returns the new @offset after filling the barriers on success. Otherwise + * returns error. + */ static inline s64 -tmc_etr_buf_insert_barrier_packet(struct etr_buf *etr_buf, u64 offset) +tmc_etr_buf_insert_barrier_packets(struct etr_buf *etr_buf, + u64 offset, u64 size) { ssize_t len; char *bufp; - len = tmc_etr_buf_get_data(etr_buf, offset, - CORESIGHT_BARRIER_PKT_SIZE, &bufp); - if (WARN_ON(len <= CORESIGHT_BARRIER_PKT_SIZE)) + if (size < CORESIGHT_BARRIER_PKT_SIZE) return -EINVAL; - coresight_insert_barrier_packet(bufp); - return offset + CORESIGHT_BARRIER_PKT_SIZE; + /* + * Normally the size should be aligned to the frame size + * of the ETR. Even if it isn't, the decoder looks for a + * barrier packet at a frame size aligned offset. So align + * the buffer to frame size first and then fill barrier + * packets. + */ + do { + len = tmc_etr_buf_get_data(etr_buf, offset, size, &bufp); + if (WARN_ON(len <= 0)) + return -EINVAL; + /* + * We are guaranteed that @bufp will point to a linear range + * of @len bytes, where @len <= @size. + */ + size -= len; + offset += len; + while (len >= CORESIGHT_BARRIER_PKT_SIZE) { + coresight_insert_barrier_packet(bufp); + bufp += CORESIGHT_BARRIER_PKT_SIZE; + len -= CORESIGHT_BARRIER_PKT_SIZE; + } + + /* If we reached the end of the buffer, wrap around */ + if (offset == etr_buf->size) + offset -= etr_buf->size; + } while (size); + + return offset; +} + +static inline s64 +tmc_etr_buf_insert_barrier_packet(struct etr_buf *etr_buf, u64 offset) +{ + return tmc_etr_buf_insert_barrier_packets(etr_buf, offset, + CORESIGHT_BARRIER_PKT_SIZE); } /* -- 2.7.4