From patchwork Fri Oct 7 21:10:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Poirier X-Patchwork-Id: 77355 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp418971qge; Fri, 7 Oct 2016 14:11:18 -0700 (PDT) X-Received: by 10.66.189.168 with SMTP id gj8mr33485783pac.117.1475874678395; Fri, 07 Oct 2016 14:11:18 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n3si10318331pfn.77.2016.10.07.14.11.18; Fri, 07 Oct 2016 14:11:18 -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; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757434AbcJGVLI (ORCPT + 27 others); Fri, 7 Oct 2016 17:11:08 -0400 Received: from mail-io0-f176.google.com ([209.85.223.176]:36099 "EHLO mail-io0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932726AbcJGVKr (ORCPT ); Fri, 7 Oct 2016 17:10:47 -0400 Received: by mail-io0-f176.google.com with SMTP id j37so59418136ioo.3 for ; Fri, 07 Oct 2016 14:10:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=/THanV4USbgbBeDd2FEGOdiJZOZGa84v+/DW8k1cb2Y=; b=Ipu0bB1nYJAbkFOiLX4jy7lYRNvKSgrCjcRts/XkmL5r+KN7aC1oSiA8bymQFfg3lO WiM5OQnWVQoy6bfwyeB+wl0K3Y1PG1lQEm6jnjvuPTSrOl3omHHfifBRU3GNghr+axEq J/ClPQr+YbwhVPNSRDy3HN6dflZUEQbVmmnzw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=/THanV4USbgbBeDd2FEGOdiJZOZGa84v+/DW8k1cb2Y=; b=lCVk7c3XFZ2MpBmRfZr7NiKES3k8sZS8+qwV9n/Cwg2NPW1ppPqiCYJVW/lTHw+N3o crm3q8N1I8c6FHctCB1POtqxzPvOgVUUTim5zMnKMnYGSTD10AjZVw59SVEvpfXTAweL oOGPXVsF1Il7IY0t0jLKMhBrSFgKxIeHI/M224e6AKtJC4ThD024HBw5/bBbSFCo1SXe B+n7zAZ5JxAUMLyQMX9QkE9TCBu7oGaXw1e7OgKd2coLjYQAo/LIk0Lt9RRk3+nIxeNr KwBaLkUgwf5HzNaYuBakQrUKVzy3aRQaXsnDJ9W8HT23q3aNSxSPQuYh91a9MIJn78FC KSBg== X-Gm-Message-State: AA6/9Rnj5q2r1MHJ05tWUx3mXA4Gg3utExabLOyR0HDDLL9WO+YYP0bioMC3oj5oBlI6y6M9 X-Received: by 10.107.17.229 with SMTP id 98mr21768629ior.96.1475874646224; Fri, 07 Oct 2016 14:10:46 -0700 (PDT) Received: from t430.cg.shawcable.net (S0106002369de4dac.cg.shawcable.net. [68.147.8.254]) by smtp.gmail.com with ESMTPSA id r80sm8321189ioe.43.2016.10.07.14.10.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 07 Oct 2016 14:10:45 -0700 (PDT) From: Mathieu Poirier To: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, Suzuki.Poulose@arm.com Subject: [PATCH] coresight: reset "enable_sink" flag when need be Date: Fri, 7 Oct 2016 15:10:43 -0600 Message-Id: <1475874643-9464-1-git-send-email-mathieu.poirier@linaro.org> X-Mailer: git-send-email 2.7.4 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When using coresight from the perf interface sinks are specified as part of the perf command line. As such the sink needs to be disabled once it has been acknowledged by the coresight framework. Otherwise the sink stays enabled, which may interfere with other sessions. This patch removes the sink selection check from the build path process and make it a function on it's own. The function is then used when operating from sysFS or perf to determine what sink has been selected. Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etm-perf.c | 31 ++++++------ drivers/hwtracing/coresight/coresight-priv.h | 4 +- drivers/hwtracing/coresight/coresight.c | 62 +++++++++++++++++++++--- 3 files changed, 75 insertions(+), 22 deletions(-) -- 2.7.4 Reviewed-by: Suzuki K Poulose diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index 2cd7c718198a..1103073b2640 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -202,6 +202,21 @@ static void *etm_setup_aux(int event_cpu, void **pages, if (!event_data) return NULL; + /* + * In theory nothing prevent tracers in a trace session from being + * associated with different sinks, nor having a sink per tracer. But + * until we have HW with this kind of topolog we need to assume tracers + * in a trace session are using the same sink. Therefore go through + * the coresight bus and pick the first enabled sink. + * + * When operated from sysFS users are responsible to enable the sink + * while from perf, the perf tools will do it based on the choice made + * on the cmd line. As such the "enable_sink" flag in sysFS is reset. + */ + sink = coresight_get_enabled_sink(true); + if (!sink) + return NULL; + INIT_WORK(&event_data->work, free_event_data); mask = &event_data->mask; @@ -219,25 +234,11 @@ static void *etm_setup_aux(int event_cpu, void **pages, * list of devices from source to sink that can be * referenced later when the path is actually needed. */ - event_data->path[cpu] = coresight_build_path(csdev); + event_data->path[cpu] = coresight_build_path(csdev, sink); if (IS_ERR(event_data->path[cpu])) goto err; } - /* - * In theory nothing prevent tracers in a trace session from being - * associated with different sinks, nor having a sink per tracer. But - * until we have HW with this kind of topology and a way to convey - * sink assignement from the perf cmd line we need to assume tracers - * in a trace session are using the same sink. Therefore pick the sink - * found at the end of the first available path. - */ - cpu = cpumask_first(mask); - /* Grab the sink at the end of the path */ - sink = coresight_get_sink(event_data->path[cpu]); - if (!sink) - goto err; - if (!sink_ops(sink)->alloc_buffer) goto err; diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 196a14be4b3d..ef9d8e93e3b2 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -111,7 +111,9 @@ static inline void CS_UNLOCK(void __iomem *addr) void coresight_disable_path(struct list_head *path); int coresight_enable_path(struct list_head *path, u32 mode); struct coresight_device *coresight_get_sink(struct list_head *path); -struct list_head *coresight_build_path(struct coresight_device *csdev); +struct coresight_device *coresight_get_enabled_sink(bool reset); +struct list_head *coresight_build_path(struct coresight_device *csdev, + struct coresight_device *sink); void coresight_release_path(struct list_head *path); #ifdef CONFIG_CORESIGHT_SOURCE_ETM3X diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 7bf00a0beb6f..40ede643d553 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -368,6 +368,40 @@ struct coresight_device *coresight_get_sink(struct list_head *path) return csdev; } +static int coresight_enabled_sink(struct device *dev, void *data) +{ + bool *reset = data; + struct coresight_device *csdev = to_coresight_device(dev); + + if ((csdev->type == CORESIGHT_DEV_TYPE_SINK || + csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) && + csdev->activated) { + /* + * Now that we have a handle on the sink for this session, + * disable the sysFS "enable_sink" flag so that possible + * concurrent perf session that wish to use another sink don't + * trip on it. Doing so has no ramification for the current + * session. + */ + if (*reset) + csdev->activated = false; + + return 1; + } + + return 0; +} + +struct coresight_device *coresight_get_enabled_sink(bool reset) +{ + struct device *dev = NULL; + + dev = bus_find_device(&coresight_bustype, NULL, &reset, + coresight_enabled_sink); + + return dev ? to_coresight_device(dev) : NULL; +} + /** * _coresight_build_path - recursively build a path from a @csdev to a sink. * @csdev: The device to start from. @@ -380,6 +414,7 @@ struct coresight_device *coresight_get_sink(struct list_head *path) * last one. */ static int _coresight_build_path(struct coresight_device *csdev, + struct coresight_device *sink, struct list_head *path) { int i; @@ -387,15 +422,15 @@ static int _coresight_build_path(struct coresight_device *csdev, struct coresight_node *node; /* An activated sink has been found. Enqueue the element */ - if ((csdev->type == CORESIGHT_DEV_TYPE_SINK || - csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) && csdev->activated) + if (csdev == sink) goto out; /* Not a sink - recursively explore each port found on this element */ for (i = 0; i < csdev->nr_outport; i++) { struct coresight_device *child_dev = csdev->conns[i].child_dev; - if (child_dev && _coresight_build_path(child_dev, path) == 0) { + if (child_dev && + _coresight_build_path(child_dev, sink, path) == 0) { found = true; break; } @@ -422,18 +457,22 @@ out: return 0; } -struct list_head *coresight_build_path(struct coresight_device *csdev) +struct list_head *coresight_build_path(struct coresight_device *source, + struct coresight_device *sink) { struct list_head *path; int rc; + if (!sink) + return ERR_PTR(-EINVAL); + path = kzalloc(sizeof(struct list_head), GFP_KERNEL); if (!path) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(path); - rc = _coresight_build_path(csdev, path); + rc = _coresight_build_path(source, sink, path); if (rc) { kfree(path); return ERR_PTR(rc); @@ -497,6 +536,7 @@ static int coresight_validate_source(struct coresight_device *csdev, int coresight_enable(struct coresight_device *csdev) { int cpu, ret = 0; + struct coresight_device *sink; struct list_head *path; mutex_lock(&coresight_mutex); @@ -508,7 +548,17 @@ int coresight_enable(struct coresight_device *csdev) if (csdev->enable) goto out; - path = coresight_build_path(csdev); + /* + * Search for a valid sink for this session but don't reset the + * "enable_sink" flag in sysFS. Users get to do that explicitly. + */ + sink = coresight_get_enabled_sink(false); + if (!sink) { + ret = -EINVAL; + goto out; + } + + path = coresight_build_path(csdev, sink); if (IS_ERR(path)) { pr_err("building path(s) failed\n"); ret = PTR_ERR(path);