aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Rientjes <rientjes@google.com>2009-01-06 17:39:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 18:58:59 -0500
commit75aa199410359dc5fbcf9025ff7af98a9d20f0d5 (patch)
tree569bffa181ccba56d884ec7e826ae61384297f56
parentc7d4caeb1d68d07f77cc09fc20b7759d6d7aa3b1 (diff)
oom: print triggering task's cpuset and mems allowed
When cpusets are enabled, it's necessary to print the triggering task's set of allowable nodes so the subsequently printed meminfo can be interpreted correctly. We also print the task's cpuset name for informational purposes. [rientjes@google.com: task lock current before dereferencing cpuset] Cc: Paul Menage <menage@google.com> Cc: Li Zefan <lizf@cn.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/cpuset.h6
-rw-r--r--kernel/cpuset.c34
-rw-r--r--mm/oom_kill.c3
3 files changed, 43 insertions, 0 deletions
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 8e540d32c9fe..51ea2bdea0f9 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -78,6 +78,8 @@ extern int current_cpuset_is_being_rebound(void);
78 78
79extern void rebuild_sched_domains(void); 79extern void rebuild_sched_domains(void);
80 80
81extern void cpuset_print_task_mems_allowed(struct task_struct *p);
82
81#else /* !CONFIG_CPUSETS */ 83#else /* !CONFIG_CPUSETS */
82 84
83static inline int cpuset_init_early(void) { return 0; } 85static inline int cpuset_init_early(void) { return 0; }
@@ -159,6 +161,10 @@ static inline void rebuild_sched_domains(void)
159 partition_sched_domains(1, NULL, NULL); 161 partition_sched_domains(1, NULL, NULL);
160} 162}
161 163
164static inline void cpuset_print_task_mems_allowed(struct task_struct *p)
165{
166}
167
162#endif /* !CONFIG_CPUSETS */ 168#endif /* !CONFIG_CPUSETS */
163 169
164#endif /* _LINUX_CPUSET_H */ 170#endif /* _LINUX_CPUSET_H */
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 39c1a4c1c5a9..345ace5117de 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -240,6 +240,17 @@ static struct cpuset top_cpuset = {
240static DEFINE_MUTEX(callback_mutex); 240static DEFINE_MUTEX(callback_mutex);
241 241
242/* 242/*
243 * cpuset_buffer_lock protects both the cpuset_name and cpuset_nodelist
244 * buffers. They are statically allocated to prevent using excess stack
245 * when calling cpuset_print_task_mems_allowed().
246 */
247#define CPUSET_NAME_LEN (128)
248#define CPUSET_NODELIST_LEN (256)
249static char cpuset_name[CPUSET_NAME_LEN];
250static char cpuset_nodelist[CPUSET_NODELIST_LEN];
251static DEFINE_SPINLOCK(cpuset_buffer_lock);
252
253/*
243 * This is ugly, but preserves the userspace API for existing cpuset 254 * This is ugly, but preserves the userspace API for existing cpuset
244 * users. If someone tries to mount the "cpuset" filesystem, we 255 * users. If someone tries to mount the "cpuset" filesystem, we
245 * silently switch it to mount "cgroup" instead 256 * silently switch it to mount "cgroup" instead
@@ -2356,6 +2367,29 @@ int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
2356 return nodes_intersects(tsk1->mems_allowed, tsk2->mems_allowed); 2367 return nodes_intersects(tsk1->mems_allowed, tsk2->mems_allowed);
2357} 2368}
2358 2369
2370/**
2371 * cpuset_print_task_mems_allowed - prints task's cpuset and mems_allowed
2372 * @task: pointer to task_struct of some task.
2373 *
2374 * Description: Prints @task's name, cpuset name, and cached copy of its
2375 * mems_allowed to the kernel log. Must hold task_lock(task) to allow
2376 * dereferencing task_cs(task).
2377 */
2378void cpuset_print_task_mems_allowed(struct task_struct *tsk)
2379{
2380 struct dentry *dentry;
2381
2382 dentry = task_cs(tsk)->css.cgroup->dentry;
2383 spin_lock(&cpuset_buffer_lock);
2384 snprintf(cpuset_name, CPUSET_NAME_LEN,
2385 dentry ? (const char *)dentry->d_name.name : "/");
2386 nodelist_scnprintf(cpuset_nodelist, CPUSET_NODELIST_LEN,
2387 tsk->mems_allowed);
2388 printk(KERN_INFO "%s cpuset=%s mems_allowed=%s\n",
2389 tsk->comm, cpuset_name, cpuset_nodelist);
2390 spin_unlock(&cpuset_buffer_lock);
2391}
2392
2359/* 2393/*
2360 * Collection of memory_pressure is suppressed unless 2394 * Collection of memory_pressure is suppressed unless
2361 * this flag is enabled by writing "1" to the special 2395 * this flag is enabled by writing "1" to the special
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index e5f50cfdca4d..6b9e758c98a5 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -392,6 +392,9 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
392 printk(KERN_WARNING "%s invoked oom-killer: " 392 printk(KERN_WARNING "%s invoked oom-killer: "
393 "gfp_mask=0x%x, order=%d, oomkilladj=%d\n", 393 "gfp_mask=0x%x, order=%d, oomkilladj=%d\n",
394 current->comm, gfp_mask, order, current->oomkilladj); 394 current->comm, gfp_mask, order, current->oomkilladj);
395 task_lock(current);
396 cpuset_print_task_mems_allowed(current);
397 task_unlock(current);
395 dump_stack(); 398 dump_stack();
396 show_mem(); 399 show_mem();
397 if (sysctl_oom_dump_tasks) 400 if (sysctl_oom_dump_tasks)