lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <66c67d0b0e551aba11a83ce6a840ad29@codeaurora.org>
Date:   Fri, 14 Sep 2018 18:23:34 +0530
From:   Sibi Sankar <sibis@...eaurora.org>
To:     Saravana Kannan <skannan@...eaurora.org>
Cc:     MyungJoo Ham <myungjoo.ham@...sung.com>,
        Kyungmin Park <kyungmin.park@...sung.com>,
        Chanwoo Choi <cw00.choi@...sung.com>,
        Rob Herring <robh+dt@...nel.org>,
        Mark Rutland <mark.rutland@....com>, georgi.djakov@...aro.org,
        vincent.guittot@...aro.org, daidavid1@...eaurora.org,
        bjorn.andersson@...aro.org, linux-pm@...r.kernel.org,
        devicetree@...r.kernel.org, linux-kernel@...r.kernel.org,
        linux-kernel-owner@...r.kernel.org, rnayak@...eaurora.org
Subject: Re: [PATCH v3 2/2] PM / devfreq: Add devfreq driver for interconnect
 bandwidth voting

Hi Saravana,

On 2018-08-02 06:27, Saravana Kannan wrote:
> This driver registers itself as a devfreq device that allows devfreq
> governors to make bandwidth votes for an interconnect path. This allows
> applying various policies for different interconnect paths using 
> devfreq
> governors.
> 
> Example uses:
> * Use the devfreq performance governor to set the CPU to DDR 
> interconnect
>   path for maximum performance.
> * Use the devfreq performance governor to set the GPU to DDR 
> interconnect
>   path for maximum performance.
> * Use the CPU frequency to device frequency mapping governor to scale 
> the
>   DDR frequency based on the needs of the CPUs' current frequency.
> 
> Signed-off-by: Saravana Kannan <skannan@...eaurora.org>
> ---
>  Documentation/devicetree/bindings/devfreq/icbw.txt |  21 ++++
>  drivers/devfreq/Kconfig                            |  13 +++
>  drivers/devfreq/Makefile                           |   1 +
>  drivers/devfreq/devfreq_icbw.c                     | 116 
> +++++++++++++++++++++
>  4 files changed, 151 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/devfreq/icbw.txt
>  create mode 100644 drivers/devfreq/devfreq_icbw.c
> 
> diff --git a/Documentation/devicetree/bindings/devfreq/icbw.txt
> b/Documentation/devicetree/bindings/devfreq/icbw.txt
> new file mode 100644
> index 0000000..36cf045
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/devfreq/icbw.txt
> @@ -0,0 +1,21 @@
> +Interconnect bandwidth device
> +
> +icbw is a device that represents an interconnect path that connects 
> two
> +devices. This device is typically used to vote for BW requirements 
> between
> +two devices. Eg: CPU to DDR, GPU to DDR, etc
> +
> +Required properties:
> +- compatible:		Must be "devfreq-icbw"
> +- interconnects:	Pairs of phandles and interconnect provider specifier
> +			to denote the edge source and destination ports of
> +			the interconnect path. See also:
> +		Documentation/devicetree/bindings/interconnect/interconnect.txt
> +- interconnect-names:	Must have one entry with the name "path".
> +
> +Example:
> +
> +	qcom,cpubw {
> +		compatible = "devfreq-icbw";
> +		interconnects = <&snoc MASTER_APSS_1 &bimc SLAVE_EBI_CH0>;
> +		interconnect-names = "path";
> +	};
> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
> index 3d9ae68..590370e 100644
> --- a/drivers/devfreq/Kconfig
> +++ b/drivers/devfreq/Kconfig
> @@ -121,6 +121,19 @@ config ARM_RK3399_DMC_DEVFREQ
>            It sets the frequency for the memory controller and reads
> the usage counts
>            from hardware.
> 
> +config DEVFREQ_ICBW
> +	bool "DEVFREQ device for making bandwidth votes on interconnect 
> paths"
> +	select DEVFREQ_GOV_PERFORMANCE
> +	select DEVFREQ_GOV_POWERSAVE
> +	select DEVFREQ_GOV_USERSPACE
> +	default n
> +	help
> +	  Different devfreq governors use this devfreq device to make
> +	  bandwidth votes for interconnect paths between different devices
> +	  (Eg: CPU to DDR, GPU to DDR, etc). This driver provides a generic
> +	  interface so that the devfreq governors can be shared across SoCs
> +	  and architectures.
> +
>  source "drivers/devfreq/event/Kconfig"
> 
>  endif # PM_DEVFREQ
> diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
> index e9dc3e9..b302c5cf 100644
> --- a/drivers/devfreq/Makefile
> +++ b/drivers/devfreq/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_DEVFREQ_GOV_CPUFREQ_MAP)	+=
> governor_cpufreq_map.o
>  obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)	+= exynos-bus.o
>  obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)	+= rk3399_dmc.o
>  obj-$(CONFIG_ARM_TEGRA_DEVFREQ)		+= tegra-devfreq.o
> +obj-$(CONFIG_DEVFREQ_ICBW)		+= devfreq_icbw.o
> 
>  # DEVFREQ Event Drivers
>  obj-$(CONFIG_PM_DEVFREQ_EVENT)		+= event/
> diff --git a/drivers/devfreq/devfreq_icbw.c 
> b/drivers/devfreq/devfreq_icbw.c
> new file mode 100644
> index 0000000..231fb21
> --- /dev/null
> +++ b/drivers/devfreq/devfreq_icbw.c
> @@ -0,0 +1,116 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2013-2014, 2018, The Linux Foundation. All rights 
> reserved.
> + */
> +
> +#define pr_fmt(fmt) "icbw: " fmt
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/mutex.h>
> +#include <linux/devfreq.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/interconnect.h>
> +
> +struct dev_data {
> +	struct icc_path *path;
> +	u32 cur_ab;
> +	u32 cur_pb;
> +	unsigned long gov_ab;
> +	struct devfreq *df;
> +	struct devfreq_dev_profile dp;
> +};
> +
> +static int icbw_target(struct device *dev, unsigned long *freq, u32 
> flags)
> +{
> +	struct dev_data *d = dev_get_drvdata(dev);
> +	int ret;
> +	u32 new_pb = *freq, new_ab = d->gov_ab;
> +
> +	if (d->cur_pb == new_pb && d->cur_ab == new_ab)
> +		return 0;
> +
> +	dev_dbg(dev, "BW KBps: AB: %u PB: %u\n", new_ab, new_pb);
> +
> +	ret = icc_set(d->path, new_ab, new_pb);
> +	if (ret) {
> +		dev_err(dev, "bandwidth request failed (%d)\n", ret);
> +	} else {
> +		d->cur_pb = new_pb;
> +		d->cur_ab = new_ab;
> +	}
> +
> +	return ret;
> +}
> +
> +static int icbw_get_dev_status(struct device *dev,
> +				struct devfreq_dev_status *stat)
> +{
> +	struct dev_data *d = dev_get_drvdata(dev);
> +
> +	stat->private_data = &d->gov_ab;
> +	return 0;
> +}
> +
> +static int devfreq_icbw_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct dev_data *d;
> +	struct devfreq_dev_profile *p;
> +
> +	d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL);
> +	if (!d)
> +		return -ENOMEM;
> +	dev_set_drvdata(dev, d);
> +
> +	p = &d->dp;
> +	p->polling_ms = 50;
> +	p->target = icbw_target;
> +	p->get_dev_status = icbw_get_dev_status;
> +
> +	d->path = of_icc_get(dev, "path");
> +	if (IS_ERR(d->path)) {
> +		dev_err(dev, "Unable to register interconnect path\n");
> +		return -ENODEV;
> +	}

The probe fails if the provider is not registered yet. Worked around it 
using -EPROBE_DEFER
but this should probably come from of_icc_get itself.

> +
> +	d->df = devfreq_add_device(dev, p, "performance", NULL);
> +	if (IS_ERR(d->df)) {
> +		icc_put(d->path);
> +		return PTR_ERR(d->df);
> +	}

devfreq_add_device will fail with -EINVAL for set_table_freq, 
find_available_min_freq and
find_available_max_freq. If you end up working your way around it, I 
still ended up getting
multiple errors like "Couldn't update frequency transition information" 
after probing.

> +
> +	return 0;
> +}
> +
> +static int devfreq_icbw_remove(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct dev_data *d = dev_get_drvdata(dev);
> +
> +	devfreq_remove_device(d->df);
> +	icc_put(d->path);
> +	return 0;
> +}
> +
> +static const struct of_device_id icbw_match_table[] = {
> +	{ .compatible = "devfreq-icbw" },
> +	{}
> +};
> +
> +static struct platform_driver icbw_driver = {
> +	.probe = devfreq_icbw_probe,
> +	.remove = devfreq_icbw_remove,
> +	.driver = {
> +		.name = "devfreq-icbw",
> +		.of_match_table = icbw_match_table,
> +	},
> +};
> +
> +module_platform_driver(icbw_driver);
> +MODULE_DESCRIPTION("Interconnect bandwidth voting driver");
> +MODULE_LICENSE("GPL v2");

-- 
-- Sibi Sankar --
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ