[IMPROVE] Buffer: implement initialization with structure
[kernel/swap-modules.git] / driver / driver_to_buffer.c
1 /*
2  *  SWAP driver
3  *  modules/driver/driver_to_buffer.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/string.h>
26 #include <linux/slab.h>
27 #include <linux/splice.h>
28 #include <asm/uaccess.h>
29 #include <linux/spinlock.h>
30 #include <linux/mm.h>
31
32 #include <buffer/swap_buffer_module.h>
33 #include <buffer/swap_buffer_errors.h>
34 #include <buffer/buffer_description.h>
35 #include <writer/swap_writer_module.h>
36
37 #include "driver_defs.h"
38 #include "swap_driver_errors.h"
39 #include "device_driver_to_driver_to_buffer.h"
40
41 /* Current busy buffer */
42 static struct swap_subbuffer *busy_buffer = NULL;
43
44 /* Buffers count ready to be read */
45 static int buffers_to_read = 0;
46
47 /* Pages count in one subbuffer */
48 static int pages_per_buffer = 0;
49
50 /* Used to sync changes of the buffers_to_read var */
51 static spinlock_t buf_to_read;
52
53
54 static inline void init_buffers_to_read(void)
55 {
56         spin_lock_init(&buf_to_read);
57         buffers_to_read = 0;
58 }
59
60 static inline void inc_buffers_to_read(void)
61 {
62         unsigned long flags;
63
64         spin_lock_irqsave(&buf_to_read, flags);
65         buffers_to_read++;
66         spin_unlock_irqrestore(&buf_to_read, flags);
67 }
68
69 static inline void dec_buffers_to_read(void)
70 {
71         unsigned long flags;
72
73         spin_lock_irqsave(&buf_to_read, flags);
74         buffers_to_read--;
75         spin_unlock_irqrestore(&buf_to_read, flags);
76 }
77
78 static inline void set_buffers_to_read(int count)
79 {
80         unsigned long flags;
81
82         spin_lock_irqsave(&buf_to_read, flags);
83         buffers_to_read = count;
84         spin_unlock_irqrestore(&buf_to_read, flags);
85 }
86
87 static inline int something_to_read(void)
88 {
89         unsigned long flags;
90         int result;
91
92         spin_lock_irqsave(&buf_to_read, flags);
93         result = buffers_to_read;
94         spin_unlock_irqrestore(&buf_to_read, flags);
95
96         return result;
97 }
98
99 /* TODO Get subbuffer for reading */
100 static size_t driver_to_buffer_get(void)
101 {
102         int result;
103
104         /* If there is no readable buffers, return error */
105         result = swap_buffer_get(&busy_buffer);
106         if (result == -E_SB_NO_READABLE_BUFFERS) {
107                 busy_buffer = NULL;
108                 return -E_SD_NO_DATA_TO_READ;
109         } else if (result < 0) {
110                 print_err("swap_buffer_get unhandle error %d\n", result);
111                 return -E_SD_BUFFER_ERROR;
112         }
113
114         return busy_buffer->full_buffer_part;
115 }
116
117 /* TODO Release subbuffer */
118 static int driver_to_buffer_release(void)
119 {
120         int result;
121
122         if (!busy_buffer)
123                 return -E_SD_NO_BUSY_SUBBUFFER;
124
125         result = swap_buffer_release(&busy_buffer);
126         if (result == -E_SB_NO_SUBBUFFER_IN_BUSY) {
127                 return -E_SD_WRONG_SUBBUFFER_PTR;
128         } else if (result < 0) {
129                 print_err("swap_buffer_release unhandle error %d\n", result);
130                 return -E_SD_BUFFER_ERROR;
131         }
132
133         busy_buffer = NULL;
134
135         return E_SD_SUCCESS;
136 }
137
138 /* Buffers callback function */
139 int driver_to_buffer_callback(void)
140 {
141         /* Increment buffers_to_read counter */
142         inc_buffers_to_read();
143         swap_device_wake_up_process();
144
145         return E_SD_SUCCESS;
146 }
147
148 /* Read buffers */
149 ssize_t driver_to_buffer_read(char __user *buf, size_t count)
150 {
151         size_t bytes_to_copy;
152         size_t bytes_to_read = 0;
153         int page_counter = 0;
154
155         /* Reading from swap_device means reading only current busy_buffer. So, if
156          * there is no busy_buffer, we don't get next to read, we just read nothing.
157          * In this case, or if there is nothing to read from busy_buffer - return
158          * -E_SD_NO_DATA_TO_READ. It should be correctly handled in device_driver */
159         if (!busy_buffer || !busy_buffer->full_buffer_part)
160                 return -E_SD_NO_DATA_TO_READ;
161
162         /* Bytes count that we're going to copy to user buffer is equal to user
163          * buffer size or to subbuffer readable size whichever is less */
164         bytes_to_copy = (count > busy_buffer->full_buffer_part) ?
165                     busy_buffer->full_buffer_part : count;
166
167         /* Copy data from each page to buffer */
168         while(bytes_to_copy > 0) {
169                 /* Get size that should be copied from current page */
170                 size_t read_from_this_page = (bytes_to_copy > PAGE_SIZE) ? PAGE_SIZE
171                                                                  : bytes_to_copy;
172
173                 /* Copy and add size to copied bytes count */
174
175                 // TODO Check with more than one page
176                 bytes_to_read += read_from_this_page -
177                          copy_to_user(buf, page_address(busy_buffer->data_buffer) +
178                                                         (sizeof(struct page*) *
179                                                          page_counter),
180                                                         read_from_this_page);
181                 bytes_to_copy -= read_from_this_page;
182                 page_counter++;
183         }
184
185         return bytes_to_read;
186 }
187
188 /* Flush swap_buffer */
189 int driver_to_buffer_flush(void)
190 {
191         unsigned int flushed;
192
193         flushed = swap_buffer_flush();
194         set_buffers_to_read(flushed);
195         swap_device_wake_up_process();
196
197         return E_SD_SUCCESS;
198 }
199
200 /* Fills spd structure */
201 int driver_to_buffer_fill_spd(struct splice_pipe_desc *spd)
202 {
203         size_t data_to_splice = busy_buffer->full_buffer_part;
204         struct page **pages = spd->pages;
205         struct partial_page *partial = spd->partial;
206
207         while (data_to_splice) {
208                 size_t read_from_current_page = min(data_to_splice, (size_t)PAGE_SIZE);
209
210                 pages[spd->nr_pages] = alloc_page(GFP_KERNEL);
211                 if (!pages[spd->nr_pages]) {
212                         print_err("Cannot alloc page for splice\n");
213                         return -ENOMEM;
214                 }
215
216                 /* FIXME: maybe there is more efficient way */
217                 memcpy(page_address(pages[spd->nr_pages]),
218                page_address(&busy_buffer->data_buffer[spd->nr_pages]),
219                read_from_current_page);
220
221                 /* Always beginning of the page */
222                 partial[spd->nr_pages].offset = 0;
223                 partial[spd->nr_pages].len = read_from_current_page;
224
225                 /* Private is not used */
226                 partial[spd->nr_pages].private = 0;
227
228                 spd->nr_pages++;
229                 data_to_splice -= read_from_current_page;
230
231                 /* TODO: add check for pipe->buffers exceeding */
232                 /* if (spd->nr_pages == pipe->buffers) { */
233                 /*      break; */
234                 /* } */
235         }
236         return 0;
237 }
238
239 /* Check for subbuffers ready to be read */
240 int driver_to_buffer_buffer_to_read(void)
241 {
242         return busy_buffer ? 1 : 0;
243 }
244
245 /* Set buffers size and count */
246 int driver_to_buffer_initialize(size_t size, unsigned int count)
247 {
248         int result;
249         struct buffer_init_t buf_init = {
250                 .subbuffer_size = size,
251                 .nr_subbuffers = count,
252                 .subbuffer_full_cb = driver_to_buffer_callback,
253                 .lower_threshold = 20,
254                 .low_mem_cb = NULL,
255                 .top_threshold = 80,
256                 .enough_mem_cb = NULL,
257         };
258
259         if (size == 0 && count == 0) {
260                 return -E_SD_WRONG_ARGS;
261         }
262
263         result = swap_buffer_init(&buf_init);
264         if (result == -E_SB_NO_MEM_QUEUE_BUSY
265                 || result == -E_SB_NO_MEM_BUFFER_STRUCT) {
266                 return -E_SD_NO_MEMORY;
267         }
268
269         // TODO Race condition: buffer can be used in other thread till we're in
270         // this func
271         /* Initialize driver_to_buffer variables */
272         pages_per_buffer = result;
273         busy_buffer = NULL;
274         init_buffers_to_read();
275
276         return E_SD_SUCCESS;
277 }
278
279 /* Uninitialize buffer */
280 int driver_to_buffer_uninitialize(void)
281 {
282         int result;
283
284         /* Release occupied buffer */
285         if (busy_buffer) {
286                 result = driver_to_buffer_release();
287                 // TODO Maybe release anyway
288                 if (result < 0) {
289                         return result;
290                 }
291                 busy_buffer = NULL;
292         }
293
294         result = swap_buffer_uninit();
295         if (result == -E_SB_UNRELEASED_BUFFERS) {
296                 print_err("Can't uninit buffer! There are busy subbuffers!\n");
297                 result = -E_SD_BUFFER_ERROR;
298         } else if (result < 0) {
299                 print_err("swap_buffer_uninit error %d\n", result);
300                 result = -E_SD_BUFFER_ERROR;
301         } else {
302                 result = E_SD_SUCCESS;
303         }
304
305         /* Reinit driver_to_buffer vars */
306         init_buffers_to_read();
307         pages_per_buffer = 0;
308
309         return result;
310 }
311
312 /* Get next buffer to read */
313 int driver_to_buffer_next_buffer_to_read(void)
314 {
315         int result;
316
317         /* If there is busy_buffer first release it */
318         if (busy_buffer) {
319                 result = driver_to_buffer_release();
320                 if (result)
321                         return result;
322         }
323
324         /* If there is no buffers to read, return E_SD_NO_DATA_TO_READ.
325          * SHOULD BE POSITIVE, cause there is no real error. */
326         if (!something_to_read()) {
327                 return E_SD_NO_DATA_TO_READ;
328         }
329
330         /* Get next buffer to read */
331         result = driver_to_buffer_get();
332         if (result < 0) {
333                 print_err("buffer_to_reads > 0, but there are no buffers to read\n");
334                 return result;
335         }
336
337         /* Decrement buffers_to_read counter */
338         dec_buffers_to_read();
339
340         return E_SD_SUCCESS;
341 }
342