Date: Mon, 26 Apr 2021 08:13:38 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: e284a6234ffb - stable/13 - linuxkpi: reduce number of stray mm_struct allocations Message-ID: <202104260813.13Q8DcEr009335@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=e284a6234ffb946d083e7239512c27855019f2c9 commit e284a6234ffb946d083e7239512c27855019f2c9 Author: Konstantin Belousov <konstantinb@nvidia.com> AuthorDate: 2021-03-11 06:48:22 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-04-26 07:10:13 +0000 linuxkpi: reduce number of stray mm_struct allocations (cherry picked from commit fad437ba612a7c19f5cf1633e2d0d1c44d4dd478) --- sys/compat/linuxkpi/common/src/linux_current.c | 85 +++++++++++++++----------- 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_current.c b/sys/compat/linuxkpi/common/src/linux_current.c index ef51acc1952e..9bae7ee92e49 100644 --- a/sys/compat/linuxkpi/common/src/linux_current.c +++ b/sys/compat/linuxkpi/common/src/linux_current.c @@ -48,15 +48,35 @@ static eventhandler_tag linuxkpi_thread_dtor_tag; static uma_zone_t linux_current_zone; static uma_zone_t linux_mm_zone; +/* check if another thread already has a mm_struct */ +static struct mm_struct * +find_other_mm(struct proc *p) +{ + struct thread *td; + struct task_struct *ts; + struct mm_struct *mm; + + PROC_LOCK_ASSERT(p, MA_OWNED); + FOREACH_THREAD_IN_PROC(p, td) { + ts = td->td_lkpi_task; + if (ts == NULL) + continue; + mm = ts->mm; + if (mm == NULL) + continue; + /* try to share other mm_struct */ + if (atomic_inc_not_zero(&mm->mm_users)) + return (mm); + } + return (NULL); +} + int linux_alloc_current(struct thread *td, int flags) { struct proc *proc; - struct thread *td_other; struct task_struct *ts; - struct task_struct *ts_other; - struct mm_struct *mm; - struct mm_struct *mm_other; + struct mm_struct *mm, *mm_other; MPASS(td->td_lkpi_task == NULL); @@ -71,14 +91,7 @@ linux_alloc_current(struct thread *td, int flags) panic("linux_alloc_current: failed to allocate task"); return (ENOMEM); } - - mm = uma_zalloc(linux_mm_zone, flags | M_ZERO); - if (mm == NULL) { - if ((flags & (M_WAITOK | M_NOWAIT)) == M_WAITOK) - panic("linux_alloc_current: failed to allocate mm"); - uma_zfree(linux_current_zone, mm); - return (ENOMEM); - } + mm = NULL; /* setup new task structure */ atomic_set(&ts->kthread_flags, 0); @@ -93,35 +106,37 @@ linux_alloc_current(struct thread *td, int flags) proc = td->td_proc; - /* check if another thread already has a mm_struct */ PROC_LOCK(proc); - FOREACH_THREAD_IN_PROC(proc, td_other) { - ts_other = td_other->td_lkpi_task; - if (ts_other == NULL) - continue; + mm_other = find_other_mm(proc); - mm_other = ts_other->mm; - if (mm_other == NULL) - continue; + /* use allocated mm_struct as a fallback */ + if (mm_other == NULL) { + PROC_UNLOCK(proc); + mm = uma_zalloc(linux_mm_zone, flags | M_ZERO); + if (mm == NULL) { + if ((flags & (M_WAITOK | M_NOWAIT)) == M_WAITOK) + panic( + "linux_alloc_current: failed to allocate mm"); + uma_zfree(linux_current_zone, mm); + return (ENOMEM); + } - /* try to share other mm_struct */ - if (atomic_inc_not_zero(&mm_other->mm_users)) { + PROC_LOCK(proc); + mm_other = find_other_mm(proc); + if (mm_other == NULL) { + /* setup new mm_struct */ + init_rwsem(&mm->mmap_sem); + atomic_set(&mm->mm_count, 1); + atomic_set(&mm->mm_users, 1); /* set mm_struct pointer */ + ts->mm = mm; + /* clear pointer to not free memory */ + mm = NULL; + } else { ts->mm = mm_other; - break; } - } - - /* use allocated mm_struct as a fallback */ - if (ts->mm == NULL) { - /* setup new mm_struct */ - init_rwsem(&mm->mmap_sem); - atomic_set(&mm->mm_count, 1); - atomic_set(&mm->mm_users, 1); - /* set mm_struct pointer */ - ts->mm = mm; - /* clear pointer to not free memory */ - mm = NULL; + } else { + ts->mm = mm_other; } /* store pointer to task struct */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202104260813.13Q8DcEr009335>