lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Fri, 14 Dec 2012 16:30:22 +0000
From:	"Tu, Xiaobing" <xiaobing.tu@...el.com>
To:	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	"greg@...ah.com" <greg@...ah.com>,
	"swetland@...gle.com" <swetland@...gle.com>
CC:	"Zhang, Di" <di.zhang@...el.com>,
	"Zhang, Yanmin" <yanmin.zhang@...el.com>
Subject: Subject: [PATCH] [lmk]  improve ANR produce rate caused by high io
 wait on android,create a thread for lowmem killer instead of usingkswapd

Subject: [PATCH] [lmk] create a thread for low mem killer instead of using kswapd

Currently low mem killer is registered as a shrinker and will be
invoked by kswapd. Since low mem killer and kswapd has different
criteria to invoke to work -- kswap wakes up when watermark of some
certain order in zone is low, and low mem killer should do its job
when free memory is below the min free threshold. In the case that
the kswapd isn't waked up and lmk is, the killed process selected
by lmk will release memory so that the kswapd doesn't need to work
any more.So it is not appropriate to mix them together. A 20 minutes
average vmstat shows that the iowait/page fault has huge improvement.
In this way, it can reduce the chance of ANR due to high iowait.

orignal:
flt    wa
62.70 2.00

with patch
flt    wa
2.32  0.01

Signed-off-by: Zhang Di <di.zhang@...el.com>
Signed-off-by: xiaobing tu <xiaobing.tu@...el.com>
---
 drivers/staging/android/lowmemorykiller.c |   92 ++++++++++++++++++++++++++--
 1 files changed, 85 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 2d8d2b7..8f29fe8 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -36,6 +36,8 @@
 #include <linux/sched.h>
 #include <linux/profile.h>
 #include <linux/notifier.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
 
 static uint32_t lowmem_debug_level = 2;
 static int lowmem_adj[6] = {
@@ -68,17 +70,47 @@ static struct notifier_block task_nb = {
 	.notifier_call	= task_notify_func,
 };
 
+static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc);  
+
+int lmk_involk()  
+{  
+	int other_free = global_page_state(NR_FREE_PAGES);  
+	int other_file = global_page_state(NR_INACTIVE_FILE);  
+	int array_max_idx = ARRAY_SIZE(lowmem_adj)-2;  
+
+	if (lowmem_deathpending &&  
+		time_before_eq(jiffies, lowmem_deathpending_timeout))  
+ 		return 0;  
+
+	if (time_before_eq(jiffies, lowmem_timeout))  
+		return 0;  
+
+	if (other_free + other_file > lowmem_minfree[array_max_idx])  
+		return 0;  
+
+	lowmem_timeout = jiffies + HZ/2;  
+
+	return 1;  
+}
+
+void wakeup_lmkd();  
+
 static int
 task_notify_func(struct notifier_block *self, unsigned long val, void *data)
 {
 	struct task_struct *task = data;
-	if (task == lowmem_deathpending) {
+	struct shrink_control sc = {NULL, 1};  
+	if (task == lowmem_deathpending) {  
 		lowmem_deathpending = NULL;
-		task_handoff_unregister(&task_nb);
-	}
+		if (lmk_involk()) {  
+			wakeup_lmkd();  
+		}  
+	}  
 	return NOTIFY_OK;
 }
 
+
+
 static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 {
 	struct task_struct *p;
@@ -93,6 +125,8 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 	int other_free = global_page_state(NR_FREE_PAGES);
 	int other_file = global_page_state(NR_FILE_PAGES) -
 						global_page_state(NR_SHMEM);
+	int other_file_act = global_page_state(NR_ACTIVE_FILE);  
+	int other_anon = global_page_state(NR_ANON_PAGES);  
 
 	/*
 	 * If we already have a death outstanding, then
@@ -105,7 +139,8 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 	 */
 	if (lowmem_deathpending)
 		return 0;
-
+	lowmem_deathpending = NULL;
+	
 	if (lowmem_adj_size < array_size)
 		array_size = lowmem_adj_size;
 	if (lowmem_minfree_size < array_size)
@@ -146,7 +181,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 			continue;
 		}
 		oom_adj = sig->oom_adj;
-		if (oom_adj < min_adj) {
+		if (oom_adj < selected_oom_adj) {
 			task_unlock(p);
 			continue;
 		}
@@ -155,8 +190,6 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 		if (tasksize <= 0)
 			continue;
 		if (selected) {
-			if (oom_adj < selected_oom_adj)
-				continue;
 			if (oom_adj == selected_oom_adj &&
 			    tasksize <= selected_tasksize)
 				continue;
@@ -189,6 +222,51 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 	return rem;
 }
 
+wait_queue_head_t lmkd_wait;  
+
+static void lmkd_try_to_sleep()  
+{  
+	long remaining;  
+	DEFINE_WAIT(wait);  
+ 
+	prepare_to_wait(&lmkd_wait, &wait, TASK_INTERRUPTIBLE);  
+	schedule();  
+	finish_wait(&lmkd_wait, &wait);  
+}  
+ 
+struct task_struct *lmkd_task;  
+static int lmkd();  
+int lmkd_run(int nid)  
+{  
+	int ret = 0;  
+	if (lmkd_task)  
+		return ret;  
+	init_waitqueue_head(&lmkd_wait);  
+	lowmem_timeout = jiffies;  
+	lmkd_task = kthread_run(lmkd, NULL , "lmkd");  
+	if (IS_ERR(lmkd_task)) {  
+		printk("Failed to start lmkd\n");  
+		ret = -1;  
+	}  
+	return ret;  
+}  
+  
+static int lmkd()  
+{  
+	struct shrink_control sc = {NULL, 1};  
+	while (1) {  
+		lowmem_shrink(NULL, &sc);  
+		lmkd_try_to_sleep();  
+	}  
+}  
+
+void wakeup_lmkd()  
+{  
+	if (!waitqueue_active(&lmkd_wait))  
+		return;  
+	wake_up_interruptible(&lmkd_wait);  
+}  
+
 static struct shrinker lowmem_shrinker = {
 	.shrink = lowmem_shrink,
 	.seeks = DEFAULT_SEEKS * 16
-- 
1.7.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ