Add setup buffer via debugfs accepted/tizen/3.0/common/20161213.163408 accepted/tizen/3.0/mobile/20161213.091137 accepted/tizen/3.0/tv/20161213.091206 accepted/tizen/3.0/wearable/20161213.091225 accepted/tizen/common/20161210.162302 accepted/tizen/mobile/20161212.025617 accepted/tizen/tv/20161212.025635 accepted/tizen/wearable/20161212.025649 submit/tizen/20161209.134902 submit/tizen_3.0/20161209.134853
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 6 Dec 2016 15:16:18 +0000 (18:16 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Fri, 9 Dec 2016 12:26:32 +0000 (15:26 +0300)
Change-Id: I01c749ff0e920530e5bc1579acfd901177aa9f82
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
driver/Kbuild
driver/device_driver.c
driver/driver_debugfs.c [new file with mode: 0644]
driver/driver_debugfs.h [new file with mode: 0644]
driver/driver_to_buffer.c
driver/driver_to_buffer.h
driver/swap_driver_errors.h
driver/swap_driver_module.c

index b3e3030..51f30cc 100644 (file)
@@ -4,7 +4,8 @@ KBUILD_EXTRA_SYMBOLS = $(src)/../buffer/Module.symvers
 obj-m := swap_driver.o
 swap_driver-y := swap_driver_module.o \
                      device_driver.o \
-                     driver_to_buffer.o
+                     driver_to_buffer.o \
+                     driver_debugfs.o
 
 ifeq ($(CONFIG_CONNECTOR),y)
        swap_driver-y += us_interaction.o
index f06b0f1..a19ffbf 100644 (file)
@@ -58,9 +58,6 @@
 /** SWAP device name as it is in /dev/. */
 #define SWAP_DEVICE_NAME "swap_device"
 
-/** Maximum subbuffer size. Used for sanitization checks. */
-#define MAXIMUM_SUBBUFFER_SIZE (64 * 1024)
-
 /* swap_device driver routines */
 static ssize_t swap_device_read(struct file *filp, char __user *buf,
                                size_t count, loff_t *f_pos);
@@ -317,14 +314,21 @@ static long swap_device_ioctl(struct file *filp, unsigned int cmd,
                if (result)
                        break;
 
-               if (initialize_struct.size > MAXIMUM_SUBBUFFER_SIZE) {
-                       print_err("Wrong subbuffer size\n");
-                       result = -E_SD_WRONG_ARGS;
+               result = driver_to_buffer_set_size(initialize_struct.size);
+               if (result < 0) {
+                       print_err("Wrong subbuffer size=%zu\n",
+                                 initialize_struct.size);
+                       break;
+               }
+
+               result = driver_to_buffer_set_count(initialize_struct.count);
+               if (result < 0) {
+                       print_err("Wrong subbuffer count=%u\n",
+                                 initialize_struct.count);
                        break;
                }
 
-               result = driver_to_buffer_initialize(initialize_struct.size,
-                                                    initialize_struct.count);
+               result = driver_to_buffer_initialize();
                if (result < 0) {
                        print_err("Buffer initialization failed %d\n", result);
                        break;
diff --git a/driver/driver_debugfs.c b/driver/driver_debugfs.c
new file mode 100644 (file)
index 0000000..00d81a0
--- /dev/null
@@ -0,0 +1,156 @@
+/**
+ * @author Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ * @section LICENSE
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * @section COPYRIGHT
+ *
+ * Copyright (C) Samsung Electronics, 2016
+ *
+ * @section DESCRIPTION
+ *
+ * SWAP debugfs interface definition.
+ */
+
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/debugfs.h>
+#include <master/swap_debugfs.h>
+#include "driver_to_buffer.h"
+#include "swap_driver_errors.h"
+
+
+#define WRITER_DBG_PERMS (S_IRUSR | S_IWUSR) /* u+rw */
+
+
+static int buf_enabled_set(u64 val)
+{
+       int ret = -EINVAL;
+
+       switch (val) {
+       case 0:
+               ret = driver_to_buffer_uninitialize();
+               break;
+       case 1:
+               ret = driver_to_buffer_initialize();
+               break;
+       }
+
+       return ret;
+}
+
+static u64 buf_enabled_get(void)
+{
+       return driver_to_buffer_enabled();
+}
+
+static struct dfs_setget_64 dfs_enabled = {
+       .set = buf_enabled_set,
+       .get = buf_enabled_get,
+};
+
+static int subbuf_size_set(u64 val)
+{
+
+       if (driver_to_buffer_set_size(val) != E_SD_SUCCESS)
+               return -EINVAL;
+
+       return 0;
+}
+
+static u64 subbuf_size_get(void)
+{
+       return driver_to_buffer_get_size();
+}
+
+static struct dfs_setget_64 dfs_subbuf_size = {
+       .set = subbuf_size_set,
+       .get = subbuf_size_get,
+};
+
+static int subbuf_count_set(u64 val)
+{
+       if (driver_to_buffer_set_count(val) != E_SD_SUCCESS)
+               return -EINVAL;
+
+       return 0;
+}
+
+static u64 subbuf_count_get(void)
+{
+       return driver_to_buffer_get_count();
+}
+
+static struct dfs_setget_64 dfs_subbuf_count = {
+       .set = subbuf_count_set,
+       .get = subbuf_count_get,
+};
+
+
+struct dbgfs_data {
+       const char *name;
+       struct dfs_setget_64 *setget;
+};
+
+static struct dbgfs_data dbgfs[] = {
+       {
+               .name = "buffer_enabled",
+               .setget = &dfs_enabled,
+       }, {
+               .name = "subbuf_size",
+               .setget = &dfs_subbuf_size,
+       }, {
+               .name = "subbuf_conunt",
+               .setget = &dfs_subbuf_count,
+       }
+};
+
+
+static struct dentry *driver_dir;
+
+void driver_debugfs_uninit(void)
+{
+       debugfs_remove_recursive(driver_dir);
+       driver_dir = NULL;
+}
+
+int driver_debugfs_init(void)
+{
+       int i;
+       struct dentry *swap_dir, *dentry;
+
+       swap_dir = swap_debugfs_getdir();
+       if (swap_dir == NULL)
+               return -ENOENT;
+
+       driver_dir = debugfs_create_dir("driver", swap_dir);
+       if (driver_dir == NULL)
+               return -ENOMEM;
+
+       for (i = 0; i < ARRAY_SIZE(dbgfs); ++i) {
+               struct dbgfs_data *data = &dbgfs[i];
+               dentry = debugfs_create_setget_u64(data->name, WRITER_DBG_PERMS,
+                                                  driver_dir, data->setget);
+               if (!dentry)
+                       goto fail;
+       }
+
+       return 0;
+fail:
+       driver_debugfs_uninit();
+       return -ENOMEM;
+}
diff --git a/driver/driver_debugfs.h b/driver/driver_debugfs.h
new file mode 100644 (file)
index 0000000..5624d05
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * @author Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ * @section LICENSE
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * @section COPYRIGHT
+ *
+ * Copyright (C) Samsung Electronics, 2016
+ *
+ * @section DESCRIPTION
+ *
+ * SWAP debugfs interface definition.
+ */
+
+#ifndef DRIVER_DEBUGFS_H
+#define DRIVER_DEBUGFS_H
+
+
+int driver_debugfs_init(void);
+void driver_debugfs_uninit(void);
+
+#endif // DRIVER_DEBUGFS_H
index 3ddd19c..80683a4 100644 (file)
@@ -44,6 +44,9 @@
 #include "device_driver_to_driver_to_buffer.h"
 #include "app_manage.h"
 
+/** Maximum subbuffer size. Used for sanitization checks. */
+#define MAXIMUM_SUBBUFFER_SIZE (64 * 1024)
+
 /* Current busy buffer */
 static struct swap_subbuffer *busy_buffer;
 
@@ -272,6 +275,64 @@ int driver_to_buffer_buffer_to_read(void)
        return busy_buffer ? 1 : 0;
 }
 
+static size_t subbuf_size;
+static unsigned int subbuf_count;
+static bool buffer_enabled;
+static DEFINE_MUTEX(buffer_mtx);
+
+bool driver_to_buffer_enabled(void)
+{
+       return buffer_enabled;
+}
+
+enum _swap_driver_errors driver_to_buffer_set_size(size_t size)
+{
+       enum _swap_driver_errors ret = E_SD_SUCCESS;
+
+       if (!size || size > MAXIMUM_SUBBUFFER_SIZE)
+               return -E_SD_WRONG_ARGS;
+
+       mutex_lock(&buffer_mtx);
+       if (buffer_enabled) {
+               ret = -E_SD_BUFFER_ENABLED;
+               goto unlock;
+       }
+
+       subbuf_size = size;
+unlock:
+       mutex_unlock(&buffer_mtx);
+       return ret;
+}
+
+size_t driver_to_buffer_get_size(void)
+{
+       return subbuf_size;
+}
+
+enum _swap_driver_errors driver_to_buffer_set_count(unsigned int count)
+{
+       enum _swap_driver_errors ret = E_SD_SUCCESS;
+
+       if (!count)
+               return -E_SD_WRONG_ARGS;
+
+       mutex_lock(&buffer_mtx);
+       if (buffer_enabled) {
+               ret = -E_SD_BUFFER_ENABLED;
+               goto unlock;
+       }
+       subbuf_count = count;
+
+unlock:
+       mutex_unlock(&buffer_mtx);
+       return ret;
+}
+
+unsigned int driver_to_buffer_get_count(void)
+{
+       return subbuf_count;
+}
+
 /**
  * @brief Initializes SWAP buffer.
  *
@@ -279,12 +340,12 @@ int driver_to_buffer_buffer_to_read(void)
  * @param count Count of subbuffers.
  * @return 0 on success, negative error code on error.
  */
-int driver_to_buffer_initialize(size_t size, unsigned int count)
+int driver_to_buffer_initialize(void)
 {
-       int result;
+       enum _swap_driver_errors result;
        struct buffer_init_t buf_init = {
-               .subbuffer_size = size,
-               .nr_subbuffers = count,
+               .subbuffer_size = subbuf_size,
+               .nr_subbuffers = subbuf_count,
                .subbuffer_full_cb = driver_to_buffer_callback,
                .lower_threshold = 20,
                .low_mem_cb = app_manage_pause_apps,
@@ -292,13 +353,17 @@ int driver_to_buffer_initialize(size_t size, unsigned int count)
                .enough_mem_cb = app_manage_cont_apps,
        };
 
-       if (size == 0 && count == 0)
-               return -E_SD_WRONG_ARGS;
+       mutex_lock(&buffer_mtx);
+       if (buffer_enabled) {
+               result = -E_SD_BUFFER_ENABLED;
+               goto unlock;
+       }
 
        result = swap_buffer_init(&buf_init);
        if (result == -E_SB_NO_MEM_QUEUE_BUSY
                || result == -E_SB_NO_MEM_BUFFER_STRUCT) {
-               return -E_SD_NO_MEMORY;
+               result = -E_SD_NO_MEMORY;
+               goto unlock;
        }
 
        /* TODO Race condition: buffer can be used in other thread till */
@@ -307,8 +372,12 @@ int driver_to_buffer_initialize(size_t size, unsigned int count)
        pages_per_buffer = result;
        busy_buffer = NULL;
        init_buffers_to_read();
+       result = E_SD_SUCCESS;
+       buffer_enabled = true;
 
-       return E_SD_SUCCESS;
+unlock:
+       mutex_unlock(&buffer_mtx);
+       return result;
 }
 
 /**
@@ -320,12 +389,18 @@ int driver_to_buffer_uninitialize(void)
 {
        int result;
 
+       mutex_lock(&buffer_mtx);
+       if (!buffer_enabled) {
+               result = -E_SD_BUFFER_DISABLED;
+               goto unlock;
+       }
+
        /* Release occupied buffer */
        if (busy_buffer) {
                result = driver_to_buffer_release();
                /* TODO Maybe release anyway */
                if (result < 0)
-                       return result;
+                       goto unlock;
                busy_buffer = NULL;
        }
 
@@ -338,12 +413,15 @@ int driver_to_buffer_uninitialize(void)
                result = -E_SD_BUFFER_ERROR;
        } else {
                result = E_SD_SUCCESS;
+               buffer_enabled = false;
        }
 
        /* Reinit driver_to_buffer vars */
        init_buffers_to_read();
        pages_per_buffer = 0;
 
+unlock:
+       mutex_unlock(&buffer_mtx);
        return result;
 }
 
index e133ee1..465968f 100644 (file)
 #ifndef __SWAP_DRIVER_DRIVER_TO_BUFFER__
 #define __SWAP_DRIVER_DRIVER_TO_BUFFER__
 
-int driver_to_buffer_initialize(size_t size, unsigned int count);
+
+#include <linux/types.h>
+
+struct splice_pipe_desc;
+
+
+bool driver_to_buffer_enabled(void);
+
+enum _swap_driver_errors driver_to_buffer_set_size(size_t size);
+size_t driver_to_buffer_get_size(void);
+
+enum _swap_driver_errors driver_to_buffer_set_count(unsigned int count);
+unsigned int driver_to_buffer_get_count(void);
+
+int driver_to_buffer_initialize(void);
 int driver_to_buffer_uninitialize(void);
 ssize_t driver_to_buffer_read(char __user *buf, size_t count);
 int driver_to_buffer_fill_spd(struct splice_pipe_desc *spd);
index 75294a6..7c6fce2 100644 (file)
@@ -107,7 +107,15 @@ enum _swap_driver_errors {
        /**
         * @brief No daemon pid in us_interaction.
         */
-       E_SD_NO_DAEMON_PID = 17
+       E_SD_NO_DAEMON_PID = 17,
+       /**
+        * @brief Buffer already enabled
+        */
+       E_SD_BUFFER_ENABLED = 18,
+       /**
+        * @brief Buffer already disabled
+        */
+       E_SD_BUFFER_DISABLED = 19,
 };
 
 #endif /* __SWAP_DRIVER_ERRORS_H__ */
index 48c7016..dcb69bb 100644 (file)
@@ -32,6 +32,7 @@
 #include "driver_defs.h"
 #include "device_driver.h"
 #include "us_interaction.h"
+#include "driver_debugfs.h"
 
 static int fs_init(void)
 {
@@ -45,10 +46,16 @@ static int fs_init(void)
        if (ret)
                print_err("Cannot initialize netlink socket\n");
 
+       ret = driver_debugfs_init();
+       if (ret)
+               goto us_int_destroy;
+
        print_msg("Driver module initialized\n");
 
-       return 0;
+       return ret;
 
+us_int_destroy:
+       us_interaction_destroy();
 dev_init_fail:
        swap_device_exit();
 
@@ -57,6 +64,7 @@ dev_init_fail:
 
 static void fs_uninit(void)
 {
+       driver_debugfs_uninit();
        us_interaction_destroy();
        swap_device_exit();
        print_msg("Driver module uninitialized\n");