From: Vyacheslav Cherkashin Date: Thu, 8 Oct 2015 13:38:44 +0000 (+0300) Subject: [FEATURE] swap_td_raw implement X-Git-Tag: submit/tizen/20151123.110932~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d7d13479f8765183101b6df0e3869b508c077ee6;p=kernel%2Fswap-modules.git [FEATURE] swap_td_raw implement Change-Id: I96939a7710d3ddac969b26c50b0fd507f5b54b47 Signed-off-by: Vyacheslav Cherkashin --- diff --git a/kprobe/Kbuild b/kprobe/Kbuild index 640899f..c952322 100644 --- a/kprobe/Kbuild +++ b/kprobe/Kbuild @@ -3,7 +3,8 @@ EXTRA_CFLAGS := $(extra_cflags) obj-m := swap_kprobe.o swap_kprobe-y := swap_kprobes.o \ swap_kprobes_deps.o \ - swap_slots.o + swap_slots.o \ + swap_td_raw.o ### ARM swap_kprobe-$(CONFIG_ARM) += arch/arm/swap-asm/swap_kprobes.o \ diff --git a/kprobe/swap_kprobes.c b/kprobe/swap_kprobes.c index 7f11152..20a2e35 100644 --- a/kprobe/swap_kprobes.c +++ b/kprobe/swap_kprobes.c @@ -47,6 +47,7 @@ #include #include "swap_slots.h" +#include "swap_td_raw.h" #include "swap_kdebug.h" #include "swap_kprobes.h" #include "swap_kprobes_deps.h" @@ -1240,23 +1241,32 @@ static int init_kprobes(void) init_sm(); atomic_set(&kprobe_count, 0); - ret = swap_arch_init_kprobes(); + ret = swap_td_raw_init(); if (ret) return ret; + ret = swap_arch_init_kprobes(); + if (ret) + goto td_raw_uninit; + ret = swap_register_kprobe(&put_task_kp); - if (ret) { - swap_arch_exit_kprobes(); - return ret; - } + if (ret) + goto arch_kp_exit; return 0; + +arch_kp_exit: + swap_arch_exit_kprobes(); +td_raw_uninit: + swap_td_raw_uninit(); + return ret; } static void exit_kprobes(void) { swap_unregister_kprobe(&put_task_kp); swap_arch_exit_kprobes(); + swap_td_raw_uninit(); exit_sm(); } diff --git a/kprobe/swap_td_raw.c b/kprobe/swap_td_raw.c new file mode 100644 index 0000000..9985d06 --- /dev/null +++ b/kprobe/swap_td_raw.c @@ -0,0 +1,116 @@ +/* + * 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. + * + * Copyright (C) Samsung Electronics, 2015 + * + * 2014 Vasiliy Ulyanov + * 2015 Vyacheslav Cherkashin + * + */ + + +#include +#include +#include "swap_td_raw.h" + + +#define TD_OFFSET 1 /* skip STACK_END_MAGIC */ +#define TD_PREFIX "[SWAP_TD_RAW] " +#define TD_STACK_USAGE_MAX 0x200 +#define TD_CHUNK_MIN sizeof(long) + + +static DEFINE_MUTEX(mutex_stack_usage); +static unsigned long stack_usage = 0; +static LIST_HEAD(td_raw_list); + + +/* + * take small area from stack + * + * 0x00 +--------------------------+ + * | STACK_END_MAGIC | + * +--------------------------+ <-- bottom of stack; + * | | + * | stack | + * | | + * 0xff + * + */ + +static void *bottom_of_stack(struct task_struct *task) +{ + return (void *)(end_of_stack(task) + TD_OFFSET); +} + +int swap_td_raw_reg(struct td_raw *raw, unsigned long size) +{ + int ret = 0; + + size = (size / TD_CHUNK_MIN + !!(size % TD_CHUNK_MIN)) * TD_CHUNK_MIN; + + mutex_lock(&mutex_stack_usage); + if (stack_usage + size > TD_STACK_USAGE_MAX) { + pr_warn(TD_PREFIX "free stack ended: usage=%ld size=%ld\n", + stack_usage, size); + ret = -ENOMEM; + goto unlock; + } + + raw->offset = stack_usage; + + INIT_LIST_HEAD(&raw->list); + list_add(&raw->list, &td_raw_list); + + stack_usage += size; + +unlock: + mutex_unlock(&mutex_stack_usage); + return ret; +} +EXPORT_SYMBOL_GPL(swap_td_raw_reg); + +void swap_td_raw_unreg(struct td_raw *raw) +{ + mutex_lock(&mutex_stack_usage); + + list_del(&raw->list); + if (list_empty(&td_raw_list)) + stack_usage = 0; + + mutex_unlock(&mutex_stack_usage); +} +EXPORT_SYMBOL_GPL(swap_td_raw_unreg); + +void *swap_td_raw(struct td_raw *raw, struct task_struct *task) +{ + return bottom_of_stack(task) + raw->offset; +} +EXPORT_SYMBOL_GPL(swap_td_raw); + +int swap_td_raw_init(void) +{ + WARN_ON(stack_usage); + + stack_usage = 0; + + return 0; +} + +void swap_td_raw_uninit(void) +{ + WARN_ON(!list_empty(&td_raw_list)); + WARN_ON(stack_usage); +} diff --git a/kprobe/swap_td_raw.h b/kprobe/swap_td_raw.h new file mode 100644 index 0000000..079b153 --- /dev/null +++ b/kprobe/swap_td_raw.h @@ -0,0 +1,46 @@ +/* + * 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. + * + * Copyright (C) Samsung Electronics, 2015 + * + * 2014 Vasiliy Ulyanov + * 2015 Vyacheslav Cherkashin + * + */ + + +#ifndef _SWAP_TD_RAW_H +#define _SWAP_TD_RAW_H + + +#include + + +struct td_raw { + struct list_head list; + unsigned long offset; +}; + + +int swap_td_raw_reg(struct td_raw *raw, unsigned long size); +void swap_td_raw_unreg(struct td_raw *raw); + +void *swap_td_raw(struct td_raw *raw, struct task_struct *task); + +int swap_td_raw_init(void); +void swap_td_raw_uninit(void); + + +#endif /* _SWAP_TD_RAW_H */