X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=kernel%2Fsched%2Ffair.c;h=f01eb276835d74e13fb24bc02920eb71c62b725f;hb=ae145f3c296b09548abddea97a21f9e984e0ccc9;hp=1eac0642fa86cf5cebcb2e3572e499b93045a8e8;hpb=a32f2cd759060ad2dd0a087177dfa108d48d2574;p=sagit-ice-cold%2Fkernel_xiaomi_msm8998.git diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 1eac0642fa86..f01eb276835d 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2233,13 +2233,23 @@ no_join: return; } -void task_numa_free(struct task_struct *p) +/* + * Get rid of NUMA staticstics associated with a task (either current or dead). + * If @final is set, the task is dead and has reached refcount zero, so we can + * safely free all relevant data structures. Otherwise, there might be + * concurrent reads from places like load balancing and procfs, and we should + * reset the data back to default state without freeing ->numa_faults. + */ +void task_numa_free(struct task_struct *p, bool final) { struct numa_group *grp = p->numa_group; - void *numa_faults = p->numa_faults; + unsigned long *numa_faults = p->numa_faults; unsigned long flags; int i; + if (!numa_faults) + return; + if (grp) { spin_lock_irqsave(&grp->lock, flags); for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++) @@ -2252,8 +2262,14 @@ void task_numa_free(struct task_struct *p) put_numa_group(grp); } - p->numa_faults = NULL; - kfree(numa_faults); + if (final) { + p->numa_faults = NULL; + kfree(numa_faults); + } else { + p->total_numa_faults = 0; + for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++) + numa_faults[i] = 0; + } } /* @@ -10713,9 +10729,10 @@ no_move: out_balanced: /* * We reach balance although we may have faced some affinity - * constraints. Clear the imbalance flag if it was set. + * constraints. Clear the imbalance flag only if other tasks got + * a chance to move and fix the imbalance. */ - if (sd_parent) { + if (sd_parent && !(env.flags & LBF_ALL_PINNED)) { int *group_imbalance = &sd_parent->groups->sgc->imbalance; if (*group_imbalance)