Skip to content

Commit

Permalink
soc: renesas: Add memory related test in tight loop
Browse files Browse the repository at this point in the history
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
  • Loading branch information
prabhakarlad committed Dec 19, 2023
1 parent 7e36d23 commit 2907a62
Show file tree
Hide file tree
Showing 5 changed files with 478 additions and 0 deletions.
18 changes: 18 additions & 0 deletions drivers/soc/renesas/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -360,4 +360,22 @@ config PWC_RZV2M
config RST_RCAR
bool "Reset Controller support for R-Car" if COMPILE_TEST

#
# Renesas RDWR tests
#
config RENESAS_MEMCPY_TEST
tristate "memcpy performance profiling test module"
help
Simple memcpy test.

config RENESAS_CPY_FRM_TO_TEST
tristate "copy_form/to_user performance profiling test module"
help
copy_form/to_user test.

config RENESAS_READ_WRITE
tristate "memory performance profiling test module"
help
Simple memory driver test.

endif # SOC_RENESAS
5 changes: 5 additions & 0 deletions drivers/soc/renesas/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ endif
# Family
obj-$(CONFIG_PWC_RZV2M) += pwc-rzv2m.o
obj-$(CONFIG_RST_RCAR) += rcar-rst.o

# Renesas RDWR tests
obj-$(CONFIG_RENESAS_MEMCPY_TEST) += renesas-memcpy-test.o
obj-$(CONFIG_RENESAS_CPY_FRM_TO_TEST) += renesas-cpy-frm-to-user-test.o
obj-$(CONFIG_RENESAS_READ_WRITE) += renesas-rdwr-test.o
123 changes: 123 additions & 0 deletions drivers/soc/renesas/renesas-cpy-frm-to-user-test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/timekeeping.h>

#define DEVICE_NAME "rzfive"

static void *device_buffer;
static int buffer_size = 4 * 1024 * 1024;
static int num_iterations = 10000;

module_param(buffer_size, int, S_IRUGO);
MODULE_PARM_DESC(buffer_size, "Size of the device buffer (in bytes) to copy from/to user");

module_param(num_iterations, int, S_IRUGO);
MODULE_PARM_DESC(num_iterations, "Number of copy_to_user and copy_from_user iterations");

static s64 measure_copy_time(char __user *user_buffer, int bytes_to_copy, int copy_to_user_flag)
{
ktime_t start_time, end_time;
s64 total_time = 0;
unsigned int i;

for (i = 0; i < num_iterations; i++) {
start_time = ktime_get();

if (copy_to_user_flag) {
if (copy_to_user(user_buffer, device_buffer, bytes_to_copy) != 0) {
pr_err("copy_to_user failed!");
return 0;
}
} else {
if (copy_from_user(device_buffer, user_buffer, bytes_to_copy) != 0) {
pr_err("copy_from_user failed!");
return 0;
}
}

end_time = ktime_get();

total_time += ktime_to_ns(ktime_sub(end_time, start_time));
}

return total_time / num_iterations;
}

static ssize_t device_read(struct file *file, char __user *user_buffer, size_t count, loff_t *offset)
{
s64 avg_time;

avg_time = measure_copy_time(user_buffer, count, 1);

pr_info("copy_to_user %lu bytes from the device for %d iterations. Average time taken: %lld ns\n",
count, num_iterations, avg_time);

return count * num_iterations;
}

static ssize_t device_write(struct file *file, const char __user *user_buffer,
size_t count, loff_t *offset)
{
s64 avg_time;

avg_time = measure_copy_time((char __user *)user_buffer, count, 0);

pr_info("copy_from_user %lu bytes to the device for %d iterations. Average time taken: %lld ns\n",
count, num_iterations, avg_time);

return count * num_iterations;
}

static const struct file_operations fops = {
.owner = THIS_MODULE,
.read = device_read,
.write = device_write,
};

static struct miscdevice my_misc_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &fops,
};

static int __init mydevice_init(void)
{
int ret;

device_buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!device_buffer) {
printk(KERN_ALERT "Failed to allocate device buffer\n");
return -ENOMEM;
}

ret = misc_register(&my_misc_device);
if (ret) {
kfree(device_buffer);
printk(KERN_ALERT "Failed to register the misc device\n");
return ret;
}

pr_info("Registered the misc device: %s\n", DEVICE_NAME);
return 0;
}

static void __exit mydevice_exit(void)
{
misc_deregister(&my_misc_device);
kfree(device_buffer);
pr_info("Unregistered the misc device: %s\n", DEVICE_NAME);
}

module_init(mydevice_init);
module_exit(mydevice_exit);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
MODULE_DESCRIPTION("copy_from/to_user speed test module");
66 changes: 66 additions & 0 deletions drivers/soc/renesas/renesas-memcpy-test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/random.h>

static unsigned int memory_size_bytes = 4 * 1024 * 1024;
module_param(memory_size_bytes, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(memory_size_bytes, "Number of bytes transferred per iteration");

static unsigned int memcpy_test_count = 1;
module_param(memcpy_test_count, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(memcpy_test_count, "Number of iterations");

static void *src_buf, *dst_buf;

static s64 perform_memcpy_test(void)
{
ktime_t start_time, end_time;
s64 total_time = 0;
unsigned int i;

for (i = 0; i < memcpy_test_count; i++) {
start_time = ktime_get();

memcpy(dst_buf, src_buf, memory_size_bytes);

end_time = ktime_get();
total_time += ktime_to_ns(ktime_sub(end_time, start_time));
}

return total_time / memcpy_test_count;
}

static int __init memcpy_test_init(void)
{
src_buf = kmalloc(memory_size_bytes, GFP_KERNEL);
if (!src_buf)
return -ENOMEM;

dst_buf = kmalloc(memory_size_bytes, GFP_KERNEL);
if (!dst_buf) {
kfree(src_buf);
return -ENOMEM;
}

pr_info("Average memcpy execution time: %lld ns\n", perform_memcpy_test());

return 0;
}

static void __exit memcpy_test_exit(void)
{
kfree(src_buf);
kfree(dst_buf);
}

module_init(memcpy_test_init);
module_exit(memcpy_test_exit);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
MODULE_DESCRIPTION("memcpy speed test module");
Loading

0 comments on commit 2907a62

Please sign in to comment.