0001
0002
0003
0004 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0005
0006 #include <linux/module.h>
0007 #include <linux/kernel.h>
0008 #include <linux/sched.h>
0009 #include <linux/workqueue.h>
0010 #include <linux/delay.h>
0011
0012
0013 static bool block_transition;
0014 module_param(block_transition, bool, 0644);
0015 MODULE_PARM_DESC(block_transition, "block_transition (default=false)");
0016
0017 static void busymod_work_func(struct work_struct *work);
0018 static DECLARE_WORK(work, busymod_work_func);
0019 static DECLARE_COMPLETION(busymod_work_started);
0020
0021 static void busymod_work_func(struct work_struct *work)
0022 {
0023 pr_info("%s enter\n", __func__);
0024 complete(&busymod_work_started);
0025
0026 while (READ_ONCE(block_transition)) {
0027
0028
0029
0030
0031 msleep(20);
0032 }
0033
0034 pr_info("%s exit\n", __func__);
0035 }
0036
0037 static int test_klp_callbacks_busy_init(void)
0038 {
0039 pr_info("%s\n", __func__);
0040 schedule_work(&work);
0041
0042
0043
0044
0045
0046 wait_for_completion(&busymod_work_started);
0047
0048 if (!block_transition) {
0049
0050
0051
0052
0053 flush_work(&work);
0054 }
0055
0056 return 0;
0057 }
0058
0059 static void test_klp_callbacks_busy_exit(void)
0060 {
0061 WRITE_ONCE(block_transition, false);
0062 flush_work(&work);
0063 pr_info("%s\n", __func__);
0064 }
0065
0066 module_init(test_klp_callbacks_busy_init);
0067 module_exit(test_klp_callbacks_busy_exit);
0068 MODULE_LICENSE("GPL");
0069 MODULE_AUTHOR("Joe Lawrence <joe.lawrence@redhat.com>");
0070 MODULE_DESCRIPTION("Livepatch test: busy target module");