driver: add synchronize for msg_handler 93/140493/3
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 25 Jul 2017 06:35:04 +0000 (09:35 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 27 Jul 2017 11:42:39 +0000 (14:42 +0300)
Change-Id: Id06134af184fe576a349a9e35e8348830701bc54
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
driver/device_driver.c
driver/driver_to_msg.h
parser/swap_msg_parser.c

index 04e1adb..e473cb8 100644 (file)
@@ -114,8 +114,6 @@ typedef int(*splice_grow_spd_p_t)(const struct pipe_inode_info *pipe,
 static splice_to_pipe_p_t splice_to_pipe_p;
 static splice_grow_spd_p_t splice_grow_spd_p;
 
-static msg_handler_t msg_handler;
-
 /* Device numbers */
 static dev_t swap_device_no;
 
@@ -157,6 +155,53 @@ static void exit_w_wake_up(void)
 }
 
 
+/*
+ * Driver message handler
+ */
+static DECLARE_RWSEM(dmsg_handler_sem);
+static struct driver_msg_handler *dmsg_handler;
+
+static int driver_msg_handler_call(void __user *data)
+{
+       int ret;
+
+       down_read(&dmsg_handler_sem);
+       if (dmsg_handler) {
+               ret = dmsg_handler->handler(data);
+       } else {
+               print_warn("dmsg_handler() is not register\n");
+               ret = -EINVAL;
+       }
+       up_read(&dmsg_handler_sem);
+
+       return ret;
+}
+
+/**
+ * @brief Register message handler.
+ *
+ * @param msg_handler Pointer to message handler.
+ * @return Void.
+ */
+void driver_msg_handler_set(struct driver_msg_handler *msg_handler)
+{
+       down_write(&dmsg_handler_sem);
+       /* unregister dmsg_handler */
+       if (dmsg_handler) {
+               module_put(dmsg_handler->mod);
+               dmsg_handler = NULL;
+       }
+
+       /* register dmsg_handler */
+       if (msg_handler) {
+               BUG_ON(!try_module_get(msg_handler->mod));
+               dmsg_handler = msg_handler;
+       }
+       up_write(&dmsg_handler_sem);
+}
+EXPORT_SYMBOL_GPL(driver_msg_handler_set);
+
+
 /**
  * @brief We need this realization of splice_shrink_spd() because its desing
  * frequently changes in custom kernels.
@@ -385,12 +430,7 @@ static long swap_device_ioctl(struct file *filp, unsigned int cmd,
        }
        case SWAP_DRIVER_MSG:
        {
-               if (msg_handler) {
-                       result = msg_handler((void __user *)arg);
-               } else {
-                       print_warn("msg_handler() is not register\n");
-                       result = -EINVAL;
-               }
+               result = driver_msg_handler_call((void __user *)arg);
                break;
        }
        case SWAP_DRIVER_WAKE_UP:
@@ -522,15 +562,3 @@ void swap_device_wake_up_process(void)
                schedule_work(&w_wake_up);
        }
 }
-
-/**
- * @brief Registers received message handler.
- *
- * @param mh Pointer to message handler.
- * @return Void.
- */
-void set_msg_handler(msg_handler_t mh)
-{
-       msg_handler = mh;
-}
-EXPORT_SYMBOL_GPL(set_msg_handler);
index 73fc434..f252155 100644 (file)
 #ifndef __SWAP_DRIVER_DRIVER_TO_MSG__
 #define __SWAP_DRIVER_DRIVER_TO_MSG__
 
-/** Defines type for message handler's pointer. */
-typedef int (*msg_handler_t)(void __user *data);
+#include <linux/compiler.h>
+
+struct module;
+
+struct driver_msg_handler {
+       struct module *mod;
+       int (*handler)(void __user *data);
+};
 
 /* Set the message handler */
-void set_msg_handler(msg_handler_t mh);
+void driver_msg_handler_set(struct driver_msg_handler *msg_handler);
 
 #endif /* __SWAP_DRIVER_DRIVER_TO_MSG__ */
index a8b4c28..49d079a 100644 (file)
@@ -149,15 +149,20 @@ uninit:
        return ret;
 }
 
+static struct driver_msg_handler dmsg_handler = {
+       .mod = THIS_MODULE,
+       .handler = msg_handler,
+};
+
 static int reg_msg_handler(void)
 {
-       set_msg_handler(msg_handler);
+       driver_msg_handler_set(&dmsg_handler);
        return 0;
 }
 
 static void unreg_msg_handler(void)
 {
-       set_msg_handler(NULL);
+       driver_msg_handler_set(NULL);
        app_list_unreg_all();
 }