diff options
author | Georgi Djakov <georgi.djakov@linaro.org> | 2019-12-20 15:38:12 +0200 |
---|---|---|
committer | Georgi Djakov <georgi.djakov@linaro.org> | 2020-02-11 19:52:32 +0200 |
commit | 012e5199083c6a3d506664d98e427f0a9e32c9d1 (patch) | |
tree | 0b0f8f59fe4cb16cd37911d091410bfc9304ef46 | |
parent | 8a5c891a5f3c49abc24fcb761e5272c2898a832c (diff) |
interconnect: qcom: Add a stress test for msm8916
Add a driver for stress testing the the Qualcomm MSM8916 interconnect
driver. In includes running multiple threads in a loop that are
setting random bandwidth on different paths.
Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
-rw-r--r-- | drivers/interconnect/qcom/Kconfig | 8 | ||||
-rw-r--r-- | drivers/interconnect/qcom/Makefile | 2 | ||||
-rw-r--r-- | drivers/interconnect/qcom/msm8916-stress.c | 99 |
3 files changed, 109 insertions, 0 deletions
diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig index a98a6726c8e4..9f6bf86770d5 100644 --- a/drivers/interconnect/qcom/Kconfig +++ b/drivers/interconnect/qcom/Kconfig @@ -19,6 +19,14 @@ config INTERCONNECT_QCOM_MSM8916 This is a driver for the Qualcomm Network-on-Chip on msm8916-based platforms. +config INTERCONNECT_QCOM_MSM8916_STRESS + tristate "Stress test for the Qualcomm MSM8916 interconnect driver" + depends on INTERCONNECT_QCOM_MSM8916 + help + This is a driver for stress testing the the Qualcomm MSM8916 + interconnect driver. In includes running multiple threads in a + loop that are setting random bandwidth on different paths. + config INTERCONNECT_QCOM_MSM8974 tristate "Qualcomm MSM8974 interconnect driver" depends on INTERCONNECT_QCOM diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile index 99d535b2dca9..d4f7aaa97ec9 100644 --- a/drivers/interconnect/qcom/Makefile +++ b/drivers/interconnect/qcom/Makefile @@ -3,6 +3,7 @@ icc-bcm-voter-objs := bcm-voter.o icc-osm-l3-objs := osm-l3.o qnoc-msm8916-objs := msm8916.o +qnoc-msm8916-stress-objs := msm8916-stress.o qnoc-msm8974-objs := msm8974.o qnoc-qcs404-objs := qcs404.o icc-rpmh-obj := icc-rpmh.o @@ -11,6 +12,7 @@ icc-smd-rpm-objs := smd-rpm.o obj-$(CONFIG_INTERCONNECT_QCOM_BCM_VOTER) += icc-bcm-voter.o obj-$(CONFIG_INTERCONNECT_QCOM_MSM8916) += qnoc-msm8916.o +obj-$(CONFIG_INTERCONNECT_QCOM_MSM8916_STRESS) += qnoc-msm8916-stress.o obj-$(CONFIG_INTERCONNECT_QCOM_MSM8974) += qnoc-msm8974.o obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o diff --git a/drivers/interconnect/qcom/msm8916-stress.c b/drivers/interconnect/qcom/msm8916-stress.c new file mode 100644 index 000000000000..c573dc0baa92 --- /dev/null +++ b/drivers/interconnect/qcom/msm8916-stress.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019, Linaro Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/delay.h> +#include <linux/interconnect.h> +#include <linux/kthread.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/random.h> +#include <linux/uaccess.h> + +struct platform_device *msm8916_icc_pdev; + +struct msm8916_icc_stress_data { + struct icc_path *path; + u32 src; + u32 dst; +}; + +static struct msm8916_icc_stress_data data[] = { + { .src = 12, .dst = 53, }, // sdcc2 + { .src = 9, .dst = 53, }, // mdp + { .src = 21, .dst = 53, }, // video + { .src = 7, .dst = 53, }, // gfx3d +}; + +static int msm8916_icc_stress_thread(void *data) +{ + struct msm8916_icc_stress_data *d = data; + u32 avg_bw, peak_bw, tag = 0; + int i = 0; + + do { + avg_bw = get_random_u32() % 10000000 + 1000 ; + peak_bw = get_random_u32() % 10000000 + 1000; + tag = get_random_u32() % 100; + + if (IS_ERR_OR_NULL(d->path)) { + d->path = icc_get(&msm8916_icc_pdev->dev, d->src, d->dst); + if (IS_ERR(d->path) && PTR_ERR(d->path) != -EPROBE_DEFER) + pr_err("%s icc_get src=%u dst=%u error: %lu\n", + __func__, d->src, d->dst, PTR_ERR(d->path)); + } + + if (!IS_ERR(d->path)) { + + if (i % 7) + icc_set_tag(d->path, tag); + + icc_set_bw(d->path, avg_bw, peak_bw); + + avg_bw--; + peak_bw--; + + if (i++ % 5) { + icc_put(d->path); + d->path = NULL; + } + } + + } while (!kthread_should_stop()); + + return 0; +} + +static int __init msm8916_icc_stress_init(void) +{ + int cpu; + + msm8916_icc_pdev = platform_device_alloc("icc-msm8916-stress", + PLATFORM_DEVID_AUTO); + platform_device_add(msm8916_icc_pdev); + + for_each_online_cpu(cpu) { + + struct task_struct *k = kthread_create(msm8916_icc_stress_thread, + &data[cpu], + "icc_stress_%d", cpu); + kthread_bind(k, cpu); + wake_up_process(k); + pr_info("Started %s on cpu%d\n", __func__, cpu); + } + /* TODO: stop threads and free resources */ + + return 0; +} +late_initcall(msm8916_icc_stress_init); +MODULE_LICENSE("GPL v2"); |