From patchwork Thu Jul 16 17:57:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Poirier X-Patchwork-Id: 11668255 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 42AE717C5 for ; Thu, 16 Jul 2020 18:05:42 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 06D422070E for ; Thu, 16 Jul 2020 18:05:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="kpI0VTTZ"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="uqXCgL2C" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 06D422070E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=4zZxdK/v6bzqiqkdRZFEYcA2THa4iZiikX00Hm6tlik=; b=kpI0VTTZ39MusNcvay5+VQ3T1 OpqunjKb62XkYPaRDs5OYN6WMBF6Spn48goRxKwAYJCKDCtHeCcfd4xa7/5MBVy51D1IqMo8qyOyi rX+rp9vEoguswITx/gYu2hPczHjHSHSdWqWeNr2nEorN3MIgc3pam04X8DJZQo/pddTjq/4PYZPFz OOH8zK9iQW949ZU049SvN7495Snu8vpB+L8twgR4oFbIYiuh+1F/RtswWEw91sOe3xLr1qT0V+u57 zKxbuzAYAYagvDu3Ivc2atOLWI+9QvhcJKD8VCpDRCRGZ9ekLVAj9ceqsyAtQCqrDpuUWjqinDv94 +FKR2zFTg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jw8B7-0004MG-Mj; Thu, 16 Jul 2020 18:00:17 +0000 Received: from mail-pj1-x1043.google.com ([2607:f8b0:4864:20::1043]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jw890-0003HN-Tk for linux-arm-kernel@lists.infradead.org; Thu, 16 Jul 2020 17:58:12 +0000 Received: by mail-pj1-x1043.google.com with SMTP id gc9so5183762pjb.2 for ; Thu, 16 Jul 2020 10:58:06 -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:in-reply-to:references :mime-version:content-transfer-encoding; bh=oscPAjtaFuuauy6j4n+8DCRJWWBSQ0QskJ25gcI0x54=; b=uqXCgL2CyNM8Mz12hEpY56bXQtb1lRUAqBmXJLumrK24eSXji/kISejOxdycfsFaxy ni7fYeqK2EEXtBiO+YESiePlVrzvIrn+qddz0qqJd4Ut2S0PWPJ/6O/mkxx441WITEw5 0D1z4YwgFh1efSXqzvnK6mWtliOj7Zx+8s1MfverOfiTjYbq4HjWHFbqFRh4Iecc5rMr YnsF7GS6gyP41fpPLljJkVaJfXp0747Z/k0XfTgw9zi73mEJy1q/Z3LIwGSNWfJsg06v 4nkrJrJbsDW0IDf5KxeJbATm6SrIp7Fml+IYnaqpKHoKPrDdUoPKX5wJKMnqAyNXfbyb OJ0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oscPAjtaFuuauy6j4n+8DCRJWWBSQ0QskJ25gcI0x54=; b=IGUmYffc+OagcEBJXkCu+XFE28t8oJQIorNWwz+MevtgdeiLTagSwK3HvWFGI51Vu7 DL3z1CZ1nHfvNV3FK/sXmNfxzOOTNjoJ5SodWnGZ/KHdsWuZ57ZpIrXjcb+TCXQF+5kJ r9eAkoTs7drUdkKuYau22HmVll7whUJFEaSRZIzrnHbKBaRP6DbUKTNhGBSVkubr415K jeAJaiYRsgUATliGDmTA5tGkvEYupFzxZEpzAhbOEwZ7pKUJ7j5hT7CGm5xJ2gPBvp3F 1ac7ZYgfamEoJ9qEYtnpk6L7BW8mIZ4vEvOhkp6aOr8TOI4LYlvSAs2ajbjcQgLBZ6bx tRlw== X-Gm-Message-State: AOAM531qa+AzfQjZ0Bp7mS0IP39RJc4869LghnHZaVr0N84kb2YagliZ o2IqFJZZiBpsfINDfMVt7kP0JmrLIlA= X-Google-Smtp-Source: ABdhPJzbd2eTV1emu8G+RoQFFPQd7QltAAzyYiFhxKt1JjS4zDonmaVLlqb+rGPqSp7qAUVj7M1vAg== X-Received: by 2002:a17:90a:bc98:: with SMTP id x24mr5467172pjr.63.1594922284782; Thu, 16 Jul 2020 10:58:04 -0700 (PDT) Received: from xps15.cg.shawcable.net (S0106002369de4dac.cg.shawcable.net. [68.147.8.254]) by smtp.gmail.com with ESMTPSA id 83sm5473253pfu.60.2020.07.16.10.58.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 10:58:04 -0700 (PDT) From: Mathieu Poirier To: gregkh@linuxfoundation.org Subject: [PATCH 14/17] coresight: Add default sink selection to CoreSight base Date: Thu, 16 Jul 2020 11:57:43 -0600 Message-Id: <20200716175746.3338735-15-mathieu.poirier@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200716175746.3338735-1-mathieu.poirier@linaro.org> References: <20200716175746.3338735-1-mathieu.poirier@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200716_135807_087535_44E2A387 X-CRM114-Status: GOOD ( 27.22 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:1043 listed in] [list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: saiprakash.ranjan@codeaurora.org, suzuki.poulose@arm.com, vulab@iscas.ac.cn, tingwei@codeaurora.org, andriy.shevchenko@linux.intel.com, linux-arm-kernel@lists.infradead.org, mike.leach@linaro.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Mike Leach Adds a method to select a suitable sink connected to a given source. In cases where no sink is defined, the coresight_find_default_sink routine can search from a given source, through the child connections until a suitable sink is found. The suitability is defined in by the sink coresight_dev_subtype on the CoreSight device, and the distance from the source by counting connections. Higher value subtype is preferred - where these are equal, shorter distance from source is used as a tie-break. This allows for default sink to be discovered were none is specified (e.g. perf command line) Signed-off-by: Mike Leach Suggested-by: Suzuki K Poulose Reviewed-by: Leo Yan Reviewed-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-priv.h | 2 + drivers/hwtracing/coresight/coresight.c | 166 +++++++++++++++++++ include/linux/coresight.h | 3 + 3 files changed, 171 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 36c943ae94d5..f2dc625ea585 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -150,6 +150,8 @@ int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data); struct coresight_device *coresight_get_sink(struct list_head *path); struct coresight_device *coresight_get_enabled_sink(bool reset); struct coresight_device *coresight_get_sink_by_id(u32 id); +struct coresight_device * +coresight_find_default_sink(struct coresight_device *csdev); struct list_head *coresight_build_path(struct coresight_device *csdev, struct coresight_device *sink); void coresight_release_path(struct list_head *path); diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index f3efbb3b2b4d..e9c90f2de34a 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -769,6 +769,171 @@ void coresight_release_path(struct list_head *path) path = NULL; } +/* return true if the device is a suitable type for a default sink */ +static inline bool coresight_is_def_sink_type(struct coresight_device *csdev) +{ + /* sink & correct subtype */ + if (((csdev->type == CORESIGHT_DEV_TYPE_SINK) || + (csdev->type == CORESIGHT_DEV_TYPE_LINKSINK)) && + (csdev->subtype.sink_subtype >= CORESIGHT_DEV_SUBTYPE_SINK_BUFFER)) + return true; + return false; +} + +/** + * coresight_select_best_sink - return the best sink for use as default from + * the two provided. + * + * @sink: current best sink. + * @depth: search depth where current sink was found. + * @new_sink: new sink for comparison with current sink. + * @new_depth: search depth where new sink was found. + * + * Sinks prioritised according to coresight_dev_subtype_sink, with only + * subtypes CORESIGHT_DEV_SUBTYPE_SINK_BUFFER or higher being used. + * + * Where two sinks of equal priority are found, the sink closest to the + * source is used (smallest search depth). + * + * return @new_sink & update @depth if better than @sink, else return @sink. + */ +static struct coresight_device * +coresight_select_best_sink(struct coresight_device *sink, int *depth, + struct coresight_device *new_sink, int new_depth) +{ + bool update = false; + + if (!sink) { + /* first found at this level */ + update = true; + } else if (new_sink->subtype.sink_subtype > + sink->subtype.sink_subtype) { + /* found better sink */ + update = true; + } else if ((new_sink->subtype.sink_subtype == + sink->subtype.sink_subtype) && + (*depth > new_depth)) { + /* found same but closer sink */ + update = true; + } + + if (update) + *depth = new_depth; + return update ? new_sink : sink; +} + +/** + * coresight_find_sink - recursive function to walk trace connections from + * source to find a suitable default sink. + * + * @csdev: source / current device to check. + * @depth: [in] search depth of calling dev, [out] depth of found sink. + * + * This will walk the connection path from a source (ETM) till a suitable + * sink is encountered and return that sink to the original caller. + * + * If current device is a plain sink return that & depth, otherwise recursively + * call child connections looking for a sink. Select best possible using + * coresight_select_best_sink. + * + * return best sink found, or NULL if not found at this node or child nodes. + */ +static struct coresight_device * +coresight_find_sink(struct coresight_device *csdev, int *depth) +{ + int i, curr_depth = *depth + 1, found_depth = 0; + struct coresight_device *found_sink = NULL; + + if (coresight_is_def_sink_type(csdev)) { + found_depth = curr_depth; + found_sink = csdev; + if (csdev->type == CORESIGHT_DEV_TYPE_SINK) + goto return_def_sink; + /* look past LINKSINK for something better */ + } + + /* + * Not a sink we want - or possible child sink may be better. + * recursively explore each port found on this element. + */ + for (i = 0; i < csdev->pdata->nr_outport; i++) { + struct coresight_device *child_dev, *sink = NULL; + int child_depth = curr_depth; + + child_dev = csdev->pdata->conns[i].child_dev; + if (child_dev) + sink = coresight_find_sink(child_dev, &child_depth); + + if (sink) + found_sink = coresight_select_best_sink(found_sink, + &found_depth, + sink, + child_depth); + } + +return_def_sink: + /* return found sink and depth */ + if (found_sink) + *depth = found_depth; + return found_sink; +} + +/** + * coresight_find_default_sink: Find a sink suitable for use as a + * default sink. + * + * @csdev: starting source to find a connected sink. + * + * Walks connections graph looking for a suitable sink to enable for the + * supplied source. Uses CoreSight device subtypes and distance from source + * to select the best sink. + * + * If a sink is found, then the default sink for this device is set and + * will be automatically used in future. + * + * Used in cases where the CoreSight user (perf / sysfs) has not selected a + * sink. + */ +struct coresight_device * +coresight_find_default_sink(struct coresight_device *csdev) +{ + int depth = 0; + + /* look for a default sink if we have not found for this device */ + if (!csdev->def_sink) + csdev->def_sink = coresight_find_sink(csdev, &depth); + return csdev->def_sink; +} + +static int coresight_remove_sink_ref(struct device *dev, void *data) +{ + struct coresight_device *sink = data; + struct coresight_device *source = to_coresight_device(dev); + + if (source->def_sink == sink) + source->def_sink = NULL; + return 0; +} + +/** + * coresight_clear_default_sink: Remove all default sink references to the + * supplied sink. + * + * If supplied device is a sink, then check all the bus devices and clear + * out all the references to this sink from the coresight_device def_sink + * parameter. + * + * @csdev: coresight sink - remove references to this from all sources. + */ +static void coresight_clear_default_sink(struct coresight_device *csdev) +{ + if ((csdev->type == CORESIGHT_DEV_TYPE_SINK) || + (csdev->type == CORESIGHT_DEV_TYPE_LINKSINK)) { + bus_for_each_dev(&coresight_bustype, NULL, csdev, + coresight_remove_sink_ref); + } +} + /** coresight_validate_source - make sure a source has the right credentials * @csdev: the device structure for a source. * @function: the function this was called from. @@ -1358,6 +1523,7 @@ void coresight_unregister(struct coresight_device *csdev) etm_perf_del_symlink_sink(csdev); /* Remove references of that device in the topology */ coresight_remove_conns(csdev); + coresight_clear_default_sink(csdev); coresight_release_platform_data(csdev, csdev->pdata); device_unregister(&csdev->dev); } diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 84dc695e87d4..58fffdecdbfd 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -48,6 +48,7 @@ enum coresight_dev_subtype_sink { CORESIGHT_DEV_SUBTYPE_SINK_NONE, CORESIGHT_DEV_SUBTYPE_SINK_PORT, CORESIGHT_DEV_SUBTYPE_SINK_BUFFER, + CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM, }; enum coresight_dev_subtype_link { @@ -182,6 +183,7 @@ struct coresight_sysfs_link { * happens when a source has been selected and a path is enabled * from source to that sink. * @ea: Device attribute for sink representation under PMU directory. + * @def_sink: cached reference to default sink found for this device. * @ect_dev: Associated cross trigger device. Not part of the trace data * path or connections. * @nr_links: number of sysfs links created to other components from this @@ -200,6 +202,7 @@ struct coresight_device { /* sink specific fields */ bool activated; /* true only if a sink is part of a path */ struct dev_ext_attribute *ea; + struct coresight_device *def_sink; /* cross trigger handling */ struct coresight_device *ect_dev; /* sysfs links between components */