Skip to content

Commit

Permalink
Add Dynamic Fsync Control v1.5
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Reioux <reioux@gmail.com>
Signed-off-by: Javier Sayago <admin@lonasdigital.com>
  • Loading branch information
faux123 authored and javilonas committed Jun 4, 2015
1 parent 4a4075b commit 98bc598
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 0 deletions.
1 change: 1 addition & 0 deletions arch/arm/configs/apq8084_sec_defconfig
Expand Up @@ -872,6 +872,7 @@ CONFIG_DEFAULT_TCP_CONG="westwood"
CONFIG_FORCE_FAST_CHARGE=y
CONFIG_SIMPLE_GPU_ALGORITHM=y
CONFIG_CPU_VOLTAGE_CONTROL=y
CONFIG_DYNAMIC_FSYNC=y

#
# IO Schedulers
Expand Down
6 changes: 6 additions & 0 deletions fs/Kconfig
Expand Up @@ -284,4 +284,10 @@ endif # NETWORK_FILESYSTEMS
source "fs/nls/Kconfig"
source "fs/dlm/Kconfig"

config DYNAMIC_FSYNC
bool "dynamic file sync control"
default n
help
An experimental file sync control using Android's power suspend / late resume drivers

endmenu
2 changes: 2 additions & 0 deletions fs/Makefile
Expand Up @@ -132,3 +132,5 @@ obj-$(CONFIG_EFIVAR_FS) += efivarfs/

# Patched by YAFFS
obj-$(CONFIG_YAFFS_FS) += yaffs2/

obj-$(CONFIG_DYNAMIC_FSYNC) += dyn_sync_cntrl.o
208 changes: 208 additions & 0 deletions fs/dyn_sync_cntrl.c
@@ -0,0 +1,208 @@
/*
* Author: Paul Reioux aka Faux123 <reioux@gmail.com>
*
* Copyright 2013 Paul Reioux
* Copyright 2012 Paul Reioux
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/

#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/powersuspend.h>
#include <linux/mutex.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/writeback.h>

#define DYN_FSYNC_VERSION_MAJOR 1
#define DYN_FSYNC_VERSION_MINOR 5

/*
* fsync_mutex protects dyn_fsync_active during power suspend / late resume
* transitions
*/
static DEFINE_MUTEX(fsync_mutex);

bool power_suspend_active __read_mostly = false;
bool dyn_fsync_active __read_mostly = false;

static ssize_t dyn_fsync_active_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", (dyn_fsync_active ? 1 : 0));
}

static ssize_t dyn_fsync_active_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
{
unsigned int data;

if(sscanf(buf, "%u\n", &data) == 1) {
if (data == 1) {
pr_info("%s: dynamic fsync enabled\n", __FUNCTION__);
dyn_fsync_active = true;
}
else if (data == 0) {
pr_info("%s: dyanamic fsync disabled\n", __FUNCTION__);
dyn_fsync_active = false;
}
else
pr_info("%s: bad value: %u\n", __FUNCTION__, data);
} else
pr_info("%s: unknown input!\n", __FUNCTION__);

return count;
}

static ssize_t dyn_fsync_version_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "version: %u.%u by faux123\n",
DYN_FSYNC_VERSION_MAJOR,
DYN_FSYNC_VERSION_MINOR);
}

static ssize_t dyn_fsync_powersuspend_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "power suspend active: %u\n", power_suspend_active);
}

static struct kobj_attribute dyn_fsync_active_attribute =
__ATTR(Dyn_fsync_active, 0666,
dyn_fsync_active_show,
dyn_fsync_active_store);

static struct kobj_attribute dyn_fsync_version_attribute =
__ATTR(Dyn_fsync_version, 0444, dyn_fsync_version_show, NULL);

static struct kobj_attribute dyn_fsync_powersuspend_attribute =
__ATTR(Dyn_fsync_earlysuspend, 0444, dyn_fsync_powersuspend_show, NULL);

static struct attribute *dyn_fsync_active_attrs[] =
{
&dyn_fsync_active_attribute.attr,
&dyn_fsync_version_attribute.attr,
&dyn_fsync_powersuspend_attribute.attr,
NULL,
};

static struct attribute_group dyn_fsync_active_attr_group =
{
.attrs = dyn_fsync_active_attrs,
};

static struct kobject *dyn_fsync_kobj;

extern void sync_filesystems(int wait);
static void dyn_fsync_force_flush(void)
{

}

static void dyn_fsync_suspend(struct power_suspend *p)
{
mutex_lock(&fsync_mutex);
if (dyn_fsync_active) {
power_suspend_active = true;
dyn_fsync_force_flush();
}
mutex_unlock(&fsync_mutex);
}

static void dyn_fsync_resume(struct power_suspend *p)
{
mutex_lock(&fsync_mutex);
power_suspend_active = false;
mutex_unlock(&fsync_mutex);
}

static struct power_suspend dyn_fsync_power_suspend_handler =
{
.suspend = dyn_fsync_suspend,
.resume = dyn_fsync_resume,
};

static int dyn_fsync_panic_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
power_suspend_active = true;
dyn_fsync_force_flush();
//pr_warn("dyn fsync: panic: force flush!\n");

return NOTIFY_DONE;
}

static struct notifier_block dyn_fsync_panic_block = {
.notifier_call = dyn_fsync_panic_event,
.priority = INT_MAX,
};

static int dyn_fsync_notify_sys(struct notifier_block *this, unsigned long code,
void *unused)
{
if (code == SYS_DOWN || code == SYS_HALT) {
power_suspend_active = true;
dyn_fsync_force_flush();
//pr_warn("dyn fsync: reboot: force flush!\n");
}
return NOTIFY_DONE;
}

static struct notifier_block dyn_fsync_notifier = {
.notifier_call = dyn_fsync_notify_sys,
};

static int dyn_fsync_init(void)
{
int sysfs_result;

register_power_suspend(&dyn_fsync_power_suspend_handler);
register_reboot_notifier(&dyn_fsync_notifier);
atomic_notifier_chain_register(&panic_notifier_list,
&dyn_fsync_panic_block);

dyn_fsync_kobj = kobject_create_and_add("dyn_fsync", kernel_kobj);
if (!dyn_fsync_kobj) {
pr_err("%s dyn_fsync kobject create failed!\n", __FUNCTION__);
return -ENOMEM;
}

sysfs_result = sysfs_create_group(dyn_fsync_kobj,
&dyn_fsync_active_attr_group);

if (sysfs_result) {
pr_info("%s dyn_fsync sysfs create failed!\n", __FUNCTION__);
kobject_put(dyn_fsync_kobj);
}
return sysfs_result;
}

static void dyn_fsync_exit(void)
{
unregister_power_suspend(&dyn_fsync_power_suspend_handler);
unregister_reboot_notifier(&dyn_fsync_notifier);
atomic_notifier_chain_unregister(&panic_notifier_list,
&dyn_fsync_panic_block);

if (dyn_fsync_kobj != NULL)
kobject_put(dyn_fsync_kobj);
}

module_init(dyn_fsync_init);
module_exit(dyn_fsync_exit);

MODULE_AUTHOR("Paul Reioux <reioux@gmail.com>");
MODULE_DESCRIPTION("dynamic fsync - automatic fs sync optimizaition using"
"Power_suspend driver!");
MODULE_LICENSE("GPL v2");

0 comments on commit 98bc598

Please sign in to comment.