On Thu, 14 Sep 2017 14:22:25 -0400 Sherry Yang <sherryy@xxxxxxxxxxx> 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 <akpm@xxxxxxxxxxxxxxxxxxxx> 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 <akpm@xxxxxxxxxxxxxxxxxxxx> --- 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)); _ _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel