From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57A7EC433ED for ; Wed, 5 May 2021 07:24:39 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 987DC61168 for ; Wed, 5 May 2021 07:24:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 987DC61168 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References:Message-ID: Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=gU9rvgYC9fLI5k66E/Gp1hWqca8ngXUEzNq2anpHC90=; b=o0/Xc7zOyHPIf1f6oTSMLhxLV Lqc2hEdWwwRjgpzCcMGLqO+0/+dFV9UEKykeHAksCeARMwK6wJAEQi2K65pbNRIZY/5njXE0THfhq QIYNNznrqSuMSrkcYl9rIjiUwt00SeJSktNbW26nmNMy5tiHPUWdS65wDhYxahDRll8zN1M6+SB+1 77tgzWKLa1GEumABVIYVILZTtr5qYttbHiNiVAEJmB2Rl/0KWBqDO0Z6DtDKiAKXvDK5cHjBzy5oQ CQBdhg5OP1sccB8BPGIOOtDs4YDBjsxFMuM+QvhKAUw5c9rUsxc42h6lHM25UEVcG5ZrBMAcVkhBV HDRbZsUhA==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1leBrN-000Rtw-P7; Wed, 05 May 2021 07:22:18 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1leBrD-000RsR-5I for linux-arm-kernel@desiato.infradead.org; Wed, 05 May 2021 07:22:07 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=In-Reply-To:Content-Type:MIME-Version :References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=XnCJ982vdxzQuF3DGk0AZWtZQoNufcY4tmgQrfrTfCg=; b=VvRdJe6NLdEwvmUa6fnzB9V+ta c14K2Spt1K4X2XPXocE60yDlhQEy39XhmRdhEnE+rQH/Y1RLdN4TNyATFSqGcsO/W4oa4pWx8xPaf OKuBTI86jhuHGG9yptGDsThn20WWzHAjOSfBx1T6WrAXwCPsh1roXbq1jQwn0wjf69zNCgvHNciNn vjGF+WdRzaEEyZSuW1nK/dqEi8FhGL9US/Ffmq2forizaWSr4oqceLoOYps29yYKBlKNG/0AYqaTu Lsc+zgRy6uEp/Dp1KhsD99NVTiXEFyeklMCv2wcPugxtPDBHnmuSgVBYggfTVvvsQnVIUq3tit6zG cFrH1zdA==; Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1leBr9-004Wk0-9P for linux-arm-kernel@lists.infradead.org; Wed, 05 May 2021 07:22:05 +0000 Received: by mail-pl1-x634.google.com with SMTP id p17so627211plf.12 for ; Wed, 05 May 2021 00:22:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=XnCJ982vdxzQuF3DGk0AZWtZQoNufcY4tmgQrfrTfCg=; b=oZWdHwCWoreoOXlYZn+XaIA4gCRFC18xPGGgt4z9Yd/+TTOhPQayspGQo6gpI/SJFN 6+jTaW2BM6bk7FvLRqXjpsed8+NYca88SrrlwfgeWt+g0Mfgzv4zQGGh6ppZ/T7kO6tB k7c/7fUTg9LvSJCmR6j5h41PNbF6raSENMqQY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=XnCJ982vdxzQuF3DGk0AZWtZQoNufcY4tmgQrfrTfCg=; b=WV3Mev1ozk5aJxh5b+EBrMBzZkit/G/o5ymXCvgSCj4Xp8iQJZCvEP5d4rz6nmvOs5 PZnJRQMFLDFeSf1phJ6b67nrO1PyAeeFTdeBN/cnapaGS0SjOH8F9bsaaC0eLvdV8LzB 25wKmFpSvRX2nZF18DDCEuO4RgBH45IEV+q++B++TSDziiVjydzQIvSlQX5+M0qK7fQM DLa6jRDK1pXpXHRCJy3ItVnEMMRLJCDkJhXnhgPn9WkIpcdXZH//+6sZYXk9VGgmdxgZ 7Luf6ykWlyMYOvUg4dZ1zOvyNs2k+OH2MFe9k2Zkich5eOD4G6GPQbulRfRpRzdtFZyK Fpqw== X-Gm-Message-State: AOAM533eqSV9ytjSljgFICaVYNBifgXOI5O5fPAUX3niLXQtv0nVR2cS JTHHkRu4SCCfIUbJCWD8MMJw+g== X-Google-Smtp-Source: ABdhPJzA1BMjrU2XJr115Z1N+s1pJuvwLTN6l9l0Io83XNEuM5uXTPBx9zwF93CSvk6ApPwgl+/rqA== X-Received: by 2002:a17:90b:3615:: with SMTP id ml21mr9932903pjb.28.1620199321021; Wed, 05 May 2021 00:22:01 -0700 (PDT) Received: from google.com ([2620:15c:2ce:200:90e0:a7d5:38c7:10c8]) by smtp.gmail.com with ESMTPSA id v21sm1346321pgh.12.2021.05.05.00.21.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 May 2021 00:22:00 -0700 (PDT) Date: Wed, 5 May 2021 00:21:58 -0700 From: Denis Nikitin To: Daniel Kiss Cc: mathieu.poirier@linaro.org, suzuki.poulose@arm.com, mike.leach@linaro.org, leo.yan@linaro.org, coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, Branislav Rankov Subject: Re: [PATCH 4/4] coresight: Add ETR-PERF polling. Message-ID: References: <20210421120413.3110775-1-daniel.kiss@arm.com> <20210421120413.3110775-5-daniel.kiss@arm.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20210421120413.3110775-5-daniel.kiss@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210505_002203_403821_3CCF4211 X-CRM114-Status: GOOD ( 37.64 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Wed, Apr 21, 2021 at 02:04:13PM +0200, Daniel Kiss wrote: > ETR might fill up the buffer sooner than an event makes perf to trigger > the synchronisation especially in system wide trace. Polling runs > periodically to sync the ETR buffer. Period is configurable via sysfs, > disabled by default. > > Signed-off-by: Daniel Kiss > Signed-off-by: Branislav Rankov Tested-by: Denis Nikitin Thanks, Denis > --- > .../testing/sysfs-bus-coresight-devices-tmc | 8 + > drivers/hwtracing/coresight/Makefile | 2 +- > .../hwtracing/coresight/coresight-etm-perf.c | 8 + > .../coresight/coresight-etr-perf-polling.c | 316 ++++++++++++++++++ > .../coresight/coresight-etr-perf-polling.h | 42 +++ > .../hwtracing/coresight/coresight-tmc-core.c | 2 + > .../hwtracing/coresight/coresight-tmc-etr.c | 9 + > 7 files changed, 386 insertions(+), 1 deletion(-) > create mode 100644 drivers/hwtracing/coresight/coresight-etr-perf-polling.c > create mode 100644 drivers/hwtracing/coresight/coresight-etr-perf-polling.h > > diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc > index 6aa527296c710..4ca7af22a3686 100644 > --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc > +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc > @@ -91,3 +91,11 @@ Contact: Mathieu Poirier > Description: (RW) Size of the trace buffer for TMC-ETR when used in SYSFS > mode. Writable only for TMC-ETR configurations. The value > should be aligned to the kernel pagesize. > + > +What: /sys/bus/coresight/devices/.tmc/polling/period > +Date: April 2021 > +KernelVersion: 5.13 > +Contact: Daniel Kiss > +Description: (RW) Time in milliseconds when the TMC-ETR is synced. > + Default value is 0, means the feature is disabled. > + Writable only for TMC-ETR configurations. > diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile > index d60816509755c..4df90b71d98cd 100644 > --- a/drivers/hwtracing/coresight/Makefile > +++ b/drivers/hwtracing/coresight/Makefile > @@ -4,7 +4,7 @@ > # > obj-$(CONFIG_CORESIGHT) += coresight.o > coresight-y := coresight-core.o coresight-etm-perf.o coresight-platform.o \ > - coresight-sysfs.o > + coresight-sysfs.o coresight-etr-perf-polling.o > obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o > coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \ > coresight-tmc-etr.o > diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c > index 78a55fc2bcab5..910a99944eea8 100644 > --- a/drivers/hwtracing/coresight/coresight-etm-perf.c > +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c > @@ -19,6 +19,7 @@ > #include > > #include "coresight-etm-perf.h" > +#include "coresight-etr-perf-polling.h" > #include "coresight-priv.h" > > static struct pmu etm_pmu; > @@ -438,6 +439,8 @@ static void etm_event_start(struct perf_event *event, int flags) > /* Tell the perf core the event is alive */ > event->hw.state = 0; > > + etr_perf_polling_event_start(event, event_data, handle); > + > /* Finally enable the tracer */ > if (source_ops(csdev)->enable(csdev, event, CS_MODE_PERF)) > goto fail_disable_path; > @@ -497,6 +500,8 @@ static void etm_event_stop(struct perf_event *event, int mode) > if (!sink) > return; > > + etr_perf_polling_event_stop(event, event_data); > + > /* stop tracer */ > source_ops(csdev)->disable(csdev, event); > > @@ -741,6 +746,8 @@ int __init etm_perf_init(void) > etm_pmu.addr_filters_validate = etm_addr_filters_validate; > etm_pmu.nr_addr_filters = ETM_ADDR_CMP_MAX; > > + etr_perf_polling_init(); > + > ret = perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1); > if (ret == 0) > etm_perf_up = true; > @@ -750,5 +757,6 @@ int __init etm_perf_init(void) > > void __exit etm_perf_exit(void) > { > + etr_perf_polling_exit(); > perf_pmu_unregister(&etm_pmu); > } > diff --git a/drivers/hwtracing/coresight/coresight-etr-perf-polling.c b/drivers/hwtracing/coresight/coresight-etr-perf-polling.c > new file mode 100644 > index 0000000000000..aa0352908873a > --- /dev/null > +++ b/drivers/hwtracing/coresight/coresight-etr-perf-polling.c > @@ -0,0 +1,316 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright(C) 2021 Arm Limited. All rights reserved. > + * Author: Daniel Kiss > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "coresight-etr-perf-polling.h" > +#include "coresight-priv.h" > +#include "coresight-tmc.h" > + > +#if defined(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) || \ > + defined(CONFIG_CORESIGHT_LINK_AND_SINK_TMC_MODULE) > + > +struct polling_event_list { > + struct perf_event *perf_event; > + struct etm_event_data *etm_event_data; > + struct perf_output_handle *ctx_handle; > + void (*tmc_etr_reset_hw)(struct tmc_drvdata *); > + struct list_head list; > +}; > + > +struct polling { > + int cpu; > + struct list_head polled_events; > + struct delayed_work delayed_work; > +}; > + > +static atomic_t period; > +static spinlock_t spinlock_re; > +static struct list_head registered_events; > + > +static DEFINE_PER_CPU(struct polling, polling); > + > +static ssize_t period_show(struct device *dev, struct device_attribute *attr, > + char *buf) > +{ > + int temp; > + struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent); > + > + if (drvdata->config_type != TMC_CONFIG_TYPE_ETR) > + return -EPERM; > + > + temp = atomic_read(&period); > + return sprintf(buf, "%i\n", temp); > +} > + > +static ssize_t period_store(struct device *dev, struct device_attribute *attr, > + const char *buf, size_t count) > +{ > + int temp = 0; > + struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent); > + > + if (drvdata->config_type != TMC_CONFIG_TYPE_ETR) > + return -EPERM; > + > + if ((1 == sscanf(buf, "%i", &temp)) && (temp >= 0)) > + atomic_set(&period, temp); > + return count; > +} > + > +static DEVICE_ATTR_RW(period); > + > +static struct attribute *coresight_tmc_polling_attrs[] = { > + &dev_attr_period.attr, > + NULL, > +}; > +const struct attribute_group coresight_tmc_polling_group = { > + .attrs = coresight_tmc_polling_attrs, > + .name = "polling", > +}; > +EXPORT_SYMBOL_GPL(coresight_tmc_polling_group); > + > +static inline void polling_sched_worker(struct polling *p) > +{ > + int tickrate = atomic_read(&period); > + if (!list_empty(&p->polled_events) && (tickrate > 0)) > + schedule_delayed_work_on(p->cpu, &p->delayed_work, > + msecs_to_jiffies(tickrate)); > +} > + > +static inline bool is_etr_related(struct etm_event_data *etm_event_data, int cpu) > +{ > + struct list_head *path; > + struct coresight_device *sink; > + struct tmc_drvdata *drvdata; > + path = etm_event_cpu_path(etm_event_data, cpu); > + if (WARN_ON(!path)) > + return false; > + sink = coresight_get_sink(path); > + if (WARN_ON(!sink)) > + return false; > + drvdata = dev_get_drvdata(sink->dev.parent); > + if (drvdata->config_type != TMC_CONFIG_TYPE_ETR) > + return false; > + return true; > +} > + > +/* > + * Adds the event to the polled events list. > + */ > +void etr_perf_polling_event_start(struct perf_event *event, > + struct etm_event_data *etm_event_data, > + struct perf_output_handle *ctx_handle) > +{ > + int cpu = smp_processor_id(); > + struct polling *p = per_cpu_ptr(&polling, cpu); > + struct polling_event_list *element; > + struct list_head *i, *tmp; > + > + if (!is_etr_related(etm_event_data, cpu)) > + return; > + > + spin_lock(&spinlock_re); > + list_for_each_safe (i, tmp, ®istered_events) { > + element = list_entry(i, struct polling_event_list, list); > + if (element->ctx_handle == ctx_handle) { > + element->perf_event = event; > + element->etm_event_data = etm_event_data; > + list_del(&element->list); > + spin_unlock(&spinlock_re); > + list_add(&element->list, &p->polled_events); > + polling_sched_worker(p); > + return; > + } > + } > + spin_unlock(&spinlock_re); > +} > +EXPORT_SYMBOL_GPL(etr_perf_polling_event_start); > + > +/* > + * Removes the event from the to be polled events list. > + */ > +void etr_perf_polling_event_stop(struct perf_event *event, > + struct etm_event_data *etm_event_data) > +{ > + int cpu = smp_processor_id(); > + struct list_head *i, *tmp; > + struct polling *p = per_cpu_ptr(&polling, cpu); > + > + if (!is_etr_related(etm_event_data, cpu)) > + return; > + > + list_for_each_safe (i, tmp, &p->polled_events) { > + struct polling_event_list *element = > + list_entry(i, struct polling_event_list, list); > + if (element->perf_event == event) { > + list_del(&element->list); > + element->perf_event = NULL; > + element->etm_event_data = NULL; > + spin_lock(&spinlock_re); > + list_add(&element->list, ®istered_events); > + spin_unlock(&spinlock_re); > + if (list_empty(&p->polled_events)) { > + cancel_delayed_work(&p->delayed_work); > + } > + return; > + } > + } > +} > +EXPORT_SYMBOL_GPL(etr_perf_polling_event_stop); > + > +/* > + * The polling worker is a workqueue job which is periodically > + * woken up to update the perf aux buffer from the etr shrink. > + */ > +static void etr_perf_polling_worker(struct work_struct *work) > +{ > + unsigned long flags; > + int cpu = smp_processor_id(); > + struct polling *p = per_cpu_ptr(&polling, cpu); > + struct list_head *i, *tmp; > + > + if (!atomic_read(&period)) > + return; > + > + /* > + * Scheduling would do the same from the perf hooks, > + * this should be done in one go. > + */ > + local_irq_save(flags); > + preempt_disable(); > + /* Perf requires rcu lock. */ > + rcu_read_lock(); > + > + polling_sched_worker(p); > + > + list_for_each_safe (i, tmp, &p->polled_events) { > + struct list_head *path; > + struct coresight_device *sink; > + struct polling_event_list *element = > + list_entry(i, struct polling_event_list, list); > + > + path = etm_event_cpu_path(element->etm_event_data, cpu); > + if (WARN_ON(!path)) > + continue; > + sink = coresight_get_sink(path); > + if (WARN_ON(!sink)) > + continue; > + if (sink_ops(sink)->update_buffer) { > + int size, refcnt; > + struct tmc_drvdata *drvdata = dev_get_drvdata(sink->dev.parent); > + > + /* > + * Act as now we are the only users of the sink. Due to the locks > + * we are safe. > + */ > + refcnt = atomic_xchg(sink->refcnt, 1); > + size = sink_ops(sink)->update_buffer( > + sink, element->ctx_handle, > + element->etm_event_data->snk_config); > + refcnt = atomic_xchg(sink->refcnt, refcnt); > + /* > + * Restart the trace. > + */ > + if (element->tmc_etr_reset_hw) > + element->tmc_etr_reset_hw(drvdata); > + > + WARN_ON(size < 0); > + if (size > 0) { > + struct etm_event_data *new_event_data; > + > + perf_aux_output_end(element->ctx_handle, size); > + new_event_data = perf_aux_output_begin( > + element->ctx_handle, > + element->perf_event); > + if (WARN_ON(new_event_data == NULL)) > + continue; > + element->etm_event_data = new_event_data; > + WARN_ON(new_event_data->snk_config != > + element->etm_event_data->snk_config); > + } > + } > + } > + > + rcu_read_unlock(); > + preempt_enable(); > + local_irq_restore(flags); > +} > + > +void etr_perf_polling_handle_register(struct perf_output_handle *handle, > + void (*tmc_etr_reset_hw)(struct tmc_drvdata *drvdata)) > +{ > + struct polling_event_list *element; > + > + element = kmalloc(sizeof(*element), GFP_KERNEL); > + if (WARN_ON(!element)) > + return; > + memset(element, 0, sizeof(*element)); > + element->ctx_handle = handle; > + element->tmc_etr_reset_hw = tmc_etr_reset_hw; > + spin_lock(&spinlock_re); > + list_add(&element->list, ®istered_events); > + spin_unlock(&spinlock_re); > +} > +EXPORT_SYMBOL_GPL(etr_perf_polling_handle_register); > + > +void etr_perf_polling_handle_deregister(struct perf_output_handle *handle) > +{ > + struct list_head *i, *tmp; > + > + spin_lock(&spinlock_re); > + list_for_each_safe (i, tmp, ®istered_events) { > + struct polling_event_list *element = > + list_entry(i, struct polling_event_list, list); > + if (element->ctx_handle == handle) { > + list_del(&element->list); > + spin_unlock(&spinlock_re); > + kfree(element); > + return; > + } > + } > + spin_unlock(&spinlock_re); > +} > +EXPORT_SYMBOL_GPL(etr_perf_polling_handle_deregister); > + > +void etr_perf_polling_init(void) > +{ > + int cpu; > + spin_lock_init(&spinlock_re); > + INIT_LIST_HEAD(®istered_events); > + atomic_set(&period, 0); > + for_each_possible_cpu (cpu) { > + struct polling *p = per_cpu_ptr(&polling, cpu); > + p->cpu = cpu; > + INIT_LIST_HEAD(&p->polled_events); > + INIT_DELAYED_WORK(&p->delayed_work, etr_perf_polling_worker); > + } > +} > +EXPORT_SYMBOL_GPL(etr_perf_polling_init); > + > +void etr_perf_polling_exit(void) > +{ > + int cpu; > + for_each_possible_cpu (cpu) { > + struct polling *p = per_cpu_ptr(&polling, cpu); > + cancel_delayed_work_sync(&p->delayed_work); > + WARN_ON(!list_empty(&p->polled_events)); > + } > + WARN_ON(!list_empty(®istered_events)); > +} > +EXPORT_SYMBOL_GPL(etr_perf_polling_exit); > + > +#endif > diff --git a/drivers/hwtracing/coresight/coresight-etr-perf-polling.h b/drivers/hwtracing/coresight/coresight-etr-perf-polling.h > new file mode 100644 > index 0000000000000..5917e1fa408bb > --- /dev/null > +++ b/drivers/hwtracing/coresight/coresight-etr-perf-polling.h > @@ -0,0 +1,42 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright(C) 2021 Arm Limited. All rights reserved. > + * Author: Daniel Kiss > + */ > + > +#ifndef _CORESIGHT_ETM_PERF_POLLING_H > +#define _CORESIGHT_ETM_PERF_POLLING_H > + > +#include > +#include > +#include "coresight-etm-perf.h" > +#include "coresight-tmc.h" > + > +#if defined(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) || \ > + defined(CONFIG_CORESIGHT_LINK_AND_SINK_TMC_MODULE) > + > +void etr_perf_polling_init(void); > +void etr_perf_polling_exit(void); > +void etr_perf_polling_handle_register(struct perf_output_handle *handle, > + void (*tmc_etr_reset_hw)(struct tmc_drvdata *drvdata)); > +void etr_perf_polling_handle_deregister(struct perf_output_handle *handle); > +void etr_perf_polling_event_start(struct perf_event *event, > + struct etm_event_data *etm_event_data, > + struct perf_output_handle *ctx_handle); > +void etr_perf_polling_event_stop(struct perf_event *event, > + struct etm_event_data *etm_event_data); > + > +extern const struct attribute_group coresight_tmc_polling_group; > +#define CORESIGHT_TMP_POLLING_GROUP &coresight_tmc_polling_group, > + > +#else /* !CONFIG_CORESIGHT_LINK_AND_SINK_TMC */ > +#define etr_perf_polling_init() > +#define etr_perf_polling_exit() > +#define etr_perf_polling_handle_register(...) > +#define etr_perf_polling_handle_deregister(...) > +#define etr_perf_polling_event_start(...) > +#define etr_perf_polling_event_stop(...) > +#define CORESIGHT_TMP_POLLING_GROUP > +#endif > + > +#endif > diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c > index 74c6323d4d6ab..51e705ef3ffa3 100644 > --- a/drivers/hwtracing/coresight/coresight-tmc-core.c > +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c > @@ -26,6 +26,7 @@ > > #include "coresight-priv.h" > #include "coresight-tmc.h" > +#include "coresight-etr-perf-polling.h" > > DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb"); > DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf"); > @@ -365,6 +366,7 @@ static const struct attribute_group coresight_tmc_mgmt_group = { > static const struct attribute_group *coresight_tmc_groups[] = { > &coresight_tmc_group, > &coresight_tmc_mgmt_group, > + CORESIGHT_TMP_POLLING_GROUP > NULL, > }; > > diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c > index bf9f6311d8663..021b594e38e71 100644 > --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c > +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c > @@ -16,6 +16,7 @@ > #include > #include "coresight-catu.h" > #include "coresight-etm-perf.h" > +#include "coresight-etr-perf-polling.h" > #include "coresight-priv.h" > #include "coresight-tmc.h" > > @@ -1139,6 +1140,12 @@ void tmc_etr_disable_hw(struct tmc_drvdata *drvdata) > drvdata->etr_buf = NULL; > } > > +static void tmc_etr_reset_hw(struct tmc_drvdata *drvdata) > +{ > + __tmc_etr_disable_hw(drvdata); > + __tmc_etr_enable_hw(drvdata); > +} > + > static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) > { > int ret = 0; > @@ -1630,6 +1637,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data) > drvdata->mode = CS_MODE_PERF; > drvdata->perf_buf = etr_perf->etr_buf; > drvdata->perf_handle = handle; > + etr_perf_polling_handle_register(handle, tmc_etr_reset_hw); > atomic_inc(csdev->refcnt); > } > > @@ -1677,6 +1685,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) > drvdata->mode = CS_MODE_DISABLED; > /* Reset perf specific data */ > drvdata->perf_buf = NULL; > + etr_perf_polling_handle_deregister(drvdata->perf_handle); > drvdata->perf_handle = NULL; > > spin_unlock_irqrestore(&drvdata->spinlock, flags); > -- > 2.25.1 > > _______________________________________________ > CoreSight mailing list > CoreSight@lists.linaro.org > https://lists.linaro.org/mailman/listinfo/coresight _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel