From patchwork Sun Oct 18 18:24:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Poirier X-Patchwork-Id: 55206 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f198.google.com (mail-wi0-f198.google.com [209.85.212.198]) by patches.linaro.org (Postfix) with ESMTPS id E570E22FFA for ; Sun, 18 Oct 2015 18:28:58 +0000 (UTC) Received: by wibhd5 with SMTP id hd5sf1045077wib.0 for ; Sun, 18 Oct 2015 11:28:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=cDuKehF61Dsi/UcSveFV6OrMwjl5H7bzfvo/B1lk4vY=; b=Ax7SmtobmBeGoEuWvtkiBJaqhUMCkI2x8/4Hwe5c7FPIS7FIumYJT5nl4L1jTcNdO1 PDx4rSJ4vLIekerpgT1ExHpEltBDqsx7akDAJFQYdX35fbBXF6QwZPLjPUmEGKmI2OdQ poVDRzxIcVe1YNJJY2wIWDkqfupgKN91JZLDilMVEpzzgBrMl0DQ853S/3o4BIgOjXcA T6NVN4ZswbTZeobS5jIZ6UVY6kFs4cFlxvkH2Y6rusAbZuT9pS6Zdy2Axo/G2ToT1uv2 yUdqnPeextPGZC0J1lfThBqkWHMYwHZu1PrmPjjNDZjWksTDaUuzN7X0ADrQws0nXP/5 786Q== X-Gm-Message-State: ALoCoQn7EgeoLMNtAX4P/1Lw10vwxhEfFf8U+Gm857C07qOvcD+ORmQfqqMvYD1C5m1Zz79kseKX X-Received: by 10.112.159.4 with SMTP id wy4mr6001217lbb.15.1445192938232; Sun, 18 Oct 2015 11:28:58 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.25.142.3 with SMTP id q3ls457499lfd.64.gmail; Sun, 18 Oct 2015 11:28:58 -0700 (PDT) X-Received: by 10.25.205.198 with SMTP id d189mr8296969lfg.72.1445192938061; Sun, 18 Oct 2015 11:28:58 -0700 (PDT) Received: from mail-lb0-f175.google.com (mail-lb0-f175.google.com. [209.85.217.175]) by mx.google.com with ESMTPS id c7si20115035lbd.63.2015.10.18.11.28.58 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 18 Oct 2015 11:28:58 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.175 as permitted sender) client-ip=209.85.217.175; Received: by lbcao8 with SMTP id ao8so127467769lbc.3 for ; Sun, 18 Oct 2015 11:28:58 -0700 (PDT) X-Received: by 10.112.159.136 with SMTP id xc8mr10213246lbb.76.1445192937930; Sun, 18 Oct 2015 11:28:57 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp1078666lbq; Sun, 18 Oct 2015 11:28:56 -0700 (PDT) X-Received: by 10.68.68.197 with SMTP id y5mr29653816pbt.88.1445192936715; Sun, 18 Oct 2015 11:28:56 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id cw4si46466294pbc.229.2015.10.18.11.28.56; Sun, 18 Oct 2015 11:28:56 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753091AbbJRS2x (ORCPT + 28 others); Sun, 18 Oct 2015 14:28:53 -0400 Received: from mail-pa0-f48.google.com ([209.85.220.48]:32970 "EHLO mail-pa0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752485AbbJRS0J (ORCPT ); Sun, 18 Oct 2015 14:26:09 -0400 Received: by pabrc13 with SMTP id rc13so167571117pab.0 for ; Sun, 18 Oct 2015 11:26:08 -0700 (PDT) X-Received: by 10.66.90.233 with SMTP id bz9mr29476984pab.14.1445192768517; Sun, 18 Oct 2015 11:26:08 -0700 (PDT) Received: from t430.cg.shawcable.net (S0106002369de4dac.cg.shawcable.net. [184.64.168.246]) by smtp.gmail.com with ESMTPSA id hq1sm20402076pbb.43.2015.10.18.11.26.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 18 Oct 2015 11:26:08 -0700 (PDT) From: Mathieu Poirier To: gregkh@linuxfoundation.org, a.p.zijlstra@chello.nl, alexander.shishkin@linux.intel.com, acme@kernel.org, mingo@redhat.com, corbet@lwn.net, nicolas.pitre@linaro.org Cc: adrian.hunter@intel.com, zhang.chunyan@linaro.org, mike.leach@arm.com, tor@ti.com, al.grant@arm.com, pawel.moll@arm.com, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, mathieu.poirier@linaro.org Subject: [PATCH V2 21/30] coresight: etb10: implementing buffer update API Date: Sun, 18 Oct 2015 12:24:38 -0600 Message-Id: <1445192687-24112-22-git-send-email-mathieu.poirier@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1445192687-24112-1-git-send-email-mathieu.poirier@linaro.org> References: <1445192687-24112-1-git-send-email-mathieu.poirier@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: mathieu.poirier@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.175 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Implementing buffer API to update the location of the ETB internal ring buffer once a trace session has ended. Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etb10.c | 128 ++++++++++++++++++++++++++ include/linux/coresight.h | 14 ++- 2 files changed, 137 insertions(+), 5 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index ca2c4b42464d..8e469d097955 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -362,12 +363,139 @@ static void etb_reset_buffer(struct coresight_device *csdev, local_set(&drvdata->in_use, 0); } +static void etb_update_buffer(struct coresight_device *csdev, + struct perf_output_handle *handle, + void *sink_config) +{ + int i, cur; + u8 *buf_ptr; + u32 read_ptr, write_ptr, start; + u32 status, read_data, words; + unsigned long flags, offset; + struct cs_buffers *buf = sink_config; + struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + if (!buf) + return; + + spin_lock_irqsave(&drvdata->spinlock, flags); + if (!drvdata->enable) + goto out; + + etb_disable_hw(drvdata); + CS_UNLOCK(drvdata->base); + + /* unit is in words, not bytes */ + read_ptr = readl_relaxed(drvdata->base + ETB_RAM_READ_POINTER); + write_ptr = readl_relaxed(drvdata->base + ETB_RAM_WRITE_POINTER); + + /* + * Entries should be aligned to the frame size. If they are not + * go back to the last alignement point to give decoding tools a + * chance to fix things. + */ + if (write_ptr % ETB_FRAME_SIZE_WORDS) { + dev_err(drvdata->dev, + "write_ptr: %lu not aligned to formatter frame size\n", + (unsigned long)write_ptr); + + write_ptr &= ~ETB_FRAME_SIZE_WORDS; + local_inc(&buf->lost); + } + + /* + * Get a hold of the status register and see if a wrap around + * has occurred. If so adjust things accordingly. Otherwise + * start at the beginning and go until the write pointer has + * been reached. + */ + status = readl_relaxed(drvdata->base + ETB_STATUS_REG); + if (status & ETB_STATUS_RAM_FULL) { + local_inc(&buf->lost); + words = drvdata->buffer_depth; + start = write_ptr; + } else { + words = CIRC_CNT(write_ptr, read_ptr, drvdata->buffer_depth); + start = read_ptr; + } + + /* + * Make sure we don't overwrite data that hasn't been consumed yet. + * It is entirely possible that the HW buffer has more data than the + * ring buffer can currently handle. If so adjust the start address + * to take only the last traces. + * + * In snapshot mode we are looking to get the latest traces only and as + * such, we don't care about not overwriting data that hasn't been + * processed by user space. + * + * Since metrics related to ETBs is in words, multiply by the + * amount of byte per word to have the right units. + */ + if (!buf->snapshot && words * ETB_FRAME_SIZE_WORDS > handle->size) { + unsigned int capacity = drvdata->buffer_depth; + + /* make sure new sizes are still multiples the frame size */ + words = handle->size / ETB_FRAME_SIZE_WORDS; + /* advance the start pointer to get the latest trace data */ + start += capacity - words; + /* wrap around if we've reach the end of the HW buffer */ + start &= capacity - 1; + /* let the decoder know we've skipped ahead */ + local_inc(&buf->lost); + } + + /* finally tell HW where we want to start reading from */ + writel_relaxed(start, drvdata->base + ETB_RAM_READ_POINTER); + + cur = buf->cur; + offset = buf->offset; + for (i = 0; i < words; i++) { + buf_ptr = buf->addr[cur] + offset; + read_data = readl_relaxed(drvdata->base + + ETB_RAM_READ_DATA_REG); + *buf_ptr++ = read_data >> 0; + *buf_ptr++ = read_data >> 8; + *buf_ptr++ = read_data >> 16; + *buf_ptr++ = read_data >> 24; + + offset += 4; + if (offset >= PAGE_SIZE) { + offset = 0; + cur++; + /* wrap around at the end of the buffer */ + cur &= buf->nr_pages - 1; + } + } + + /* reset ETB buffer for next run */ + writel_relaxed(0x0, drvdata->base + ETB_RAM_READ_POINTER); + writel_relaxed(0x0, drvdata->base + ETB_RAM_WRITE_POINTER); + + /* + * In snapshot mode all we have to do is communicate to + * perf_aux_output_end() the address of the current head. In full + * trace mode the same function expects a size to move rb->aux_head + * forward. + */ + if (buf->snapshot) + local_set(&buf->data_size, (cur * PAGE_SIZE) + offset); + else + local_add(words * ETB_FRAME_SIZE_WORDS, &buf->data_size); + + CS_LOCK(drvdata->base); + etb_enable_hw(drvdata); +out: + spin_unlock_irqrestore(&drvdata->spinlock, flags); +} + static const struct coresight_ops_sink etb_sink_ops = { .enable = etb_enable, .disable = etb_disable, .setup_aux = etb_setup_aux, .set_buffer = etb_set_buffer, .reset_buffer = etb_reset_buffer, + .update_buffer = etb_update_buffer, }; static const struct coresight_ops etb_cs_ops = { diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 78202d5ea58a..cdf401d51998 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -186,11 +186,12 @@ struct coresight_device { /** * struct coresight_ops_sink - basic operations for a sink * Operations available for sinks - * @enable: enables the sink. - * @disable: disables the sink. - * @setup_aux: initialises perf's ring buffer for trace collection. - * @set_buffer: initialises buffer mechanic before a trace session. - * @reset_buffer: finalises buffer mechanic after a trace session. + * @enable: enables the sink. + * @disable: disables the sink. + * @setup_aux: initialises perf's ring buffer for trace collection. + * @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. */ struct coresight_ops_sink { int (*enable)(struct coresight_device *csdev); @@ -203,6 +204,9 @@ struct coresight_ops_sink { void (*reset_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, + void *sink_config); }; /**