0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include <linux/kernel.h>
0028 #include <linux/module.h>
0029 #include <linux/kmod.h>
0030 #include <linux/printk.h>
0031 #include <linux/kthread.h>
0032 #include <linux/sched.h>
0033 #include <linux/fs.h>
0034 #include <linux/miscdevice.h>
0035 #include <linux/vmalloc.h>
0036 #include <linux/slab.h>
0037 #include <linux/device.h>
0038
0039 #define TEST_START_NUM_THREADS 50
0040 #define TEST_START_DRIVER "test_module"
0041 #define TEST_START_TEST_FS "xfs"
0042 #define TEST_START_TEST_CASE TEST_KMOD_DRIVER
0043
0044
0045 static bool force_init_test = false;
0046 module_param(force_init_test, bool_enable_only, 0644);
0047 MODULE_PARM_DESC(force_init_test,
0048 "Force kicking a test immediately after driver loads");
0049
0050
0051
0052
0053 static DEFINE_MUTEX(reg_dev_mutex);
0054 static LIST_HEAD(reg_test_devs);
0055
0056
0057
0058
0059
0060 static int num_test_devs;
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 enum kmod_test_case {
0072 __TEST_KMOD_INVALID = 0,
0073
0074 TEST_KMOD_DRIVER,
0075 TEST_KMOD_FS_TYPE,
0076
0077 __TEST_KMOD_MAX,
0078 };
0079
0080 struct test_config {
0081 char *test_driver;
0082 char *test_fs;
0083 unsigned int num_threads;
0084 enum kmod_test_case test_case;
0085 int test_result;
0086 };
0087
0088 struct kmod_test_device;
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 struct kmod_test_device_info {
0105 int ret_sync;
0106 struct file_system_type *fs_sync;
0107 struct task_struct *task_sync;
0108 unsigned int thread_idx;
0109 struct kmod_test_device *test_dev;
0110 bool need_mod_put;
0111 };
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 struct kmod_test_device {
0130 int dev_idx;
0131 struct test_config config;
0132 struct miscdevice misc_dev;
0133 struct device *dev;
0134 struct mutex config_mutex;
0135 struct mutex trigger_mutex;
0136 struct mutex thread_mutex;
0137
0138 unsigned int done;
0139
0140 bool test_is_oom;
0141 struct completion kthreads_done;
0142 struct list_head list;
0143
0144 struct kmod_test_device_info *info;
0145 };
0146
0147 static const char *test_case_str(enum kmod_test_case test_case)
0148 {
0149 switch (test_case) {
0150 case TEST_KMOD_DRIVER:
0151 return "TEST_KMOD_DRIVER";
0152 case TEST_KMOD_FS_TYPE:
0153 return "TEST_KMOD_FS_TYPE";
0154 default:
0155 return "invalid";
0156 }
0157 }
0158
0159 static struct miscdevice *dev_to_misc_dev(struct device *dev)
0160 {
0161 return dev_get_drvdata(dev);
0162 }
0163
0164 static struct kmod_test_device *misc_dev_to_test_dev(struct miscdevice *misc_dev)
0165 {
0166 return container_of(misc_dev, struct kmod_test_device, misc_dev);
0167 }
0168
0169 static struct kmod_test_device *dev_to_test_dev(struct device *dev)
0170 {
0171 struct miscdevice *misc_dev;
0172
0173 misc_dev = dev_to_misc_dev(dev);
0174
0175 return misc_dev_to_test_dev(misc_dev);
0176 }
0177
0178
0179 static void kmod_test_done_check(struct kmod_test_device *test_dev,
0180 unsigned int idx)
0181 {
0182 struct test_config *config = &test_dev->config;
0183
0184 test_dev->done++;
0185 dev_dbg(test_dev->dev, "Done thread count: %u\n", test_dev->done);
0186
0187 if (test_dev->done == config->num_threads) {
0188 dev_info(test_dev->dev, "Done: %u threads have all run now\n",
0189 test_dev->done);
0190 dev_info(test_dev->dev, "Last thread to run: %u\n", idx);
0191 complete(&test_dev->kthreads_done);
0192 }
0193 }
0194
0195 static void test_kmod_put_module(struct kmod_test_device_info *info)
0196 {
0197 struct kmod_test_device *test_dev = info->test_dev;
0198 struct test_config *config = &test_dev->config;
0199
0200 if (!info->need_mod_put)
0201 return;
0202
0203 switch (config->test_case) {
0204 case TEST_KMOD_DRIVER:
0205 break;
0206 case TEST_KMOD_FS_TYPE:
0207 if (info->fs_sync && info->fs_sync->owner)
0208 module_put(info->fs_sync->owner);
0209 break;
0210 default:
0211 BUG();
0212 }
0213
0214 info->need_mod_put = true;
0215 }
0216
0217 static int run_request(void *data)
0218 {
0219 struct kmod_test_device_info *info = data;
0220 struct kmod_test_device *test_dev = info->test_dev;
0221 struct test_config *config = &test_dev->config;
0222
0223 switch (config->test_case) {
0224 case TEST_KMOD_DRIVER:
0225 info->ret_sync = request_module("%s", config->test_driver);
0226 break;
0227 case TEST_KMOD_FS_TYPE:
0228 info->fs_sync = get_fs_type(config->test_fs);
0229 info->need_mod_put = true;
0230 break;
0231 default:
0232
0233 BUG();
0234 return -EINVAL;
0235 }
0236
0237 dev_dbg(test_dev->dev, "Ran thread %u\n", info->thread_idx);
0238
0239 test_kmod_put_module(info);
0240
0241 mutex_lock(&test_dev->thread_mutex);
0242 info->task_sync = NULL;
0243 kmod_test_done_check(test_dev, info->thread_idx);
0244 mutex_unlock(&test_dev->thread_mutex);
0245
0246 return 0;
0247 }
0248
0249 static int tally_work_test(struct kmod_test_device_info *info)
0250 {
0251 struct kmod_test_device *test_dev = info->test_dev;
0252 struct test_config *config = &test_dev->config;
0253 int err_ret = 0;
0254
0255 switch (config->test_case) {
0256 case TEST_KMOD_DRIVER:
0257
0258
0259
0260
0261 if (info->ret_sync != 0)
0262 err_ret = info->ret_sync;
0263 dev_info(test_dev->dev,
0264 "Sync thread %d return status: %d\n",
0265 info->thread_idx, info->ret_sync);
0266 break;
0267 case TEST_KMOD_FS_TYPE:
0268
0269 if (!info->fs_sync)
0270 err_ret = -EINVAL;
0271 dev_info(test_dev->dev, "Sync thread %u fs: %s\n",
0272 info->thread_idx, info->fs_sync ? config->test_fs :
0273 "NULL");
0274 break;
0275 default:
0276 BUG();
0277 }
0278
0279 return err_ret;
0280 }
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291 static void tally_up_work(struct kmod_test_device *test_dev)
0292 {
0293 struct test_config *config = &test_dev->config;
0294 struct kmod_test_device_info *info;
0295 unsigned int idx;
0296 int err_ret = 0;
0297 int ret = 0;
0298
0299 mutex_lock(&test_dev->thread_mutex);
0300
0301 dev_info(test_dev->dev, "Results:\n");
0302
0303 for (idx=0; idx < config->num_threads; idx++) {
0304 info = &test_dev->info[idx];
0305 ret = tally_work_test(info);
0306 if (ret)
0307 err_ret = ret;
0308 }
0309
0310
0311
0312
0313
0314 config->test_result = err_ret;
0315
0316 mutex_unlock(&test_dev->thread_mutex);
0317 }
0318
0319 static int try_one_request(struct kmod_test_device *test_dev, unsigned int idx)
0320 {
0321 struct kmod_test_device_info *info = &test_dev->info[idx];
0322 int fail_ret = -ENOMEM;
0323
0324 mutex_lock(&test_dev->thread_mutex);
0325
0326 info->thread_idx = idx;
0327 info->test_dev = test_dev;
0328 info->task_sync = kthread_run(run_request, info, "%s-%u",
0329 KBUILD_MODNAME, idx);
0330
0331 if (!info->task_sync || IS_ERR(info->task_sync)) {
0332 test_dev->test_is_oom = true;
0333 dev_err(test_dev->dev, "Setting up thread %u failed\n", idx);
0334 info->task_sync = NULL;
0335 goto err_out;
0336 } else
0337 dev_dbg(test_dev->dev, "Kicked off thread %u\n", idx);
0338
0339 mutex_unlock(&test_dev->thread_mutex);
0340
0341 return 0;
0342
0343 err_out:
0344 info->ret_sync = fail_ret;
0345 mutex_unlock(&test_dev->thread_mutex);
0346
0347 return fail_ret;
0348 }
0349
0350 static void test_dev_kmod_stop_tests(struct kmod_test_device *test_dev)
0351 {
0352 struct test_config *config = &test_dev->config;
0353 struct kmod_test_device_info *info;
0354 unsigned int i;
0355
0356 dev_info(test_dev->dev, "Ending request_module() tests\n");
0357
0358 mutex_lock(&test_dev->thread_mutex);
0359
0360 for (i=0; i < config->num_threads; i++) {
0361 info = &test_dev->info[i];
0362 if (info->task_sync && !IS_ERR(info->task_sync)) {
0363 dev_info(test_dev->dev,
0364 "Stopping still-running thread %i\n", i);
0365 kthread_stop(info->task_sync);
0366 }
0367
0368
0369
0370
0371
0372
0373
0374
0375 if (info->task_sync && info->need_mod_put)
0376 test_kmod_put_module(info);
0377 }
0378
0379 mutex_unlock(&test_dev->thread_mutex);
0380 }
0381
0382
0383
0384
0385
0386
0387
0388 static int try_requests(struct kmod_test_device *test_dev)
0389 {
0390 struct test_config *config = &test_dev->config;
0391 unsigned int idx;
0392 int ret;
0393 bool any_error = false;
0394
0395 for (idx=0; idx < config->num_threads; idx++) {
0396 if (test_dev->test_is_oom) {
0397 any_error = true;
0398 break;
0399 }
0400
0401 ret = try_one_request(test_dev, idx);
0402 if (ret) {
0403 any_error = true;
0404 break;
0405 }
0406 }
0407
0408 if (!any_error) {
0409 test_dev->test_is_oom = false;
0410 dev_info(test_dev->dev,
0411 "No errors were found while initializing threads\n");
0412 wait_for_completion(&test_dev->kthreads_done);
0413 tally_up_work(test_dev);
0414 } else {
0415 test_dev->test_is_oom = true;
0416 dev_info(test_dev->dev,
0417 "At least one thread failed to start, stop all work\n");
0418 test_dev_kmod_stop_tests(test_dev);
0419 return -ENOMEM;
0420 }
0421
0422 return 0;
0423 }
0424
0425 static int run_test_driver(struct kmod_test_device *test_dev)
0426 {
0427 struct test_config *config = &test_dev->config;
0428
0429 dev_info(test_dev->dev, "Test case: %s (%u)\n",
0430 test_case_str(config->test_case),
0431 config->test_case);
0432 dev_info(test_dev->dev, "Test driver to load: %s\n",
0433 config->test_driver);
0434 dev_info(test_dev->dev, "Number of threads to run: %u\n",
0435 config->num_threads);
0436 dev_info(test_dev->dev, "Thread IDs will range from 0 - %u\n",
0437 config->num_threads - 1);
0438
0439 return try_requests(test_dev);
0440 }
0441
0442 static int run_test_fs_type(struct kmod_test_device *test_dev)
0443 {
0444 struct test_config *config = &test_dev->config;
0445
0446 dev_info(test_dev->dev, "Test case: %s (%u)\n",
0447 test_case_str(config->test_case),
0448 config->test_case);
0449 dev_info(test_dev->dev, "Test filesystem to load: %s\n",
0450 config->test_fs);
0451 dev_info(test_dev->dev, "Number of threads to run: %u\n",
0452 config->num_threads);
0453 dev_info(test_dev->dev, "Thread IDs will range from 0 - %u\n",
0454 config->num_threads - 1);
0455
0456 return try_requests(test_dev);
0457 }
0458
0459 static ssize_t config_show(struct device *dev,
0460 struct device_attribute *attr,
0461 char *buf)
0462 {
0463 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
0464 struct test_config *config = &test_dev->config;
0465 int len = 0;
0466
0467 mutex_lock(&test_dev->config_mutex);
0468
0469 len += snprintf(buf, PAGE_SIZE,
0470 "Custom trigger configuration for: %s\n",
0471 dev_name(dev));
0472
0473 len += snprintf(buf+len, PAGE_SIZE - len,
0474 "Number of threads:\t%u\n",
0475 config->num_threads);
0476
0477 len += snprintf(buf+len, PAGE_SIZE - len,
0478 "Test_case:\t%s (%u)\n",
0479 test_case_str(config->test_case),
0480 config->test_case);
0481
0482 if (config->test_driver)
0483 len += snprintf(buf+len, PAGE_SIZE - len,
0484 "driver:\t%s\n",
0485 config->test_driver);
0486 else
0487 len += snprintf(buf+len, PAGE_SIZE - len,
0488 "driver:\tEMPTY\n");
0489
0490 if (config->test_fs)
0491 len += snprintf(buf+len, PAGE_SIZE - len,
0492 "fs:\t%s\n",
0493 config->test_fs);
0494 else
0495 len += snprintf(buf+len, PAGE_SIZE - len,
0496 "fs:\tEMPTY\n");
0497
0498 mutex_unlock(&test_dev->config_mutex);
0499
0500 return len;
0501 }
0502 static DEVICE_ATTR_RO(config);
0503
0504
0505
0506
0507
0508 static int __trigger_config_run(struct kmod_test_device *test_dev)
0509 {
0510 struct test_config *config = &test_dev->config;
0511
0512 test_dev->done = 0;
0513
0514 switch (config->test_case) {
0515 case TEST_KMOD_DRIVER:
0516 return run_test_driver(test_dev);
0517 case TEST_KMOD_FS_TYPE:
0518 return run_test_fs_type(test_dev);
0519 default:
0520 dev_warn(test_dev->dev,
0521 "Invalid test case requested: %u\n",
0522 config->test_case);
0523 return -EINVAL;
0524 }
0525 }
0526
0527 static int trigger_config_run(struct kmod_test_device *test_dev)
0528 {
0529 struct test_config *config = &test_dev->config;
0530 int ret;
0531
0532 mutex_lock(&test_dev->trigger_mutex);
0533 mutex_lock(&test_dev->config_mutex);
0534
0535 ret = __trigger_config_run(test_dev);
0536 if (ret < 0)
0537 goto out;
0538 dev_info(test_dev->dev, "General test result: %d\n",
0539 config->test_result);
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554 ret = 0;
0555
0556 out:
0557 mutex_unlock(&test_dev->config_mutex);
0558 mutex_unlock(&test_dev->trigger_mutex);
0559
0560 return ret;
0561 }
0562
0563 static ssize_t
0564 trigger_config_store(struct device *dev,
0565 struct device_attribute *attr,
0566 const char *buf, size_t count)
0567 {
0568 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
0569 int ret;
0570
0571 if (test_dev->test_is_oom)
0572 return -ENOMEM;
0573
0574
0575
0576
0577
0578
0579
0580 ret = trigger_config_run(test_dev);
0581 if (unlikely(ret < 0))
0582 goto out;
0583
0584
0585
0586
0587
0588
0589
0590 if (WARN_ON(ret > 0))
0591 return -EINVAL;
0592
0593 ret = count;
0594 out:
0595 return ret;
0596 }
0597 static DEVICE_ATTR_WO(trigger_config);
0598
0599
0600
0601
0602
0603
0604 static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp)
0605 {
0606 *dst = kstrndup(name, count, gfp);
0607 if (!*dst)
0608 return -ENOSPC;
0609 return count;
0610 }
0611
0612 static int config_copy_test_driver_name(struct test_config *config,
0613 const char *name,
0614 size_t count)
0615 {
0616 return __kstrncpy(&config->test_driver, name, count, GFP_KERNEL);
0617 }
0618
0619
0620 static int config_copy_test_fs(struct test_config *config, const char *name,
0621 size_t count)
0622 {
0623 return __kstrncpy(&config->test_fs, name, count, GFP_KERNEL);
0624 }
0625
0626 static void __kmod_config_free(struct test_config *config)
0627 {
0628 if (!config)
0629 return;
0630
0631 kfree_const(config->test_driver);
0632 config->test_driver = NULL;
0633
0634 kfree_const(config->test_fs);
0635 config->test_fs = NULL;
0636 }
0637
0638 static void kmod_config_free(struct kmod_test_device *test_dev)
0639 {
0640 struct test_config *config;
0641
0642 if (!test_dev)
0643 return;
0644
0645 config = &test_dev->config;
0646
0647 mutex_lock(&test_dev->config_mutex);
0648 __kmod_config_free(config);
0649 mutex_unlock(&test_dev->config_mutex);
0650 }
0651
0652 static ssize_t config_test_driver_store(struct device *dev,
0653 struct device_attribute *attr,
0654 const char *buf, size_t count)
0655 {
0656 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
0657 struct test_config *config = &test_dev->config;
0658 int copied;
0659
0660 mutex_lock(&test_dev->config_mutex);
0661
0662 kfree_const(config->test_driver);
0663 config->test_driver = NULL;
0664
0665 copied = config_copy_test_driver_name(config, buf, count);
0666 mutex_unlock(&test_dev->config_mutex);
0667
0668 return copied;
0669 }
0670
0671
0672
0673
0674 static ssize_t config_test_show_str(struct mutex *config_mutex,
0675 char *dst,
0676 char *src)
0677 {
0678 int len;
0679
0680 mutex_lock(config_mutex);
0681 len = snprintf(dst, PAGE_SIZE, "%s\n", src);
0682 mutex_unlock(config_mutex);
0683
0684 return len;
0685 }
0686
0687 static ssize_t config_test_driver_show(struct device *dev,
0688 struct device_attribute *attr,
0689 char *buf)
0690 {
0691 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
0692 struct test_config *config = &test_dev->config;
0693
0694 return config_test_show_str(&test_dev->config_mutex, buf,
0695 config->test_driver);
0696 }
0697 static DEVICE_ATTR_RW(config_test_driver);
0698
0699 static ssize_t config_test_fs_store(struct device *dev,
0700 struct device_attribute *attr,
0701 const char *buf, size_t count)
0702 {
0703 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
0704 struct test_config *config = &test_dev->config;
0705 int copied;
0706
0707 mutex_lock(&test_dev->config_mutex);
0708
0709 kfree_const(config->test_fs);
0710 config->test_fs = NULL;
0711
0712 copied = config_copy_test_fs(config, buf, count);
0713 mutex_unlock(&test_dev->config_mutex);
0714
0715 return copied;
0716 }
0717
0718 static ssize_t config_test_fs_show(struct device *dev,
0719 struct device_attribute *attr,
0720 char *buf)
0721 {
0722 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
0723 struct test_config *config = &test_dev->config;
0724
0725 return config_test_show_str(&test_dev->config_mutex, buf,
0726 config->test_fs);
0727 }
0728 static DEVICE_ATTR_RW(config_test_fs);
0729
0730 static int trigger_config_run_type(struct kmod_test_device *test_dev,
0731 enum kmod_test_case test_case,
0732 const char *test_str)
0733 {
0734 int copied = 0;
0735 struct test_config *config = &test_dev->config;
0736
0737 mutex_lock(&test_dev->config_mutex);
0738
0739 switch (test_case) {
0740 case TEST_KMOD_DRIVER:
0741 kfree_const(config->test_driver);
0742 config->test_driver = NULL;
0743 copied = config_copy_test_driver_name(config, test_str,
0744 strlen(test_str));
0745 break;
0746 case TEST_KMOD_FS_TYPE:
0747 kfree_const(config->test_fs);
0748 config->test_fs = NULL;
0749 copied = config_copy_test_fs(config, test_str,
0750 strlen(test_str));
0751 break;
0752 default:
0753 mutex_unlock(&test_dev->config_mutex);
0754 return -EINVAL;
0755 }
0756
0757 config->test_case = test_case;
0758
0759 mutex_unlock(&test_dev->config_mutex);
0760
0761 if (copied <= 0 || copied != strlen(test_str)) {
0762 test_dev->test_is_oom = true;
0763 return -ENOMEM;
0764 }
0765
0766 test_dev->test_is_oom = false;
0767
0768 return trigger_config_run(test_dev);
0769 }
0770
0771 static void free_test_dev_info(struct kmod_test_device *test_dev)
0772 {
0773 vfree(test_dev->info);
0774 test_dev->info = NULL;
0775 }
0776
0777 static int kmod_config_sync_info(struct kmod_test_device *test_dev)
0778 {
0779 struct test_config *config = &test_dev->config;
0780
0781 free_test_dev_info(test_dev);
0782 test_dev->info =
0783 vzalloc(array_size(sizeof(struct kmod_test_device_info),
0784 config->num_threads));
0785 if (!test_dev->info)
0786 return -ENOMEM;
0787
0788 return 0;
0789 }
0790
0791
0792
0793
0794
0795 #ifdef get_kmod_umh_limit
0796 static unsigned int kmod_init_test_thread_limit(void)
0797 {
0798 return get_kmod_umh_limit();
0799 }
0800 #else
0801 static unsigned int kmod_init_test_thread_limit(void)
0802 {
0803 return TEST_START_NUM_THREADS;
0804 }
0805 #endif
0806
0807 static int __kmod_config_init(struct kmod_test_device *test_dev)
0808 {
0809 struct test_config *config = &test_dev->config;
0810 int ret = -ENOMEM, copied;
0811
0812 __kmod_config_free(config);
0813
0814 copied = config_copy_test_driver_name(config, TEST_START_DRIVER,
0815 strlen(TEST_START_DRIVER));
0816 if (copied != strlen(TEST_START_DRIVER))
0817 goto err_out;
0818
0819 copied = config_copy_test_fs(config, TEST_START_TEST_FS,
0820 strlen(TEST_START_TEST_FS));
0821 if (copied != strlen(TEST_START_TEST_FS))
0822 goto err_out;
0823
0824 config->num_threads = kmod_init_test_thread_limit();
0825 config->test_result = 0;
0826 config->test_case = TEST_START_TEST_CASE;
0827
0828 ret = kmod_config_sync_info(test_dev);
0829 if (ret)
0830 goto err_out;
0831
0832 test_dev->test_is_oom = false;
0833
0834 return 0;
0835
0836 err_out:
0837 test_dev->test_is_oom = true;
0838 WARN_ON(test_dev->test_is_oom);
0839
0840 __kmod_config_free(config);
0841
0842 return ret;
0843 }
0844
0845 static ssize_t reset_store(struct device *dev,
0846 struct device_attribute *attr,
0847 const char *buf, size_t count)
0848 {
0849 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
0850 int ret;
0851
0852 mutex_lock(&test_dev->trigger_mutex);
0853 mutex_lock(&test_dev->config_mutex);
0854
0855 ret = __kmod_config_init(test_dev);
0856 if (ret < 0) {
0857 ret = -ENOMEM;
0858 dev_err(dev, "could not alloc settings for config trigger: %d\n",
0859 ret);
0860 goto out;
0861 }
0862
0863 dev_info(dev, "reset\n");
0864 ret = count;
0865
0866 out:
0867 mutex_unlock(&test_dev->config_mutex);
0868 mutex_unlock(&test_dev->trigger_mutex);
0869
0870 return ret;
0871 }
0872 static DEVICE_ATTR_WO(reset);
0873
0874 static int test_dev_config_update_uint_sync(struct kmod_test_device *test_dev,
0875 const char *buf, size_t size,
0876 unsigned int *config,
0877 int (*test_sync)(struct kmod_test_device *test_dev))
0878 {
0879 int ret;
0880 unsigned int val;
0881 unsigned int old_val;
0882
0883 ret = kstrtouint(buf, 10, &val);
0884 if (ret)
0885 return ret;
0886
0887 mutex_lock(&test_dev->config_mutex);
0888
0889 old_val = *config;
0890 *(unsigned int *)config = val;
0891
0892 ret = test_sync(test_dev);
0893 if (ret) {
0894 *(unsigned int *)config = old_val;
0895
0896 ret = test_sync(test_dev);
0897 WARN_ON(ret);
0898
0899 mutex_unlock(&test_dev->config_mutex);
0900 return -EINVAL;
0901 }
0902
0903 mutex_unlock(&test_dev->config_mutex);
0904
0905 return size;
0906 }
0907
0908 static int test_dev_config_update_uint_range(struct kmod_test_device *test_dev,
0909 const char *buf, size_t size,
0910 unsigned int *config,
0911 unsigned int min,
0912 unsigned int max)
0913 {
0914 unsigned int val;
0915 int ret;
0916
0917 ret = kstrtouint(buf, 10, &val);
0918 if (ret)
0919 return ret;
0920
0921 if (val < min || val > max)
0922 return -EINVAL;
0923
0924 mutex_lock(&test_dev->config_mutex);
0925 *config = val;
0926 mutex_unlock(&test_dev->config_mutex);
0927
0928
0929 return size;
0930 }
0931
0932 static int test_dev_config_update_int(struct kmod_test_device *test_dev,
0933 const char *buf, size_t size,
0934 int *config)
0935 {
0936 int val;
0937 int ret;
0938
0939 ret = kstrtoint(buf, 10, &val);
0940 if (ret)
0941 return ret;
0942
0943 mutex_lock(&test_dev->config_mutex);
0944 *config = val;
0945 mutex_unlock(&test_dev->config_mutex);
0946
0947 return size;
0948 }
0949
0950 static ssize_t test_dev_config_show_int(struct kmod_test_device *test_dev,
0951 char *buf,
0952 int config)
0953 {
0954 int val;
0955
0956 mutex_lock(&test_dev->config_mutex);
0957 val = config;
0958 mutex_unlock(&test_dev->config_mutex);
0959
0960 return snprintf(buf, PAGE_SIZE, "%d\n", val);
0961 }
0962
0963 static ssize_t test_dev_config_show_uint(struct kmod_test_device *test_dev,
0964 char *buf,
0965 unsigned int config)
0966 {
0967 unsigned int val;
0968
0969 mutex_lock(&test_dev->config_mutex);
0970 val = config;
0971 mutex_unlock(&test_dev->config_mutex);
0972
0973 return snprintf(buf, PAGE_SIZE, "%u\n", val);
0974 }
0975
0976 static ssize_t test_result_store(struct device *dev,
0977 struct device_attribute *attr,
0978 const char *buf, size_t count)
0979 {
0980 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
0981 struct test_config *config = &test_dev->config;
0982
0983 return test_dev_config_update_int(test_dev, buf, count,
0984 &config->test_result);
0985 }
0986
0987 static ssize_t config_num_threads_store(struct device *dev,
0988 struct device_attribute *attr,
0989 const char *buf, size_t count)
0990 {
0991 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
0992 struct test_config *config = &test_dev->config;
0993
0994 return test_dev_config_update_uint_sync(test_dev, buf, count,
0995 &config->num_threads,
0996 kmod_config_sync_info);
0997 }
0998
0999 static ssize_t config_num_threads_show(struct device *dev,
1000 struct device_attribute *attr,
1001 char *buf)
1002 {
1003 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
1004 struct test_config *config = &test_dev->config;
1005
1006 return test_dev_config_show_int(test_dev, buf, config->num_threads);
1007 }
1008 static DEVICE_ATTR_RW(config_num_threads);
1009
1010 static ssize_t config_test_case_store(struct device *dev,
1011 struct device_attribute *attr,
1012 const char *buf, size_t count)
1013 {
1014 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
1015 struct test_config *config = &test_dev->config;
1016
1017 return test_dev_config_update_uint_range(test_dev, buf, count,
1018 &config->test_case,
1019 __TEST_KMOD_INVALID + 1,
1020 __TEST_KMOD_MAX - 1);
1021 }
1022
1023 static ssize_t config_test_case_show(struct device *dev,
1024 struct device_attribute *attr,
1025 char *buf)
1026 {
1027 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
1028 struct test_config *config = &test_dev->config;
1029
1030 return test_dev_config_show_uint(test_dev, buf, config->test_case);
1031 }
1032 static DEVICE_ATTR_RW(config_test_case);
1033
1034 static ssize_t test_result_show(struct device *dev,
1035 struct device_attribute *attr,
1036 char *buf)
1037 {
1038 struct kmod_test_device *test_dev = dev_to_test_dev(dev);
1039 struct test_config *config = &test_dev->config;
1040
1041 return test_dev_config_show_int(test_dev, buf, config->test_result);
1042 }
1043 static DEVICE_ATTR_RW(test_result);
1044
1045 #define TEST_KMOD_DEV_ATTR(name) &dev_attr_##name.attr
1046
1047 static struct attribute *test_dev_attrs[] = {
1048 TEST_KMOD_DEV_ATTR(trigger_config),
1049 TEST_KMOD_DEV_ATTR(config),
1050 TEST_KMOD_DEV_ATTR(reset),
1051
1052 TEST_KMOD_DEV_ATTR(config_test_driver),
1053 TEST_KMOD_DEV_ATTR(config_test_fs),
1054 TEST_KMOD_DEV_ATTR(config_num_threads),
1055 TEST_KMOD_DEV_ATTR(config_test_case),
1056 TEST_KMOD_DEV_ATTR(test_result),
1057
1058 NULL,
1059 };
1060
1061 ATTRIBUTE_GROUPS(test_dev);
1062
1063 static int kmod_config_init(struct kmod_test_device *test_dev)
1064 {
1065 int ret;
1066
1067 mutex_lock(&test_dev->config_mutex);
1068 ret = __kmod_config_init(test_dev);
1069 mutex_unlock(&test_dev->config_mutex);
1070
1071 return ret;
1072 }
1073
1074 static struct kmod_test_device *alloc_test_dev_kmod(int idx)
1075 {
1076 int ret;
1077 struct kmod_test_device *test_dev;
1078 struct miscdevice *misc_dev;
1079
1080 test_dev = vzalloc(sizeof(struct kmod_test_device));
1081 if (!test_dev)
1082 goto err_out;
1083
1084 mutex_init(&test_dev->config_mutex);
1085 mutex_init(&test_dev->trigger_mutex);
1086 mutex_init(&test_dev->thread_mutex);
1087
1088 init_completion(&test_dev->kthreads_done);
1089
1090 ret = kmod_config_init(test_dev);
1091 if (ret < 0) {
1092 pr_err("Cannot alloc kmod_config_init()\n");
1093 goto err_out_free;
1094 }
1095
1096 test_dev->dev_idx = idx;
1097 misc_dev = &test_dev->misc_dev;
1098
1099 misc_dev->minor = MISC_DYNAMIC_MINOR;
1100 misc_dev->name = kasprintf(GFP_KERNEL, "test_kmod%d", idx);
1101 if (!misc_dev->name) {
1102 pr_err("Cannot alloc misc_dev->name\n");
1103 goto err_out_free_config;
1104 }
1105 misc_dev->groups = test_dev_groups;
1106
1107 return test_dev;
1108
1109 err_out_free_config:
1110 free_test_dev_info(test_dev);
1111 kmod_config_free(test_dev);
1112 err_out_free:
1113 vfree(test_dev);
1114 test_dev = NULL;
1115 err_out:
1116 return NULL;
1117 }
1118
1119 static void free_test_dev_kmod(struct kmod_test_device *test_dev)
1120 {
1121 if (test_dev) {
1122 kfree_const(test_dev->misc_dev.name);
1123 test_dev->misc_dev.name = NULL;
1124 free_test_dev_info(test_dev);
1125 kmod_config_free(test_dev);
1126 vfree(test_dev);
1127 test_dev = NULL;
1128 }
1129 }
1130
1131 static struct kmod_test_device *register_test_dev_kmod(void)
1132 {
1133 struct kmod_test_device *test_dev = NULL;
1134 int ret;
1135
1136 mutex_lock(®_dev_mutex);
1137
1138
1139 if (num_test_devs + 1 == INT_MAX) {
1140 pr_err("reached limit of number of test devices\n");
1141 goto out;
1142 }
1143
1144 test_dev = alloc_test_dev_kmod(num_test_devs);
1145 if (!test_dev)
1146 goto out;
1147
1148 ret = misc_register(&test_dev->misc_dev);
1149 if (ret) {
1150 pr_err("could not register misc device: %d\n", ret);
1151 free_test_dev_kmod(test_dev);
1152 test_dev = NULL;
1153 goto out;
1154 }
1155
1156 test_dev->dev = test_dev->misc_dev.this_device;
1157 list_add_tail(&test_dev->list, ®_test_devs);
1158 dev_info(test_dev->dev, "interface ready\n");
1159
1160 num_test_devs++;
1161
1162 out:
1163 mutex_unlock(®_dev_mutex);
1164
1165 return test_dev;
1166
1167 }
1168
1169 static int __init test_kmod_init(void)
1170 {
1171 struct kmod_test_device *test_dev;
1172 int ret;
1173
1174 test_dev = register_test_dev_kmod();
1175 if (!test_dev) {
1176 pr_err("Cannot add first test kmod device\n");
1177 return -ENODEV;
1178 }
1179
1180
1181
1182
1183
1184
1185
1186
1187 if (force_init_test) {
1188 ret = trigger_config_run_type(test_dev,
1189 TEST_KMOD_DRIVER, "tun");
1190 if (WARN_ON(ret))
1191 return ret;
1192 ret = trigger_config_run_type(test_dev,
1193 TEST_KMOD_FS_TYPE, "btrfs");
1194 if (WARN_ON(ret))
1195 return ret;
1196 }
1197
1198 return 0;
1199 }
1200 late_initcall(test_kmod_init);
1201
1202 static
1203 void unregister_test_dev_kmod(struct kmod_test_device *test_dev)
1204 {
1205 mutex_lock(&test_dev->trigger_mutex);
1206 mutex_lock(&test_dev->config_mutex);
1207
1208 test_dev_kmod_stop_tests(test_dev);
1209
1210 dev_info(test_dev->dev, "removing interface\n");
1211 misc_deregister(&test_dev->misc_dev);
1212
1213 mutex_unlock(&test_dev->config_mutex);
1214 mutex_unlock(&test_dev->trigger_mutex);
1215
1216 free_test_dev_kmod(test_dev);
1217 }
1218
1219 static void __exit test_kmod_exit(void)
1220 {
1221 struct kmod_test_device *test_dev, *tmp;
1222
1223 mutex_lock(®_dev_mutex);
1224 list_for_each_entry_safe(test_dev, tmp, ®_test_devs, list) {
1225 list_del(&test_dev->list);
1226 unregister_test_dev_kmod(test_dev);
1227 }
1228 mutex_unlock(®_dev_mutex);
1229 }
1230 module_exit(test_kmod_exit);
1231
1232 MODULE_AUTHOR("Luis R. Rodriguez <mcgrof@kernel.org>");
1233 MODULE_LICENSE("GPL");