sync_unlock(&read_queue.queue_sync);
}
-/**
- * @brief Call add to read list and callback function from driver module.
- *
- * @param subbuffer Pointer to the subbuffer to add.
- * @return swap_buffer_callback result.
- */
-int add_to_read_list_with_callback(struct swap_subbuffer *subbuffer)
+static int add_to_read_list_with_callback(struct swap_subbuffer *subbuffer,
+ bool wakeup)
{
int result = 0;
add_to_read_list(subbuffer);
/* TODO Handle ret value */
- result = swap_buffer_callback(subbuffer);
+ result = swap_buffer_callback(subbuffer, wakeup);
return result;
}
* beginning of memory for writing should be stored.
* @return Found swap_subbuffer.
*/
-struct swap_subbuffer *get_from_write_list(size_t size, void **ptr_to_write)
+struct swap_subbuffer *get_from_write_list(size_t size, void **ptr_to_write,
+ bool wakeup)
{
struct swap_subbuffer *result = NULL;
callback_queue.start_ptr =
callback_queue.start_ptr->next_in_queue;
- add_to_read_list_with_callback(tmp_buffer);
+ add_to_read_list_with_callback(tmp_buffer, wakeup);
}
return result;
#ifndef __BUFFER_QUEUE_H__
#define __BUFFER_QUEUE_H__
+#include <linux/types.h>
#include "buffer_description.h"
int buffer_queue_allocation(size_t subbuffer_size,
void buffer_queue_free(void);
int buffer_queue_reset(void);
void buffer_queue_flush(void);
-struct swap_subbuffer *get_from_write_list(size_t size, void **ptr_to_write);
+struct swap_subbuffer *get_from_write_list(size_t size, void **ptr_to_write,
+ bool wakeup);
struct swap_subbuffer *get_from_read_list(void);
void add_to_write_list(struct swap_subbuffer *subbuffer);
void add_to_read_list(struct swap_subbuffer *subbuffer);
/**
* @brief Subbuffer callback type.
*/
-typedef int(*subbuffer_callback_type)(void);
+typedef int(*subbuffer_callback_type)(bool wakeup);
/* Callback that is called when full subbuffer appears */
static subbuffer_callback_type subbuffer_callback;
* @param size Size of a data for writing.
* @return Size of written data on success, negative error code otherwise.
*/
-ssize_t swap_buffer_write(void *data, size_t size)
+ssize_t swap_buffer_write(void *data, size_t size, bool wakeup)
{
int result = E_SB_SUCCESS;
struct swap_subbuffer *buffer_to_write = NULL;
swap_irq_disable(&flags);
/* Get next write buffer and occupying semaphore */
- buffer_to_write = get_from_write_list(size, &ptr_to_write);
+ buffer_to_write = get_from_write_list(size, &ptr_to_write, wakeup);
if (!buffer_to_write) {
swap_irq_enable(&flags);
return -E_SB_NO_WRITABLE_BUFFERS;
* @return -E_SB_NO_CALLBACK if no callback is registered or callbacks ret
* value otherwise.
*/
-int swap_buffer_callback(void *buffer)
+int swap_buffer_callback(void *buffer, bool wakeup)
{
int result;
if (!subbuffer_callback)
return -E_SB_NO_CALLBACK;
- result = subbuffer_callback();
+ result = subbuffer_callback(wakeup);
if (result < 0)
print_err("Callback error! Error code: %d\n", result);
struct buffer_init_t {
size_t subbuffer_size;
unsigned int nr_subbuffers;
- int (*subbuffer_full_cb)(void);
+ int (*subbuffer_full_cb)(bool wakeup);
unsigned char lower_threshold;
int (*low_mem_cb)(void);
/* SWAP Buffer write function. Pass it size of the data and pointer to the data.
* On success returns number of bytes written (>=0) or error code (<0)
* otherwise */
-ssize_t swap_buffer_write(void *data, size_t size);
+ssize_t swap_buffer_write(void *data, size_t size, bool wakeup);
/* SWAP Buffer get. Put subbuffer pointer to the variable *subbuffer.
* Return pages count in subbuffer. */
#ifndef __SWAP_BUFFER_TO_BUFFER_QUEUE_H__
#define __SWAP_BUFFER_TO_BUFFER_QUEUE_H__
-int swap_buffer_callback(void *buffer);
+#include <linux/types.h>
+
+int swap_buffer_callback(void *buffer, bool wakeup);
#endif /* __SWAP_BUFFER_TO_BUFFER_QUEUE_H__ */
return E_SD_SUCCESS;
}
-/**
- * @brief Buffers callback function
- *
- * @return 0
- */
-int driver_to_buffer_callback(void)
+static int driver_to_buffer_callback(bool wakeup)
{
/* Increment buffers_to_read counter */
inc_buffers_to_read();
- swap_device_wake_up_process();
+ if (wakeup)
+ swap_device_wake_up_process();
return E_SD_SUCCESS;
}
int driver_to_buffer_initialize(size_t size, unsigned int count);
int driver_to_buffer_uninitialize(void);
ssize_t driver_to_buffer_read(char __user *buf, size_t count);
-void driver_to_buffer_callback(void);
int driver_to_buffer_fill_spd(struct splice_pipe_desc *spd);
int driver_to_buffer_buffer_to_read(void);
int driver_to_buffer_next_buffer_to_read(void);
mcs->tid = task->pid;
mcs->cpu_num = smp_processor_id();
- swap_msg_flush(m, sizeof(*mcs));
+ swap_msg_flush_wakeupoff(m, sizeof(*mcs));
swap_msg_put(m);
}
}
EXPORT_SYMBOL_GPL(swap_msg_get);
-int swap_msg_flush(struct swap_msg *m, size_t size)
+static int __swap_msg_flush(struct swap_msg *m, size_t size, bool wakeup)
{
if (unlikely(size >= SWAP_MSG_PAYLOAD_SIZE))
return -ENOMEM;
m->len = size;
- if (swap_buffer_write(m, SWAP_MSG_PRIV_DATA + size) !=
+ if (swap_buffer_write(m, SWAP_MSG_PRIV_DATA + size, wakeup) !=
(SWAP_MSG_PRIV_DATA + size)) {
atomic_inc(&discarded);
return -EINVAL;
return 0;
}
+
+int swap_msg_flush(struct swap_msg *m, size_t size)
+{
+ return __swap_msg_flush(m, size, true);
+}
EXPORT_SYMBOL_GPL(swap_msg_flush);
+int swap_msg_flush_wakeupoff(struct swap_msg *m, size_t size)
+{
+ return __swap_msg_flush(m, size, false);
+}
+EXPORT_SYMBOL_GPL(swap_msg_flush_wakeupoff);
+
void swap_msg_put(struct swap_msg *m)
{
put_cpu();
m->seq_num = atomic_inc_return(&seq_num);
/* TODO: What should be returned?! When message was discarded. */
- if (swap_buffer_write(m, size) != size)
+ if (swap_buffer_write(m, size, true) != size)
atomic_inc(&discarded);
return size;
struct swap_msg *swap_msg_get(enum swap_msg_id id);
int swap_msg_flush(struct swap_msg *m, size_t size);
+int swap_msg_flush_wakeupoff(struct swap_msg *m, size_t size);
void swap_msg_put(struct swap_msg *m);
static inline void *swap_msg_payload(struct swap_msg *m)