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>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20111202011015.GA9724@localhost>
Date:	Fri, 2 Dec 2011 09:10:15 +0800
From:	Wu Fengguang <fengguang.wu@...el.com>
To:	Randy Dunlap <rdunlap@...otime.net>
Cc:	Stephen Rothwell <sfr@...b.auug.org.au>,
	"linux-next@...r.kernel.org" <linux-next@...r.kernel.org>,
	LKML <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH -next] exit: fix writeback build errors

On Fri, Dec 02, 2011 at 02:19:11AM +0800, Randy Dunlap wrote:
> From: Randy Dunlap <rdunlap@...otime.net>
> 
> Fix build errors:
> kernel/exit.c:1039:3: error: 'dirty_throttle_leaks' undeclared (first use in this function)
> kernel/exit.c:1039:3: warning: type defaults to 'int' in type name
> kernel/exit.c:1039:3: warning: initialization makes pointer from integer without a cast
> kernel/exit.c:1039:1: warning: type defaults to 'int' in declaration of 'pao_T__'
> kernel/exit.c:1039:1: warning: type defaults to 'int' in declaration of 'pao_T__'
> kernel/exit.c:1039:1: warning: type defaults to 'int' in declaration of 'pao_T__'
> kernel/exit.c:1039:1: warning: type defaults to 'int' in declaration of 'pao_T__'
> 
> Signed-off-by: Randy Dunlap <rdunlap@...otime.net>

Thanks! I merged this with the original patch, so as to make it
bisectable.

---
Subject: writeback: charge leaked page dirties to active tasks
Date: Tue Apr 05 13:21:19 CST 2011

It's a years long problem that a large number of short-lived dirtiers
(eg. gcc instances in a fast kernel build) may starve long-run dirtiers
(eg. dd) as well as pushing the dirty pages to the global hard limit.

The solution is to charge the pages dirtied by the exited gcc to the
other random dirtying tasks. It sounds not perfect, however should
behave good enough in practice, seeing as that throttled tasks aren't
actually running so those that are running are more likely to pick it up
and get throttled, therefore promoting an equal spread.

Randy: fix compile error: 'dirty_throttle_leaks' undeclared in exit.c

Acked-by: Peter Zijlstra <a.p.zijlstra@...llo.nl>
Signed-off-by: Randy Dunlap <rdunlap@...otime.net>
Signed-off-by: Wu Fengguang <fengguang.wu@...el.com>
---
 include/linux/writeback.h |    2 ++
 kernel/exit.c             |    3 +++
 mm/page-writeback.c       |   27 +++++++++++++++++++++++++++
 3 files changed, 32 insertions(+)

--- linux-next.orig/include/linux/writeback.h	2011-11-30 15:11:31.000000000 +0800
+++ linux-next/include/linux/writeback.h	2011-12-02 09:07:19.000000000 +0800
@@ -7,6 +7,8 @@
 #include <linux/sched.h>
 #include <linux/fs.h>
 
+DECLARE_PER_CPU(int, dirty_throttle_leaks);
+
 /*
  * The 1/4 region under the global dirty thresh is for smooth dirty throttling:
  *
--- linux-next.orig/mm/page-writeback.c	2011-11-30 15:11:39.000000000 +0800
+++ linux-next/mm/page-writeback.c	2011-12-02 09:07:19.000000000 +0800
@@ -1236,6 +1236,22 @@ void set_page_dirty_balance(struct page 
 
 static DEFINE_PER_CPU(int, bdp_ratelimits);
 
+/*
+ * Normal tasks are throttled by
+ *	loop {
+ *		dirty tsk->nr_dirtied_pause pages;
+ *		take a snap in balance_dirty_pages();
+ *	}
+ * However there is a worst case. If every task exit immediately when dirtied
+ * (tsk->nr_dirtied_pause - 1) pages, balance_dirty_pages() will never be
+ * called to throttle the page dirties. The solution is to save the not yet
+ * throttled page dirties in dirty_throttle_leaks on task exit and charge them
+ * randomly into the running tasks. This works well for the above worst case,
+ * as the new task will pick up and accumulate the old task's leaked dirty
+ * count and eventually get throttled.
+ */
+DEFINE_PER_CPU(int, dirty_throttle_leaks) = 0;
+
 /**
  * balance_dirty_pages_ratelimited_nr - balance dirty memory state
  * @mapping: address_space which was dirtied
@@ -1283,6 +1299,17 @@ void balance_dirty_pages_ratelimited_nr(
 			ratelimit = 0;
 		}
 	}
+	/*
+	 * Pick up the dirtied pages by the exited tasks. This avoids lots of
+	 * short-lived tasks (eg. gcc invocations in a kernel build) escaping
+	 * the dirty throttling and livelock other long-run dirtiers.
+	 */
+	p = &__get_cpu_var(dirty_throttle_leaks);
+	if (*p > 0 && current->nr_dirtied < ratelimit) {
+		nr_pages_dirtied = min(*p, ratelimit - current->nr_dirtied);
+		*p -= nr_pages_dirtied;
+		current->nr_dirtied += nr_pages_dirtied;
+	}
 	preempt_enable();
 
 	if (unlikely(current->nr_dirtied >= ratelimit))
--- linux-next.orig/kernel/exit.c	2011-11-30 15:11:31.000000000 +0800
+++ linux-next/kernel/exit.c	2011-12-02 09:08:12.000000000 +0800
@@ -51,6 +51,7 @@
 #include <trace/events/sched.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/oom.h>
+#include <linux/writeback.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -1037,6 +1038,8 @@ NORET_TYPE void do_exit(long code)
 	validate_creds_for_do_exit(tsk);
 
 	preempt_disable();
+	if (tsk->nr_dirtied)
+		__this_cpu_add(dirty_throttle_leaks, tsk->nr_dirtied);
 	exit_rcu();
 	/* causes final put_task_struct in finish_task_switch(). */
 	tsk->state = TASK_DEAD;
--
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