Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751845AbdINUMt (ORCPT ); Thu, 14 Sep 2017 16:12:49 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:42672 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751610AbdINUMq (ORCPT ); Thu, 14 Sep 2017 16:12:46 -0400 Date: Thu, 14 Sep 2017 13:12:45 -0700 From: Andrew Morton To: Sherry Yang Cc: linux-kernel@vger.kernel.org, maco@google.com, tkjos@google.com, Greg Kroah-Hartman , Arve =?ISO-8859-1?Q?Hj=F8nnev?= =?ISO-8859-1?Q?=E5g?= , Riley Andrews , Ingo Molnar , Michal Hocko , Vlastimil Babka , Hillf Danton , Peter Zijlstra , Andrea Arcangeli , Thomas Gleixner , Andy Lutomirski , Oleg Nesterov , Hoeun Ryu , Christoph Lameter , Vegard Nossum , Frederic Weisbecker , devel@driverdev.osuosl.org (open list:ANDROID DRIVERS) Subject: Re: [PATCH v2] android: binder: Drop lru lock in isolate callback Message-Id: <20170914131245.2808f63306a9711fe233b37e@linux-foundation.org> In-Reply-To: <20170914182231.90908-1-sherryy@android.com> References: <20170914081929.um7lszeqtkesdtx3@dhcp22.suse.cz> <20170914182231.90908-1-sherryy@android.com> X-Mailer: Sylpheed 3.4.1 (GTK+ 2.24.23; x86_64-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4416 Lines: 162 On Thu, 14 Sep 2017 14:22:25 -0400 Sherry Yang wrote: > Drop the global lru lock in isolate callback > before calling zap_page_range which calls > cond_resched, and re-acquire the global lru > lock before returning. Also change return > code to LRU_REMOVED_RETRY. > > Use mmput_async when fail to acquire mmap sem > in an atomic context. > > Fix "BUG: sleeping function called from invalid context" > errors when CONFIG_DEBUG_ATOMIC_SLEEP is enabled. > > Also restore mmput_async, which was initially introduced in > ec8d7c14e ("mm, oom_reaper: do not mmput synchronously from > the oom reaper context"), and was removed in 212925802 > ("mm: oom: let oom_reap_task and exit_mmap run concurrently"). Ho hum, OK. It's a bit sad to bring this back for one caller but mm.async_put_work is there and won't be going away. The mmdrop_async stuff should be moved into fork.c (and maybe made static) as well. It's pointless having this stuff global and inlined, especially mmdrop_async_fn(). Something like the below, not yet tested... From: Andrew Morton Subject: include/linux/sched/mm.h: uninline mmdrop_async(), etc mmdrop_async() is only used in fork.c. Move that and its support functions into fork.c, uninline it all. Signed-off-by: Andrew Morton --- include/linux/sched/mm.h | 24 +-------------- kernel/fork.c | 58 +++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 40 deletions(-) diff -puN include/linux/sched/mm.h~a include/linux/sched/mm.h --- a/include/linux/sched/mm.h~a +++ a/include/linux/sched/mm.h @@ -10,7 +10,7 @@ /* * Routines for handling mm_structs */ -extern struct mm_struct * mm_alloc(void); +extern struct mm_struct *mm_alloc(void); /** * mmgrab() - Pin a &struct mm_struct. @@ -34,27 +34,7 @@ static inline void mmgrab(struct mm_stru atomic_inc(&mm->mm_count); } -/* mmdrop drops the mm and the page tables */ -extern void __mmdrop(struct mm_struct *); -static inline void mmdrop(struct mm_struct *mm) -{ - if (unlikely(atomic_dec_and_test(&mm->mm_count))) - __mmdrop(mm); -} - -static inline void mmdrop_async_fn(struct work_struct *work) -{ - struct mm_struct *mm = container_of(work, struct mm_struct, async_put_work); - __mmdrop(mm); -} - -static inline void mmdrop_async(struct mm_struct *mm) -{ - if (unlikely(atomic_dec_and_test(&mm->mm_count))) { - INIT_WORK(&mm->async_put_work, mmdrop_async_fn); - schedule_work(&mm->async_put_work); - } -} +extern void mmdrop(struct mm_struct *mm); /** * mmget() - Pin the address space associated with a &struct mm_struct. diff -puN kernel/fork.c~a kernel/fork.c --- a/kernel/fork.c~a +++ a/kernel/fork.c @@ -386,6 +386,46 @@ void free_task(struct task_struct *tsk) } EXPORT_SYMBOL(free_task); +/* + * Called when the last reference to the mm + * is dropped: either by a lazy thread or by + * mmput. Free the page directory and the mm. + */ +static void __mmdrop(struct mm_struct *mm) +{ + BUG_ON(mm == &init_mm); + mm_free_pgd(mm); + destroy_context(mm); + hmm_mm_destroy(mm); + mmu_notifier_mm_destroy(mm); + check_mm(mm); + put_user_ns(mm->user_ns); + free_mm(mm); +} + +void mmdrop(struct mm_struct *mm) +{ + if (unlikely(atomic_dec_and_test(&mm->mm_count))) + __mmdrop(mm); +} +EXPORT_SYMBOL_GPL(mmdrop) + +static void mmdrop_async_fn(struct work_struct *work) +{ + struct mm_struct *mm; + + mm = container_of(work, struct mm_struct, async_put_work); + __mmdrop(mm); +} + +static void mmdrop_async(struct mm_struct *mm) +{ + if (unlikely(atomic_dec_and_test(&mm->mm_count))) { + INIT_WORK(&mm->async_put_work, mmdrop_async_fn); + schedule_work(&mm->async_put_work); + } +} + static inline void free_signal_struct(struct signal_struct *sig) { taskstats_tgid_free(sig); @@ -895,24 +935,6 @@ struct mm_struct *mm_alloc(void) return mm_init(mm, current, current_user_ns()); } -/* - * Called when the last reference to the mm - * is dropped: either by a lazy thread or by - * mmput. Free the page directory and the mm. - */ -void __mmdrop(struct mm_struct *mm) -{ - BUG_ON(mm == &init_mm); - mm_free_pgd(mm); - destroy_context(mm); - hmm_mm_destroy(mm); - mmu_notifier_mm_destroy(mm); - check_mm(mm); - put_user_ns(mm->user_ns); - free_mm(mm); -} -EXPORT_SYMBOL_GPL(__mmdrop); - static inline void __mmput(struct mm_struct *mm) { VM_BUG_ON(atomic_read(&mm->mm_users)); _