Merge branch 'akpm' (Andrew's patch-bomb)
Merge first batch of patches from Andrew Morton: "A few misc things and all the MM queue" * emailed from Andrew Morton <akpm@linux-foundation.org>: (92 commits) memcg: avoid THP split in task migration thp: add HPAGE_PMD_* definitions for !CONFIG_TRANSPARENT_HUGEPAGE memcg: clean up existing move charge code mm/memcontrol.c: remove unnecessary 'break' in mem_cgroup_read() mm/memcontrol.c: remove redundant BUG_ON() in mem_cgroup_usage_unregister_event() mm/memcontrol.c: s/stealed/stolen/ memcg: fix performance of mem_cgroup_begin_update_page_stat() memcg: remove PCG_FILE_MAPPED memcg: use new logic for page stat accounting memcg: remove PCG_MOVE_LOCK flag from page_cgroup memcg: simplify move_account() check memcg: remove EXPORT_SYMBOL(mem_cgroup_update_page_stat) memcg: kill dead prev_priority stubs memcg: remove PCG_CACHE page_cgroup flag memcg: let css_get_next() rely upon rcu_read_lock() cgroup: revert ss_id_lock to spinlock idr: make idr_get_next() good for rcu_read_lock() memcg: remove unnecessary thp check in page stat accounting memcg: remove redundant returns memcg: enum lru_list lru ...
This commit is contained in:
@@ -4881,9 +4881,9 @@ void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css)
|
||||
|
||||
rcu_assign_pointer(id->css, NULL);
|
||||
rcu_assign_pointer(css->id, NULL);
|
||||
write_lock(&ss->id_lock);
|
||||
spin_lock(&ss->id_lock);
|
||||
idr_remove(&ss->idr, id->id);
|
||||
write_unlock(&ss->id_lock);
|
||||
spin_unlock(&ss->id_lock);
|
||||
kfree_rcu(id, rcu_head);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(free_css_id);
|
||||
@@ -4909,10 +4909,10 @@ static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
|
||||
error = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
write_lock(&ss->id_lock);
|
||||
spin_lock(&ss->id_lock);
|
||||
/* Don't use 0. allocates an ID of 1-65535 */
|
||||
error = idr_get_new_above(&ss->idr, newid, 1, &myid);
|
||||
write_unlock(&ss->id_lock);
|
||||
spin_unlock(&ss->id_lock);
|
||||
|
||||
/* Returns error when there are no free spaces for new ID.*/
|
||||
if (error) {
|
||||
@@ -4927,9 +4927,9 @@ static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
|
||||
return newid;
|
||||
remove_idr:
|
||||
error = -ENOSPC;
|
||||
write_lock(&ss->id_lock);
|
||||
spin_lock(&ss->id_lock);
|
||||
idr_remove(&ss->idr, myid);
|
||||
write_unlock(&ss->id_lock);
|
||||
spin_unlock(&ss->id_lock);
|
||||
err_out:
|
||||
kfree(newid);
|
||||
return ERR_PTR(error);
|
||||
@@ -4941,7 +4941,7 @@ static int __init_or_module cgroup_init_idr(struct cgroup_subsys *ss,
|
||||
{
|
||||
struct css_id *newid;
|
||||
|
||||
rwlock_init(&ss->id_lock);
|
||||
spin_lock_init(&ss->id_lock);
|
||||
idr_init(&ss->idr);
|
||||
|
||||
newid = get_new_cssid(ss, 0);
|
||||
@@ -5029,6 +5029,8 @@ css_get_next(struct cgroup_subsys *ss, int id,
|
||||
return NULL;
|
||||
|
||||
BUG_ON(!ss->use_id);
|
||||
WARN_ON_ONCE(!rcu_read_lock_held());
|
||||
|
||||
/* fill start point for scan */
|
||||
tmpid = id;
|
||||
while (1) {
|
||||
@@ -5036,10 +5038,7 @@ css_get_next(struct cgroup_subsys *ss, int id,
|
||||
* scan next entry from bitmap(tree), tmpid is updated after
|
||||
* idr_get_next().
|
||||
*/
|
||||
read_lock(&ss->id_lock);
|
||||
tmp = idr_get_next(&ss->idr, &tmpid);
|
||||
read_unlock(&ss->id_lock);
|
||||
|
||||
if (!tmp)
|
||||
break;
|
||||
if (tmp->depth >= depth && tmp->stack[depth] == rootid) {
|
||||
|
@@ -964,7 +964,6 @@ static void cpuset_change_task_nodemask(struct task_struct *tsk,
|
||||
{
|
||||
bool need_loop;
|
||||
|
||||
repeat:
|
||||
/*
|
||||
* Allow tasks that have access to memory reserves because they have
|
||||
* been OOM killed to get memory anywhere.
|
||||
@@ -983,45 +982,19 @@ repeat:
|
||||
*/
|
||||
need_loop = task_has_mempolicy(tsk) ||
|
||||
!nodes_intersects(*newmems, tsk->mems_allowed);
|
||||
|
||||
if (need_loop)
|
||||
write_seqcount_begin(&tsk->mems_allowed_seq);
|
||||
|
||||
nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems);
|
||||
mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1);
|
||||
|
||||
/*
|
||||
* ensure checking ->mems_allowed_change_disable after setting all new
|
||||
* allowed nodes.
|
||||
*
|
||||
* the read-side task can see an nodemask with new allowed nodes and
|
||||
* old allowed nodes. and if it allocates page when cpuset clears newly
|
||||
* disallowed ones continuous, it can see the new allowed bits.
|
||||
*
|
||||
* And if setting all new allowed nodes is after the checking, setting
|
||||
* all new allowed nodes and clearing newly disallowed ones will be done
|
||||
* continuous, and the read-side task may find no node to alloc page.
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
/*
|
||||
* Allocation of memory is very fast, we needn't sleep when waiting
|
||||
* for the read-side.
|
||||
*/
|
||||
while (need_loop && ACCESS_ONCE(tsk->mems_allowed_change_disable)) {
|
||||
task_unlock(tsk);
|
||||
if (!task_curr(tsk))
|
||||
yield();
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
/*
|
||||
* ensure checking ->mems_allowed_change_disable before clearing all new
|
||||
* disallowed nodes.
|
||||
*
|
||||
* if clearing newly disallowed bits before the checking, the read-side
|
||||
* task may find no node to alloc page.
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP2);
|
||||
tsk->mems_allowed = *newmems;
|
||||
|
||||
if (need_loop)
|
||||
write_seqcount_end(&tsk->mems_allowed_seq);
|
||||
|
||||
task_unlock(tsk);
|
||||
}
|
||||
|
||||
|
@@ -935,7 +935,7 @@ void do_exit(long code)
|
||||
acct_update_integrals(tsk);
|
||||
/* sync mm's RSS info before statistics gathering */
|
||||
if (tsk->mm)
|
||||
sync_mm_rss(tsk, tsk->mm);
|
||||
sync_mm_rss(tsk->mm);
|
||||
group_dead = atomic_dec_and_test(&tsk->signal->live);
|
||||
if (group_dead) {
|
||||
hrtimer_cancel(&tsk->signal->real_timer);
|
||||
|
@@ -512,6 +512,23 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void check_mm(struct mm_struct *mm)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NR_MM_COUNTERS; i++) {
|
||||
long x = atomic_long_read(&mm->rss_stat.count[i]);
|
||||
|
||||
if (unlikely(x))
|
||||
printk(KERN_ALERT "BUG: Bad rss-counter state "
|
||||
"mm:%p idx:%d val:%ld\n", mm, i, x);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
VM_BUG_ON(mm->pmd_huge_pte);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and initialize an mm_struct.
|
||||
*/
|
||||
@@ -539,9 +556,7 @@ void __mmdrop(struct mm_struct *mm)
|
||||
mm_free_pgd(mm);
|
||||
destroy_context(mm);
|
||||
mmu_notifier_mm_destroy(mm);
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
VM_BUG_ON(mm->pmd_huge_pte);
|
||||
#endif
|
||||
check_mm(mm);
|
||||
free_mm(mm);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__mmdrop);
|
||||
@@ -1223,6 +1238,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
||||
#ifdef CONFIG_CPUSETS
|
||||
p->cpuset_mem_spread_rotor = NUMA_NO_NODE;
|
||||
p->cpuset_slab_spread_rotor = NUMA_NO_NODE;
|
||||
seqcount_init(&p->mems_allowed_seq);
|
||||
#endif
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
p->irq_events = 0;
|
||||
|
Reference in New Issue
Block a user