Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0f3c3f7 authored by Gavin Shan's avatar Gavin Shan Committed by Linus Torvalds
Browse files

mm/mmu_notifier: init notifier if necessary



While registering MMU notifier, new instance of MMU notifier_mm will be
allocated and later free'd if currrent mm_struct's MMU notifier_mm has
been initialized.  That causes some overhead.  The patch tries to
elominate that.

Signed-off-by: default avatarGavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: default avatarWanpeng Li <liwanp@linux.vnet.ibm.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Avi Kivity <avi@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Sagi Grimberg <sagig@mellanox.co.il>
Cc: Haggai Eran <haggaie@mellanox.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 21a92735
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -207,22 +207,23 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn,
	*/
	BUG_ON(!srcu.per_cpu_ref);

	ret = -ENOMEM;
	mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm), GFP_KERNEL);
	if (unlikely(!mmu_notifier_mm))
		goto out;

	if (take_mmap_sem)
		down_write(&mm->mmap_sem);
	ret = mm_take_all_locks(mm);
	if (unlikely(ret))
		goto out_cleanup;
		goto out;

	if (!mm_has_notifiers(mm)) {
		mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm),
					GFP_KERNEL);
		if (unlikely(!mmu_notifier_mm)) {
			ret = -ENOMEM;
			goto out_of_mem;
		}
		INIT_HLIST_HEAD(&mmu_notifier_mm->list);
		spin_lock_init(&mmu_notifier_mm->lock);

		mm->mmu_notifier_mm = mmu_notifier_mm;
		mmu_notifier_mm = NULL;
	}
	atomic_inc(&mm->mm_count);

@@ -238,13 +239,12 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn,
	hlist_add_head(&mn->hlist, &mm->mmu_notifier_mm->list);
	spin_unlock(&mm->mmu_notifier_mm->lock);

out_of_mem:
	mm_drop_all_locks(mm);
out_cleanup:
out:
	if (take_mmap_sem)
		up_write(&mm->mmap_sem);
	/* kfree() does nothing if mmu_notifier_mm is NULL */
	kfree(mmu_notifier_mm);
out:

	BUG_ON(atomic_read(&mm->mm_users) <= 0);
	return ret;
}