[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20101214154900.2d7a643c@suzukikp>
Date: Tue, 14 Dec 2010 15:49:00 +0530
From: "Suzuki K. Poulose" <suzuki@...ibm.com>
To: linux-kernel@...r.kernel.org
Cc: "Suzuki K. Poulose" <suzuki@...ibm.com>,
Jeremy Fitzhardinge <jeremy.fitzhardinge@...rix.com>,
Christoph Hellwig <hch@....de>,
Masami Hiramatsu <mhiramat@...hat.com>,
Ananth N Mavinakayanahalli <ananth@...ibm.com>,
Daisuke HATAYAMA <d.hatayama@...fujitsu.com>,
Andi Kleen <andi@...stfloor.org>,
Roland McGrath <roland@...hat.com>,
Amerigo Wang <amwang@...hat.com>,
Linus Torvalds <torvalds@...ux-foundation.org>,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@...fujitsu.com>,
KOSAKI Motohiro <kosaki.motohiro@...fujitsu.com>,
Oleg Nesterov <oleg@...hat.com>,
Andrew Morton <akpm@...ux-foundation.org>
Subject: [Patch 16/21] Wait for threads to freeze
The threads may not have entered the "refrigerator()" by the time we start
generating the NOTE sections, which can result in invalid register states.
Wait for a short interval of time for the threads to freeze. The register
information of the threads which are not frozen at the end of the interval,
is filled with 0's, to indicate we couldn't capture the information.
Signed-off-by: Suzuki K. Poulose <suzuki@...ibm.com>
---
fs/proc/gencore-elf.c | 20 ++++++++++++++++++++
fs/proc/gencore.c | 42 ++++++++++++++++++++++++++++++++++++++++++
fs/proc/gencore.h | 3 +++
3 files changed, 65 insertions(+)
Index: linux-2.6.36-rc7/fs/proc/gencore-elf.c
===================================================================
--- linux-2.6.36-rc7.orig/fs/proc/gencore-elf.c
+++ linux-2.6.36-rc7/fs/proc/gencore-elf.c
@@ -159,6 +159,21 @@ static int fill_thread_core_info(struct
}
#endif
+/*
+ * zero_thread_state :
+ * For threads, which are not frozen, we cannot capture the register state.
+ * We zero them out.
+ */
+static void zero_thread_state(struct elf_thread_core_info *tinfo)
+{
+ int i;
+
+ memset(&tinfo->prstatus.pr_reg, 0, sizeof(tinfo->prstatus.pr_reg));
+ for (i = 1; i < tinfo->num_notes; i++)
+ if (tinfo->notes[i].data)
+ memset(tinfo->notes[i].data, 0, tinfo->notes[i].datasz);
+}
+
/* Returns 0 on error, 1 on success */
static int collect_notes(struct core_proc *cp)
{
@@ -173,10 +188,15 @@ static int collect_notes(struct core_pro
fill_auxv_note(&cp->auxv, cp->task->mm);
cp->notes_size += notesize(&cp->auxv);
+ /* Make sure threads are frozen, before we start collecting notes */
+ try_to_freeze_core_threads(cp);
+
tinfo = cp->tinfo;
while (tinfo != NULL) {
if (!fill_thread_core_info(tinfo, cp))
return 0;
+ if (!tinfo->frozen)
+ zero_thread_state(tinfo);
tinfo = tinfo->next;
}
return 1;
Index: linux-2.6.36-rc7/fs/proc/gencore.h
===================================================================
--- linux-2.6.36-rc7.orig/fs/proc/gencore.h
+++ linux-2.6.36-rc7/fs/proc/gencore.h
@@ -7,6 +7,7 @@
#include <linux/elfcore-internal.h>
struct elf_thread_core_info {
+ unsigned short frozen;
unsigned short num_notes; /* Number of notes for this thread */
struct elf_thread_core_info *next;
struct task_struct *task;
@@ -28,6 +29,8 @@ struct core_proc {
size_t notes_size;
};
+extern void try_to_freeze_core_threads(struct core_proc *cp);
+
#ifdef CORE_DUMP_USE_REGSET
#include <linux/regset.h>
Index: linux-2.6.36-rc7/fs/proc/gencore.c
===================================================================
--- linux-2.6.36-rc7.orig/fs/proc/gencore.c
+++ linux-2.6.36-rc7/fs/proc/gencore.c
@@ -30,6 +30,8 @@
#include "internal.h"
#include "gencore.h"
+#define FREEZE_TIMEOUT (20 * HZ)
+
static LIST_HEAD(core_list);
static DEFINE_MUTEX(core_mutex);
@@ -45,6 +47,46 @@ static struct core_proc* get_core_proc(s
return NULL;
}
+/* Borrowed from kernel/cgroup_freezer.c */
+static int is_task_frozen_enough(struct task_struct *task)
+{
+ return frozen(task) ||
+ (task_is_stopped_or_traced(task) && freezing(task));
+}
+/*
+ * Wait for a short interval, to let the threads freeze.
+ * If "current" is generating the core, we should skip
+ * it.
+ * Based on try_to_freeze_tasks, kernel/power/process.c
+ */
+void try_to_freeze_core_threads(struct core_proc *cp)
+{
+ unsigned long end_time;
+ struct elf_thread_core_info *tinfo;
+ unsigned todo;
+
+ end_time = jiffies + FREEZE_TIMEOUT;
+
+retry:
+ tinfo = cp->tinfo;
+ todo = 0;
+ while (tinfo != NULL) {
+ if ((tinfo->task != current) && !tinfo->frozen) {
+ if (is_task_frozen_enough(tinfo->task))
+ tinfo->frozen = 1;
+ else
+ todo++;
+ }
+ tinfo = tinfo->next;
+ }
+
+ if (!todo || time_after(jiffies, end_time))
+ return;
+
+ schedule();
+ goto retry;
+}
+
static ssize_t read_gencore(struct file *file, char __user *buffer,
size_t buflen, loff_t *fpos)
{
--
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