aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgi Djakov <georgi.djakov@linaro.org>2019-12-20 15:38:12 +0200
committerGeorgi Djakov <georgi.djakov@linaro.org>2020-02-11 19:52:32 +0200
commit012e5199083c6a3d506664d98e427f0a9e32c9d1 (patch)
tree0b0f8f59fe4cb16cd37911d091410bfc9304ef46
parent8a5c891a5f3c49abc24fcb761e5272c2898a832c (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/Kconfig8
-rw-r--r--drivers/interconnect/qcom/Makefile2
-rw-r--r--drivers/interconnect/qcom/msm8916-stress.c99
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");