From: Vyacheslav Cherkashin Date: Tue, 25 Jul 2017 06:35:04 +0000 (+0300) Subject: driver: add synchronize for msg_handler X-Git-Tag: accepted/tizen/4.0/unified/20170913.154114~22 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8a40440a68c57a5898190e4ea2f3700d7ba8ece7;p=platform%2Fkernel%2Fswap-modules.git driver: add synchronize for msg_handler Change-Id: Id06134af184fe576a349a9e35e8348830701bc54 Signed-off-by: Vyacheslav Cherkashin --- diff --git a/driver/device_driver.c b/driver/device_driver.c index 04e1adb..e473cb8 100644 --- a/driver/device_driver.c +++ b/driver/device_driver.c @@ -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); diff --git a/driver/driver_to_msg.h b/driver/driver_to_msg.h index 73fc434..f252155 100644 --- a/driver/driver_to_msg.h +++ b/driver/driver_to_msg.h @@ -30,10 +30,16 @@ #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 + +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__ */ diff --git a/parser/swap_msg_parser.c b/parser/swap_msg_parser.c index a8b4c28..49d079a 100644 --- a/parser/swap_msg_parser.c +++ b/parser/swap_msg_parser.c @@ -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(); }