forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
soc: renesas: Add memory related test in tight loop
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
- Loading branch information
1 parent
7e36d23
commit 2907a62
Showing
5 changed files
with
478 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); |
Oops, something went wrong.