aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRik van Riel <riel@redhat.com>2013-10-07 06:29:28 -0400
committerIngo Molnar <mingo@kernel.org>2013-10-09 08:48:00 -0400
commit82727018b0d33d188e9916bcf76f18387484cb04 (patch)
tree429e0db98c4512f714a668ae9ef9d3bb6e85ce0f
parent83e1d2cd9eabec5164afea295ff06b941ae8e4a9 (diff)
sched/numa: Call task_numa_free() from do_execve()
It is possible for a task in a numa group to call exec, and have the new (unrelated) executable inherit the numa group association from its former self. This has the potential to break numa grouping, and is trivial to fix. Signed-off-by: Rik van Riel <riel@redhat.com> Signed-off-by: Mel Gorman <mgorman@suse.de> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1381141781-10992-51-git-send-email-mgorman@suse.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--fs/exec.c1
-rw-r--r--include/linux/sched.h4
-rw-r--r--kernel/sched/fair.c9
-rw-r--r--kernel/sched/sched.h5
4 files changed, 13 insertions, 6 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 8875dd10ae7a..2ea437e5acf4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1547,6 +1547,7 @@ static int do_execve_common(const char *filename,
1547 current->fs->in_exec = 0; 1547 current->fs->in_exec = 0;
1548 current->in_execve = 0; 1548 current->in_execve = 0;
1549 acct_update_integrals(current); 1549 acct_update_integrals(current);
1550 task_numa_free(current);
1550 free_bprm(bprm); 1551 free_bprm(bprm);
1551 if (displaced) 1552 if (displaced)
1552 put_files_struct(displaced); 1553 put_files_struct(displaced);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 724482200b83..f6385107c352 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1458,6 +1458,7 @@ struct task_struct {
1458extern void task_numa_fault(int last_node, int node, int pages, int flags); 1458extern void task_numa_fault(int last_node, int node, int pages, int flags);
1459extern pid_t task_numa_group_id(struct task_struct *p); 1459extern pid_t task_numa_group_id(struct task_struct *p);
1460extern void set_numabalancing_state(bool enabled); 1460extern void set_numabalancing_state(bool enabled);
1461extern void task_numa_free(struct task_struct *p);
1461#else 1462#else
1462static inline void task_numa_fault(int last_node, int node, int pages, 1463static inline void task_numa_fault(int last_node, int node, int pages,
1463 int flags) 1464 int flags)
@@ -1470,6 +1471,9 @@ static inline pid_t task_numa_group_id(struct task_struct *p)
1470static inline void set_numabalancing_state(bool enabled) 1471static inline void set_numabalancing_state(bool enabled)
1471{ 1472{
1472} 1473}
1474static inline void task_numa_free(struct task_struct *p)
1475{
1476}
1473#endif 1477#endif
1474 1478
1475static inline struct pid *task_pid(struct task_struct *task) 1479static inline struct pid *task_pid(struct task_struct *task)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 4c40e13310e9..c4df2de6ca4a 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1418,6 +1418,7 @@ void task_numa_free(struct task_struct *p)
1418{ 1418{
1419 struct numa_group *grp = p->numa_group; 1419 struct numa_group *grp = p->numa_group;
1420 int i; 1420 int i;
1421 void *numa_faults = p->numa_faults;
1421 1422
1422 if (grp) { 1423 if (grp) {
1423 for (i = 0; i < 2*nr_node_ids; i++) 1424 for (i = 0; i < 2*nr_node_ids; i++)
@@ -1433,7 +1434,9 @@ void task_numa_free(struct task_struct *p)
1433 put_numa_group(grp); 1434 put_numa_group(grp);
1434 } 1435 }
1435 1436
1436 kfree(p->numa_faults); 1437 p->numa_faults = NULL;
1438 p->numa_faults_buffer = NULL;
1439 kfree(numa_faults);
1437} 1440}
1438 1441
1439/* 1442/*
@@ -1452,6 +1455,10 @@ void task_numa_fault(int last_cpupid, int node, int pages, int flags)
1452 if (!p->mm) 1455 if (!p->mm)
1453 return; 1456 return;
1454 1457
1458 /* Do not worry about placement if exiting */
1459 if (p->state == TASK_DEAD)
1460 return;
1461
1455 /* Allocate buffer to track faults on a per-node basis */ 1462 /* Allocate buffer to track faults on a per-node basis */
1456 if (unlikely(!p->numa_faults)) { 1463 if (unlikely(!p->numa_faults)) {
1457 int size = sizeof(*p->numa_faults) * 2 * nr_node_ids; 1464 int size = sizeof(*p->numa_faults) * 2 * nr_node_ids;
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 8037b10a256f..eeb1923812a1 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -559,11 +559,6 @@ static inline u64 rq_clock_task(struct rq *rq)
559#ifdef CONFIG_NUMA_BALANCING 559#ifdef CONFIG_NUMA_BALANCING
560extern int migrate_task_to(struct task_struct *p, int cpu); 560extern int migrate_task_to(struct task_struct *p, int cpu);
561extern int migrate_swap(struct task_struct *, struct task_struct *); 561extern int migrate_swap(struct task_struct *, struct task_struct *);
562extern void task_numa_free(struct task_struct *p);
563#else /* CONFIG_NUMA_BALANCING */
564static inline void task_numa_free(struct task_struct *p)
565{
566}
567#endif /* CONFIG_NUMA_BALANCING */ 562#endif /* CONFIG_NUMA_BALANCING */
568 563
569#ifdef CONFIG_SMP 564#ifdef CONFIG_SMP