aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2013-07-23 11:36:46 -0400
committerDan Williams <djbw@fb.com>2013-08-23 01:57:32 -0400
commita6c268d033b1f363e0d76c0483a0f99266542820 (patch)
treeaa8c3a5c286637c15ebe18ebe4d65d593d5bd783
parentc095ba7224d8edc71dcef0d655911399a8bd4a3f (diff)
dmatest: make module parameters writable
The debugfs interface brought a copy of the test case parameters. This makes different set of values under /sys/module/dmatest/parameters/ and /sys/kernel/debug/dmatest/. The user might be confused by the divergence of values. The proposed solution in this patch is to make module parameters writable and remove them from the debugfs. Though we're still using debugfs to control test runner and getting results. Documentation part is updated accordingly. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Suggested-by: Dan Williams <djbw@fb.com> Signed-off-by: Dan Williams <djbw@fb.com>
-rw-r--r--Documentation/dmatest.txt15
-rw-r--r--drivers/dma/dmatest.c159
2 files changed, 28 insertions, 146 deletions
diff --git a/Documentation/dmatest.txt b/Documentation/dmatest.txt
index 132a094c7bc3..a2b5663eae26 100644
--- a/Documentation/dmatest.txt
+++ b/Documentation/dmatest.txt
@@ -16,15 +16,16 @@ be built as module or inside kernel. Let's consider those cases.
16 Part 2 - When dmatest is built as a module... 16 Part 2 - When dmatest is built as a module...
17 17
18After mounting debugfs and loading the module, the /sys/kernel/debug/dmatest 18After mounting debugfs and loading the module, the /sys/kernel/debug/dmatest
19folder with nodes will be created. They are the same as module parameters with 19folder with nodes will be created. There are two important files located. First
20addition of the 'run' node that controls run and stop phases of the test. 20is the 'run' node that controls run and stop phases of the test, and the second
21one, 'results', is used to get the test case results.
21 22
22Note that in this case test will not run on load automatically. 23Note that in this case test will not run on load automatically.
23 24
24Example of usage: 25Example of usage:
25 % echo dma0chan0 > /sys/kernel/debug/dmatest/channel 26 % echo dma0chan0 > /sys/module/dmatest/parameters/channel
26 % echo 2000 > /sys/kernel/debug/dmatest/timeout 27 % echo 2000 > /sys/module/dmatest/parameters/timeout
27 % echo 1 > /sys/kernel/debug/dmatest/iterations 28 % echo 1 > /sys/module/dmatest/parameters/iterations
28 % echo 1 > /sys/kernel/debug/dmatest/run 29 % echo 1 > /sys/kernel/debug/dmatest/run
29 30
30Hint: available channel list could be extracted by running the following 31Hint: available channel list could be extracted by running the following
@@ -55,8 +56,8 @@ for the first performed test. After user gets a control, the test could be
55re-run with the same or different parameters. For the details see the above 56re-run with the same or different parameters. For the details see the above
56section "Part 2 - When dmatest is built as a module..." 57section "Part 2 - When dmatest is built as a module..."
57 58
58In both cases the module parameters are used as initial values for the test case. 59In both cases the module parameters are used as the actual values for the test
59You always could check them at run-time by running 60case. You always could check them at run-time by running
60 % grep -H . /sys/module/dmatest/parameters/* 61 % grep -H . /sys/module/dmatest/parameters/*
61 62
62 Part 4 - Gathering the test results 63 Part 4 - Gathering the test results
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index e88ded2c8d2f..91716f404c03 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -25,44 +25,46 @@
25#include <linux/seq_file.h> 25#include <linux/seq_file.h>
26 26
27static unsigned int test_buf_size = 16384; 27static unsigned int test_buf_size = 16384;
28module_param(test_buf_size, uint, S_IRUGO); 28module_param(test_buf_size, uint, S_IRUGO | S_IWUSR);
29MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); 29MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer");
30 30
31static char test_channel[20]; 31static char test_channel[20];
32module_param_string(channel, test_channel, sizeof(test_channel), S_IRUGO); 32module_param_string(channel, test_channel, sizeof(test_channel),
33 S_IRUGO | S_IWUSR);
33MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)"); 34MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)");
34 35
35static char test_device[20]; 36static char test_device[20];
36module_param_string(device, test_device, sizeof(test_device), S_IRUGO); 37module_param_string(device, test_device, sizeof(test_device),
38 S_IRUGO | S_IWUSR);
37MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)"); 39MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)");
38 40
39static unsigned int threads_per_chan = 1; 41static unsigned int threads_per_chan = 1;
40module_param(threads_per_chan, uint, S_IRUGO); 42module_param(threads_per_chan, uint, S_IRUGO | S_IWUSR);
41MODULE_PARM_DESC(threads_per_chan, 43MODULE_PARM_DESC(threads_per_chan,
42 "Number of threads to start per channel (default: 1)"); 44 "Number of threads to start per channel (default: 1)");
43 45
44static unsigned int max_channels; 46static unsigned int max_channels;
45module_param(max_channels, uint, S_IRUGO); 47module_param(max_channels, uint, S_IRUGO | S_IWUSR);
46MODULE_PARM_DESC(max_channels, 48MODULE_PARM_DESC(max_channels,
47 "Maximum number of channels to use (default: all)"); 49 "Maximum number of channels to use (default: all)");
48 50
49static unsigned int iterations; 51static unsigned int iterations;
50module_param(iterations, uint, S_IRUGO); 52module_param(iterations, uint, S_IRUGO | S_IWUSR);
51MODULE_PARM_DESC(iterations, 53MODULE_PARM_DESC(iterations,
52 "Iterations before stopping test (default: infinite)"); 54 "Iterations before stopping test (default: infinite)");
53 55
54static unsigned int xor_sources = 3; 56static unsigned int xor_sources = 3;
55module_param(xor_sources, uint, S_IRUGO); 57module_param(xor_sources, uint, S_IRUGO | S_IWUSR);
56MODULE_PARM_DESC(xor_sources, 58MODULE_PARM_DESC(xor_sources,
57 "Number of xor source buffers (default: 3)"); 59 "Number of xor source buffers (default: 3)");
58 60
59static unsigned int pq_sources = 3; 61static unsigned int pq_sources = 3;
60module_param(pq_sources, uint, S_IRUGO); 62module_param(pq_sources, uint, S_IRUGO | S_IWUSR);
61MODULE_PARM_DESC(pq_sources, 63MODULE_PARM_DESC(pq_sources,
62 "Number of p+q source buffers (default: 3)"); 64 "Number of p+q source buffers (default: 3)");
63 65
64static int timeout = 3000; 66static int timeout = 3000;
65module_param(timeout, uint, S_IRUGO); 67module_param(timeout, uint, S_IRUGO | S_IWUSR);
66MODULE_PARM_DESC(timeout, "Transfer Timeout in msec (default: 3000), " 68MODULE_PARM_DESC(timeout, "Transfer Timeout in msec (default: 3000), "
67 "Pass -1 for infinite timeout"); 69 "Pass -1 for infinite timeout");
68 70
@@ -193,7 +195,6 @@ struct dmatest_info {
193 195
194 /* debugfs related stuff */ 196 /* debugfs related stuff */
195 struct dentry *root; 197 struct dentry *root;
196 struct dmatest_params dbgfs_params;
197 198
198 /* Test results */ 199 /* Test results */
199 struct list_head results; 200 struct list_head results;
@@ -1007,7 +1008,15 @@ static int __restart_threaded_test(struct dmatest_info *info, bool run)
1007 result_free(info, NULL); 1008 result_free(info, NULL);
1008 1009
1009 /* Copy test parameters */ 1010 /* Copy test parameters */
1010 memcpy(params, &info->dbgfs_params, sizeof(*params)); 1011 params->buf_size = test_buf_size;
1012 strlcpy(params->channel, strim(test_channel), sizeof(params->channel));
1013 strlcpy(params->device, strim(test_device), sizeof(params->device));
1014 params->threads_per_chan = threads_per_chan;
1015 params->max_channels = max_channels;
1016 params->iterations = iterations;
1017 params->xor_sources = xor_sources;
1018 params->pq_sources = pq_sources;
1019 params->timeout = timeout;
1011 1020
1012 /* Run test with new parameters */ 1021 /* Run test with new parameters */
1013 return __run_threaded_test(info); 1022 return __run_threaded_test(info);
@@ -1029,71 +1038,6 @@ static bool __is_threaded_test_run(struct dmatest_info *info)
1029 return false; 1038 return false;
1030} 1039}
1031 1040
1032static ssize_t dtf_write_string(void *to, size_t available, loff_t *ppos,
1033 const void __user *from, size_t count)
1034{
1035 char tmp[20];
1036 ssize_t len;
1037
1038 len = simple_write_to_buffer(tmp, sizeof(tmp) - 1, ppos, from, count);
1039 if (len >= 0) {
1040 tmp[len] = '\0';
1041 strlcpy(to, strim(tmp), available);
1042 }
1043
1044 return len;
1045}
1046
1047static ssize_t dtf_read_channel(struct file *file, char __user *buf,
1048 size_t count, loff_t *ppos)
1049{
1050 struct dmatest_info *info = file->private_data;
1051 return simple_read_from_buffer(buf, count, ppos,
1052 info->dbgfs_params.channel,
1053 strlen(info->dbgfs_params.channel));
1054}
1055
1056static ssize_t dtf_write_channel(struct file *file, const char __user *buf,
1057 size_t size, loff_t *ppos)
1058{
1059 struct dmatest_info *info = file->private_data;
1060 return dtf_write_string(info->dbgfs_params.channel,
1061 sizeof(info->dbgfs_params.channel),
1062 ppos, buf, size);
1063}
1064
1065static const struct file_operations dtf_channel_fops = {
1066 .read = dtf_read_channel,
1067 .write = dtf_write_channel,
1068 .open = simple_open,
1069 .llseek = default_llseek,
1070};
1071
1072static ssize_t dtf_read_device(struct file *file, char __user *buf,
1073 size_t count, loff_t *ppos)
1074{
1075 struct dmatest_info *info = file->private_data;
1076 return simple_read_from_buffer(buf, count, ppos,
1077 info->dbgfs_params.device,
1078 strlen(info->dbgfs_params.device));
1079}
1080
1081static ssize_t dtf_write_device(struct file *file, const char __user *buf,
1082 size_t size, loff_t *ppos)
1083{
1084 struct dmatest_info *info = file->private_data;
1085 return dtf_write_string(info->dbgfs_params.device,
1086 sizeof(info->dbgfs_params.device),
1087 ppos, buf, size);
1088}
1089
1090static const struct file_operations dtf_device_fops = {
1091 .read = dtf_read_device,
1092 .write = dtf_write_device,
1093 .open = simple_open,
1094 .llseek = default_llseek,
1095};
1096
1097static ssize_t dtf_read_run(struct file *file, char __user *user_buf, 1041static ssize_t dtf_read_run(struct file *file, char __user *user_buf,
1098 size_t count, loff_t *ppos) 1042 size_t count, loff_t *ppos)
1099{ 1043{
@@ -1187,7 +1131,6 @@ static const struct file_operations dtf_results_fops = {
1187static int dmatest_register_dbgfs(struct dmatest_info *info) 1131static int dmatest_register_dbgfs(struct dmatest_info *info)
1188{ 1132{
1189 struct dentry *d; 1133 struct dentry *d;
1190 struct dmatest_params *params = &info->dbgfs_params;
1191 int ret = -ENOMEM; 1134 int ret = -ENOMEM;
1192 1135
1193 d = debugfs_create_dir("dmatest", NULL); 1136 d = debugfs_create_dir("dmatest", NULL);
@@ -1198,56 +1141,6 @@ static int dmatest_register_dbgfs(struct dmatest_info *info)
1198 1141
1199 info->root = d; 1142 info->root = d;
1200 1143
1201 /* Copy initial values */
1202 memcpy(params, &info->params, sizeof(*params));
1203
1204 /* Test parameters */
1205
1206 d = debugfs_create_u32("test_buf_size", S_IWUSR | S_IRUGO, info->root,
1207 (u32 *)&params->buf_size);
1208 if (IS_ERR_OR_NULL(d))
1209 goto err_node;
1210
1211 d = debugfs_create_file("channel", S_IRUGO | S_IWUSR, info->root,
1212 info, &dtf_channel_fops);
1213 if (IS_ERR_OR_NULL(d))
1214 goto err_node;
1215
1216 d = debugfs_create_file("device", S_IRUGO | S_IWUSR, info->root,
1217 info, &dtf_device_fops);
1218 if (IS_ERR_OR_NULL(d))
1219 goto err_node;
1220
1221 d = debugfs_create_u32("threads_per_chan", S_IWUSR | S_IRUGO, info->root,
1222 (u32 *)&params->threads_per_chan);
1223 if (IS_ERR_OR_NULL(d))
1224 goto err_node;
1225
1226 d = debugfs_create_u32("max_channels", S_IWUSR | S_IRUGO, info->root,
1227 (u32 *)&params->max_channels);
1228 if (IS_ERR_OR_NULL(d))
1229 goto err_node;
1230
1231 d = debugfs_create_u32("iterations", S_IWUSR | S_IRUGO, info->root,
1232 (u32 *)&params->iterations);
1233 if (IS_ERR_OR_NULL(d))
1234 goto err_node;
1235
1236 d = debugfs_create_u32("xor_sources", S_IWUSR | S_IRUGO, info->root,
1237 (u32 *)&params->xor_sources);
1238 if (IS_ERR_OR_NULL(d))
1239 goto err_node;
1240
1241 d = debugfs_create_u32("pq_sources", S_IWUSR | S_IRUGO, info->root,
1242 (u32 *)&params->pq_sources);
1243 if (IS_ERR_OR_NULL(d))
1244 goto err_node;
1245
1246 d = debugfs_create_u32("timeout", S_IWUSR | S_IRUGO, info->root,
1247 (u32 *)&params->timeout);
1248 if (IS_ERR_OR_NULL(d))
1249 goto err_node;
1250
1251 /* Run or stop threaded test */ 1144 /* Run or stop threaded test */
1252 d = debugfs_create_file("run", S_IWUSR | S_IRUGO, info->root, 1145 d = debugfs_create_file("run", S_IWUSR | S_IRUGO, info->root,
1253 info, &dtf_run_fops); 1146 info, &dtf_run_fops);
@@ -1272,7 +1165,6 @@ err_root:
1272static int __init dmatest_init(void) 1165static int __init dmatest_init(void)
1273{ 1166{
1274 struct dmatest_info *info = &test_info; 1167 struct dmatest_info *info = &test_info;
1275 struct dmatest_params *params = &info->params;
1276 int ret; 1168 int ret;
1277 1169
1278 memset(info, 0, sizeof(*info)); 1170 memset(info, 0, sizeof(*info));
@@ -1283,17 +1175,6 @@ static int __init dmatest_init(void)
1283 mutex_init(&info->results_lock); 1175 mutex_init(&info->results_lock);
1284 INIT_LIST_HEAD(&info->results); 1176 INIT_LIST_HEAD(&info->results);
1285 1177
1286 /* Set default parameters */
1287 params->buf_size = test_buf_size;
1288 strlcpy(params->channel, test_channel, sizeof(params->channel));
1289 strlcpy(params->device, test_device, sizeof(params->device));
1290 params->threads_per_chan = threads_per_chan;
1291 params->max_channels = max_channels;
1292 params->iterations = iterations;
1293 params->xor_sources = xor_sources;
1294 params->pq_sources = pq_sources;
1295 params->timeout = timeout;
1296
1297 ret = dmatest_register_dbgfs(info); 1178 ret = dmatest_register_dbgfs(info);
1298 if (ret) 1179 if (ret)
1299 return ret; 1180 return ret;