--- /dev/null
+# insmod left.ko
+```shell
+
+[ +0.000447] init: left job scheduled
+[ +0.001711] LEFT ADDR: ffffffffc0e075c0
+[ +0.000003] LEFT: left message
+[ +2.042100] LEFT ADDR: ffffffffc0e075c0
+[ +0.000018] LEFT: left message
+[ +2.047996] LEFT ADDR: ffffffffc0e075c0
+[ +0.000021] LEFT: left message
+
+```
+
+# insmod right.ko
+```shell
+
+[ +1.315626] RIGHT: init
+[ +0.000003] (RIGHT)LEFT ADDR: ffffffffc0e075c0
+[ +0.000002] (RIGHT)LEFT MESSAGE: left message
+[ +0.000001] RIGHT: wrote new message
+[ +0.732281] LEFT ADDR: ffffffffc0e075c0
+[ +0.000005] LEFT: new message from right
+[ +2.048020] LEFT ADDR: ffffffffc0e075c0
+[ +0.000005] LEFT: new message from right
+
+
+```
+
+# rmmod right
+```shell
+
+[ +2.047800] LEFT ADDR: ffffffffc0e075c0
+[ +0.000004] LEFT: new message from right
+[ +0.734667] exit: right done
+[ +1.313375] LEFT ADDR: ffffffffc0e075c0
+[ +0.000008] LEFT: new message from right
+
+```
+
+# rmmod left
+```shell
+[ +1.525553] exit: left exiting, wait for job completion...
+[ +0.522363] LEFT: job exit
+[ +0.000028] exit: left exiting, wait done
+[ +0.000005] exit: left done
+
+```
\ No newline at end of file
--- /dev/null
+obj-m := left.o
+obj-m += right.o
+
+all:
+ make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
+clean:
+ make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
\ No newline at end of file
--- /dev/null
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+
+typedef struct left_messsage_shared {
+ char* message;
+ struct mutex lock;
+} left_messsage_shared;
+
+int left_condition = 1;
+static DECLARE_WAIT_QUEUE_HEAD(left_wait);
+struct work_struct left_job;
+
+left_messsage_shared* lms = NULL;
+
+void left_job_handler(struct work_struct* w){
+ while(left_condition){
+ if(lms != NULL){
+ mutex_lock(&lms->lock);
+ printk("LEFT ADDR: %px\n", (void*)&lms);
+ if(lms->message != NULL){
+ printk("LEFT: %s\n", lms->message);
+ }
+ mutex_unlock(&lms->lock);
+ }
+ msleep(2000);
+ }
+ printk("LEFT: job exit\n");
+ left_condition = 2;
+ wake_up_interruptible(&left_wait);
+}
+
+left_messsage_shared** get_left_message_address(void){
+ return &lms;
+}
+
+EXPORT_SYMBOL_GPL(get_left_message_address);
+
+static int __init left_init(void){
+ lms = (left_messsage_shared*)kzalloc(sizeof(left_messsage_shared), GFP_KERNEL);
+ if(lms == NULL){
+ printk("failed to allocate left message shared\n");
+ return -ENOMEM;
+ }
+ lms->message = (char*)kzalloc(1024, GFP_KERNEL);
+ if(lms->message == NULL){
+ printk("failed to allocate left message valud\n");
+ kfree(lms);
+ return -ENOMEM;
+ }
+ strcpy(lms->message, "left message");
+ mutex_init(&lms->lock);
+ INIT_WORK(&left_job, left_job_handler);
+ schedule_work(&left_job);
+ printk("init: left job scheduled\n");
+ return 0;
+}
+
+static void __exit left_exit(void){
+
+ printk("exit: left exiting, wait for job completion...\n");
+ left_condition = 0;
+ wait_event_interruptible(left_wait, left_condition == 2);
+ printk("exit: left exiting, wait done\n");
+ if(lms != NULL){
+ mutex_destroy(&lms->lock);
+ kfree(lms->message);
+ kfree(lms);
+ }
+ printk("exit: left done\n");
+}
+
+module_init(left_init);
+module_exit(left_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("seantywork");
\ No newline at end of file
--- /dev/null
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mutex.h>
+
+typedef struct left_messsage_shared {
+ char* message;
+ struct mutex lock;
+} left_messsage_shared;
+
+extern left_messsage_shared** get_left_message_address(void);
+
+static int __init right_init(void){
+ printk("RIGHT: init\n");
+ left_messsage_shared** lms = get_left_message_address();
+ printk("(RIGHT)LEFT ADDR: %px\n", (void*)lms);
+ mutex_lock(&(*lms)->lock);
+ printk("(RIGHT)LEFT MESSAGE: %s\n",(*lms)->message);
+ strcpy((*lms)->message, "new message from right");
+ printk("RIGHT: wrote new message\n");
+ mutex_unlock(&(*lms)->lock);
+ return 0;
+}
+
+static void __exit right_exit(void){
+ printk("exit: right done\n");
+}
+
+module_init(right_init);
+module_exit(right_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("seantywork");
\ No newline at end of file