[FIX] Kprobe: remove aggrigated probe from list
[kernel/swap-modules.git] / driver / device_driver.c
1 /*
2  *  SWAP device driver
3  *  modules/driver/device_driver.c
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Copyright (C) Samsung Electronics, 2013
20  *
21  * 2013  Alexander Aksenov <a.aksenov@samsung.com>: SWAP device driver implement
22  *
23  */
24
25 #include <linux/types.h>
26 #include <linux/fs.h>
27 #include <linux/cdev.h>
28 #include <linux/err.h>
29 #include <linux/device.h>
30 #include <linux/ioctl.h>
31 #include <linux/slab.h>
32 #include <linux/mm.h>
33 #include <linux/splice.h>
34 #include <linux/sched.h>
35 #include <linux/module.h>
36 #include <linux/wait.h>
37 #include <linux/workqueue.h>
38 #include <asm/uaccess.h>
39
40 #include <ksyms/ksyms.h>
41
42 #include "device_driver.h"
43 #include "swap_driver_errors.h"
44 #include "driver_to_buffer.h"
45 #include "swap_ioctl.h"
46 #include "driver_defs.h"
47 #include "device_driver_to_driver_to_buffer.h"
48 #include "driver_to_buffer.h"
49 #include "driver_to_msg.h"
50
51 #define SWAP_DEVICE_NAME "swap_device"
52
53 #define MAXIMUM_SUBBUFFER_SIZE (64 * 1024)
54
55 /* swap_device driver routines */
56 static int swap_device_open(struct inode *inode, struct file *filp);
57 static int swap_device_release(struct inode *inode, struct file *file);
58 static ssize_t swap_device_read(struct file *filp, char __user *buf,
59                                                                 size_t count, loff_t *f_pos);
60 static long swap_device_ioctl(struct file *filp, unsigned int cmd,
61                                                          unsigned long arg);
62 static ssize_t swap_device_splice_read(struct file *filp, loff_t *ppos,
63                                                                            struct pipe_inode_info *pipe, size_t len,
64                                                                            unsigned int flags);
65
66 /* File operations structure */
67 const struct file_operations swap_device_fops = {
68         .owner = THIS_MODULE,
69         .read = swap_device_read,
70         .open = swap_device_open,
71         .release = swap_device_release,
72         .unlocked_ioctl = swap_device_ioctl,
73         .splice_read = swap_device_splice_read,
74 };
75
76 /* Typedefs for splice_* funcs. Prototypes are for linux-3.8.6 */
77 typedef ssize_t(*splice_to_pipe_p_t)(struct pipe_inode_info *pipe,
78                                          struct splice_pipe_desc *spd);
79 typedef int(*splice_grow_spd_p_t)(const struct pipe_inode_info *pipe,
80                                         struct splice_pipe_desc *spd);
81
82 static splice_to_pipe_p_t splice_to_pipe_p = NULL;
83 static splice_grow_spd_p_t splice_grow_spd_p = NULL;
84
85 static msg_handler_t msg_handler = NULL;
86
87 /* Device numbers */
88 static dev_t swap_device_no = 0;
89
90 /* Device cdev struct */
91 static struct cdev *swap_device_cdev = NULL;
92
93 /* Device class struct */
94 static struct class *swap_device_class = NULL;
95
96 /* Device device struct */
97 static struct device *swap_device_device = NULL;
98
99 /* Reading tasks queue */
100 static DECLARE_WAIT_QUEUE_HEAD(swap_device_wait);
101
102
103 static atomic_t flag_wake_up = ATOMIC_INIT(0);
104
105 static void __bottom_wake_up(void)
106 {
107         if (waitqueue_active(&swap_device_wait))
108                 wake_up_interruptible(&swap_device_wait);
109 }
110
111 static void bottom_wake_up(struct work_struct *work)
112 {
113         if (atomic_read(&flag_wake_up)) {
114                 atomic_set(&flag_wake_up, 0);
115                 __bottom_wake_up();
116         }
117 }
118
119 static DECLARE_WORK(w_wake_up, bottom_wake_up);
120
121 static void exit_w_wake_up(void)
122 {
123         flush_scheduled_work();
124         __bottom_wake_up();
125 }
126
127
128 /* We need this realization of splice_shrink_spd() because of the its desing
129  * frequent changes that I have encountered in custom kernels */
130 void swap_device_splice_shrink_spd(struct pipe_inode_info *pipe,
131                                    struct splice_pipe_desc *spd)
132 {
133         if (pipe->buffers <= PIPE_DEF_BUFFERS)
134                 return;
135
136         kfree(spd->pages);
137         kfree(spd->partial);
138 }
139
140
141 /* Register device TODO Think of permanent major */
142 int swap_device_init(void)
143 {
144         int result;
145
146         /* Allocating device major and minor nums for swap_device */
147         result = alloc_chrdev_region(&swap_device_no, 0, 1, SWAP_DEVICE_NAME);
148         if (result < 0) {
149                 print_crit("Major number allocation has failed\n");
150                 result = -E_SD_ALLOC_CHRDEV_FAIL;
151                 goto init_fail;
152         }
153
154         /* Creating device class. Using IS_ERR, because class_create returns ERR_PTR
155          * on error. */
156         swap_device_class = class_create(THIS_MODULE, SWAP_DEVICE_NAME);
157         if (IS_ERR(swap_device_class)) {
158                 print_crit("Class creation has failed\n");
159                 result = -E_SD_CLASS_CREATE_FAIL;
160                 goto init_fail;
161         }
162
163         /* Cdev allocation */
164         swap_device_cdev = cdev_alloc();
165         if (!swap_device_cdev) {
166                 print_crit("Cdev structure allocation has failed\n");
167                 result = -E_SD_CDEV_ALLOC_FAIL;
168                 goto init_fail;
169         }
170
171         /* Cdev intialization and setting file operations */
172         cdev_init(swap_device_cdev, &swap_device_fops);
173
174         /* Adding cdev to system */
175         result = cdev_add(swap_device_cdev, swap_device_no, 1);
176         if (result < 0) {
177                 print_crit("Device adding has failed\n");
178                 result = -E_SD_CDEV_ADD_FAIL;
179                 goto init_fail;
180         }
181
182         /* Create device struct */
183         swap_device_device = device_create(swap_device_class, NULL, swap_device_no,
184                                                                            "%s", SWAP_DEVICE_NAME);
185         if (IS_ERR(swap_device_device)) {
186                 print_crit("Device struct creating has failed\n");
187                 result = -E_SD_DEVICE_CREATE_FAIL;
188                 goto init_fail;
189         }
190
191         /* Find splice_* funcs addresses */
192         splice_to_pipe_p = (splice_to_pipe_p_t)swap_ksyms("splice_to_pipe");
193         if (!splice_to_pipe_p) {
194                 print_err("splice_to_pipe() not found!\n");
195                 result = -E_SD_NO_SPLICE_FUNCS;
196                 goto init_fail;
197         }
198
199         splice_grow_spd_p = (splice_grow_spd_p_t)swap_ksyms("splice_grow_spd");
200         if (!splice_grow_spd_p) {
201                 print_err("splice_grow_spd() not found!\n");
202                 result = -E_SD_NO_SPLICE_FUNCS;
203                 goto init_fail;
204         }
205
206         return 0;
207
208 init_fail:
209         if (swap_device_cdev) {
210                 cdev_del(swap_device_cdev);
211         }
212         if (swap_device_class) {
213                 class_destroy(swap_device_class);
214         }
215         if (swap_device_no) {
216                 unregister_chrdev_region(swap_device_no, 1);
217         }
218         return result;
219 }
220
221 /* Unregister device TODO Check wether driver is registered */
222 void swap_device_exit(void)
223 {
224         exit_w_wake_up();
225
226         splice_to_pipe_p = NULL;
227         splice_grow_spd_p = NULL;
228
229         device_destroy(swap_device_class, swap_device_no);
230         cdev_del(swap_device_cdev);
231         class_destroy(swap_device_class);
232         unregister_chrdev_region(swap_device_no, 1);
233 }
234
235 static int swap_device_open(struct inode *inode, struct file *filp)
236 {
237         // TODO MOD_INC_USE_COUNT
238         return 0;
239 }
240
241 static int swap_device_release(struct inode *inode, struct file *filp)
242 {
243         // TODO MOD_DEC_USE_COUNT
244         return 0;
245 }
246
247 static ssize_t swap_device_read(struct file *filp, char __user *buf,
248                                                                 size_t count, loff_t *f_pos)
249 {
250         /* Wait queue item that consists current task. It is used to be added in
251          * swap_device_wait queue if there is no data to be read. */
252         DEFINE_WAIT(wait);
253         int result;
254
255         //TODO : Think about spin_locks to prevent reading race condition.
256         while((result = driver_to_buffer_next_buffer_to_read()) != E_SD_SUCCESS) {
257
258                 /* Add process to the swap_device_wait queue and set the current task
259                  * state TASK_INTERRUPTIBLE. If there is any data to be read, then the
260                  * current task is removed from the swap_device_wait queue and its state
261                  * is changed to this. */
262                 prepare_to_wait(&swap_device_wait, &wait, TASK_INTERRUPTIBLE);
263
264                 if (result < 0) {
265                         result = 0;
266                         goto swap_device_read_error;
267                 } else if (result == E_SD_NO_DATA_TO_READ) {
268                         /* Yes, E_SD_NO_DATA_TO_READ should be positive, cause it's not
269                          * really an error */
270                         if (filp->f_flags & O_NONBLOCK) {
271                                 result = -EAGAIN;
272                                 goto swap_device_read_error;
273                         }
274                         if (signal_pending(current)) {
275                                 result = -ERESTARTSYS;
276                                 goto swap_device_read_error;
277                         }
278                         schedule();
279                         finish_wait(&swap_device_wait, &wait);
280                 }
281         }
282
283         result = driver_to_buffer_read(buf, count);
284         /* If there is an error - return 0 */
285         if (result < 0)
286                 result = 0;
287
288
289         return result;
290
291 swap_device_read_error:
292         finish_wait(&swap_device_wait, &wait);
293
294         return result;
295 }
296
297 static long swap_device_ioctl(struct file *filp, unsigned int cmd,
298                                                          unsigned long arg)
299 {
300         int result;
301
302         switch(cmd) {
303                 case SWAP_DRIVER_BUFFER_INITIALIZE:
304                 {
305                         struct buffer_initialize initialize_struct;
306
307                         result = copy_from_user(&initialize_struct, (void*)arg,
308                                                                         sizeof(struct buffer_initialize));
309                         if (result) {
310                                 break;
311                         }
312
313                         if (initialize_struct.size > MAXIMUM_SUBBUFFER_SIZE) {
314                                 print_err("Wrong subbuffer size\n");
315                                 result = -E_SD_WRONG_ARGS;
316                                 break;
317                         }
318
319                         result = driver_to_buffer_initialize(initialize_struct.size,
320                                                                                                  initialize_struct.count);
321                         if (result < 0) {
322                                 print_err("Buffer initialization failed %d\n", result);
323                                 break;
324                         }
325                         result = E_SD_SUCCESS;
326
327                         break;
328                 }
329                 case SWAP_DRIVER_BUFFER_UNINITIALIZE:
330                 {
331                         result = driver_to_buffer_uninitialize();
332                         if (result < 0)
333                                 print_err("Buffer uninitialization failed %d\n", result);
334                         break;
335                 }
336                 case SWAP_DRIVER_NEXT_BUFFER_TO_READ:
337                 {
338                         /* Use this carefully */
339                         result = driver_to_buffer_next_buffer_to_read();
340                         if (result == E_SD_NO_DATA_TO_READ) {
341                                 /* TODO Do what we usually do when there are no subbuffers to
342                                  * read (make daemon sleep ?) */
343                         }
344                         break;
345                 }
346                 case SWAP_DRIVER_FLUSH_BUFFER:
347                 {
348                         result = driver_to_buffer_flush();
349                         break;
350                 }
351                 case SWAP_DRIVER_MSG:
352                 {
353                         if (msg_handler) {
354                                 result = msg_handler((void __user *)arg);
355                         } else {
356                                 print_warn("msg_handler() is not register\n");
357                                 result = -EINVAL;
358                         }
359                         break;
360                 }
361                 case SWAP_DRIVER_WAKE_UP:
362                 {
363                         swap_device_wake_up_process();
364                         result = E_SD_SUCCESS;
365                         break;
366                 }
367                 default:
368                         print_warn("Unknown command %d\n", cmd);
369                         result = -EINVAL;
370                         break;
371
372         }
373         return result;
374 }
375
376 static void swap_device_pipe_buf_release(struct pipe_inode_info *inode,
377                                                                                  struct pipe_buffer *pipe)
378 {
379         __free_page(pipe->page);
380 }
381
382 static void swap_device_page_release(struct splice_pipe_desc *spd,
383                                                                          unsigned int i)
384 {
385         __free_page(spd->pages[i]);
386 }
387
388 static const struct pipe_buf_operations swap_device_pipe_buf_ops = {
389         .can_merge = 0,
390         .map = generic_pipe_buf_map,
391         .unmap = generic_pipe_buf_unmap,
392         .confirm = generic_pipe_buf_confirm,
393         .release = swap_device_pipe_buf_release,
394         .steal = generic_pipe_buf_steal,
395         .get = generic_pipe_buf_get
396 };
397
398 static ssize_t swap_device_splice_read(struct file *filp, loff_t *ppos,
399                                                                            struct pipe_inode_info *pipe,
400                                                                            size_t len, unsigned int flags)
401 {
402         /* Wait queue item that consists current task. It is used to be added in
403          * swap_device_wait queue if there is no data to be read. */
404         DEFINE_WAIT(wait);
405
406         int result;
407         struct page *pages[PIPE_DEF_BUFFERS];
408         struct partial_page partial[PIPE_DEF_BUFFERS];
409         struct splice_pipe_desc spd = {
410                 .pages = pages,
411                 .partial = partial,
412 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 5))
413                 .nr_pages_max = PIPE_DEF_BUFFERS,
414 #endif
415                 .nr_pages = 0,
416                 .flags = flags,
417                 .ops = &swap_device_pipe_buf_ops,
418                 .spd_release = swap_device_page_release,
419         };
420
421         /* Get next buffer to read */
422         //TODO : Think about spin_locks to prevent reading race condition.
423         while((result = driver_to_buffer_next_buffer_to_read()) != E_SD_SUCCESS) {
424
425                 /* Add process to the swap_device_wait queue and set the current task
426                  * state TASK_INTERRUPTIBLE. If there is any data to be read, then the
427                  * current task is removed from the swap_device_wait queue and its state
428                  * is changed. */
429                 prepare_to_wait(&swap_device_wait, &wait, TASK_INTERRUPTIBLE);
430                 if (result < 0) {
431                         print_err("driver_to_buffer_next_buffer_to_read error %d\n", result);
432                         //TODO Error return to OS
433                         result = 0;
434                         goto swap_device_splice_read_error;
435                 } else if (result == E_SD_NO_DATA_TO_READ) {
436                         if (filp->f_flags & O_NONBLOCK) {
437                                 result = -EAGAIN;
438                                 goto swap_device_splice_read_error;
439                         }
440                         if (signal_pending(current)) {
441                                 result = -ERESTARTSYS;
442                                 goto swap_device_splice_read_error;
443                         }
444                         schedule();
445                         finish_wait(&swap_device_wait, &wait);
446                 }
447         }
448
449         if (splice_grow_spd_p(pipe, &spd)) {
450                 result = -ENOMEM;
451                 goto swap_device_splice_read_out;
452         }
453
454         result = driver_to_buffer_fill_spd(&spd);
455         if (result != 0) {
456                 print_err("Cannot fill spd for splice\n");
457                 goto swap_device_shrink_spd;
458         }
459
460         result = splice_to_pipe_p(pipe, &spd);
461
462 swap_device_shrink_spd:
463         swap_device_splice_shrink_spd(pipe, &spd);
464
465 swap_device_splice_read_out:
466         return result;
467
468 swap_device_splice_read_error:
469         finish_wait(&swap_device_wait, &wait);
470
471         return result;
472 }
473
474 void swap_device_wake_up_process(void)
475 {
476         if (atomic_read(&flag_wake_up) == 0) {
477                 atomic_set(&flag_wake_up, 1);
478                 schedule_work(&w_wake_up);
479         }
480 }
481
482 void set_msg_handler(msg_handler_t mh)
483 {
484         msg_handler = mh;
485 }
486 EXPORT_SYMBOL_GPL(set_msg_handler);