From owner-svn-src-user@FreeBSD.ORG Sun May 4 15:05:55 2014 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id E09EC713; Sun, 4 May 2014 15:05:54 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CCB251C23; Sun, 4 May 2014 15:05:54 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s44F5shL031323; Sun, 4 May 2014 15:05:54 GMT (envelope-from dchagin@svn.freebsd.org) Received: (from dchagin@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s44F5r5X031316; Sun, 4 May 2014 15:05:53 GMT (envelope-from dchagin@svn.freebsd.org) Message-Id: <201405041505.s44F5r5X031316@svn.freebsd.org> From: Dmitry Chagin Date: Sun, 4 May 2014 15:05:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r265322 - in user/dchagin/lemul/sys: amd64/linux amd64/linux32 compat/linux i386/linux X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 04 May 2014 15:05:55 -0000 Author: dchagin Date: Sun May 4 15:05:53 2014 New Revision: 265322 URL: http://svnweb.freebsd.org/changeset/base/265322 Log: Refund the proc emuldata struct for future use (epoll). For now move flags from thread emuldata to proc emuldata as it was originally intended. Modified: user/dchagin/lemul/sys/amd64/linux/linux_sysvec.c user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c user/dchagin/lemul/sys/compat/linux/linux_emul.c user/dchagin/lemul/sys/compat/linux/linux_emul.h user/dchagin/lemul/sys/compat/linux/linux_futex.c user/dchagin/lemul/sys/i386/linux/linux_sysvec.c Modified: user/dchagin/lemul/sys/amd64/linux/linux_sysvec.c ============================================================================== --- user/dchagin/lemul/sys/amd64/linux/linux_sysvec.c Sun May 4 14:05:14 2014 (r265321) +++ user/dchagin/lemul/sys/amd64/linux/linux_sysvec.c Sun May 4 15:05:53 2014 (r265322) @@ -128,6 +128,7 @@ static int linux_vsyscall(struct thread static eventhandler_tag linux_exec_tag; static eventhandler_tag linux_thread_dtor_tag; +static eventhandler_tag linux_exit_tag; /* * Linux syscalls return negative errno's, we do positive and map them @@ -959,6 +960,8 @@ linux64_elf_modevent(module_t mod, int t linux_device_register_handler(*ldhp); LIST_INIT(&futex_list); mtx_init(&futex_mtx, "ftllk64", NULL, MTX_DEF); + linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, + linux_proc_exit, NULL, 1000); linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec, NULL, 1000); linux_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor, @@ -987,6 +990,7 @@ linux64_elf_modevent(module_t mod, int t SET_FOREACH(ldhp, linux_device_handler_set) linux_device_unregister_handler(*ldhp); mtx_destroy(&futex_mtx); + EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); EVENTHANDLER_DEREGISTER(thread_dtor, linux_thread_dtor_tag); linux_osd_jail_deregister(); Modified: user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c ============================================================================== --- user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c Sun May 4 14:05:14 2014 (r265321) +++ user/dchagin/lemul/sys/amd64/linux32/linux32_sysvec.c Sun May 4 15:05:53 2014 (r265322) @@ -135,6 +135,7 @@ static void linux_vdso_deinstall(void *p static eventhandler_tag linux_exec_tag; static eventhandler_tag linux_thread_dtor_tag; +static eventhandler_tag linux_exit_tag; /* * Linux syscalls return negative errno's, we do positive and map them @@ -1169,6 +1170,8 @@ linux_elf_modevent(module_t mod, int typ linux_device_register_handler(*ldhp); LIST_INIT(&futex_list); mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF); + linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, + linux_proc_exit, NULL, 1000); linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec, NULL, 1000); linux_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor, @@ -1197,6 +1200,7 @@ linux_elf_modevent(module_t mod, int typ SET_FOREACH(ldhp, linux_device_handler_set) linux_device_unregister_handler(*ldhp); mtx_destroy(&futex_mtx); + EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); EVENTHANDLER_DEREGISTER(thread_dtor, linux_thread_dtor_tag); linux_osd_jail_deregister(); Modified: user/dchagin/lemul/sys/compat/linux/linux_emul.c ============================================================================== --- user/dchagin/lemul/sys/compat/linux/linux_emul.c Sun May 4 14:05:14 2014 (r265321) +++ user/dchagin/lemul/sys/compat/linux/linux_emul.c Sun May 4 15:05:53 2014 (r265322) @@ -100,7 +100,7 @@ LIN_SDT_PROBE_DEFINE1(emul, linux_set_ti LIN_SDT_PROBE_DEFINE0(emul, linux_set_tid_address, return); /* - * This returns reference to the emuldata entry (if found) + * This returns reference to the thread emuldata entry (if found) * * Hold PROC_LOCK when referencing emuldata from other threads. */ @@ -118,10 +118,27 @@ em_find(struct thread *td) return (em); } +/* + * This returns reference to the proc pemuldata entry (if found) + * + * Hold PROC_LOCK when referencing proc pemuldata from other threads. + * Hold LINUX_PEM_LOCK wher referencing pemuldata members. + */ +struct linux_pemuldata * +pem_find(struct proc *p) +{ + struct linux_pemuldata *pem; + + pem = p->p_emuldata; + + return (pem); +} + void linux_proc_init(struct thread *td, struct thread *newtd, int flags) { struct linux_emuldata *em; + struct linux_pemuldata *pem; LIN_SDT_PROBE3(emul, proc_init, entry, td, newtd, flags); @@ -129,7 +146,6 @@ linux_proc_init(struct thread *td, struc /* non-exec call */ em = malloc(sizeof(*em), M_TEMP, M_WAITOK | M_ZERO); em->pdeath_signal = 0; - em->flags = 0; em->robust_futexes = NULL; if (flags & LINUX_CLONE_THREAD) { LIN_SDT_PROBE0(emul, proc_init, create_thread); @@ -143,6 +159,10 @@ linux_proc_init(struct thread *td, struc newtd->td_proc->p_pid); em->em_tid = newtd->td_proc->p_pid; + + pem = malloc(sizeof(*pem), M_TEMP, M_WAITOK | M_ZERO); + sx_init(&pem->pem_sx, "lpemlk"); + newtd->td_proc->p_emuldata = pem; } newtd->td_emuldata = em; } else { @@ -167,6 +187,7 @@ linux_proc_init(struct thread *td, struc int linux_common_execve(struct thread *td, struct image_args *eargs) { + struct linux_pemuldata *pem; struct linux_emuldata *em; struct proc *p; int error; @@ -178,22 +199,26 @@ linux_common_execve(struct thread *td, s p = td->td_proc; /* * In a case of transition from Linux binary execing to - * FreeBSD binary we destroy linux emuldata thread entry. + * FreeBSD binary we destroy linux emuldata thread & proc entries. */ if (SV_CURPROC_ABI() != SV_ABI_LINUX) { PROC_LOCK(p); em = em_find(td); - KASSERT(em != NULL, ("proc_exec: emuldata not found.\n")); + KASSERT(em != NULL, ("proc_exec: thread emuldata not found.\n")); td->td_emuldata = NULL; PROC_UNLOCK(p); + pem = pem_find(p); + KASSERT(pem != NULL, ("proc_exit: proc emuldata not found.\n")); + p->p_emuldata = NULL; + + sx_destroy(&pem->pem_sx); + free(pem, M_TEMP); free(em, M_TEMP); } return (0); } - - void linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp) { @@ -227,7 +252,7 @@ linux_thread_detach(struct thread *td) LIN_SDT_PROBE1(emul, linux_thread_detach, entry, td); em = em_find(td); - KASSERT(em != NULL, ("thread_detach: emuldata not found.\n")); + KASSERT(em != NULL, ("thread_detach: thread emuldata not found.\n")); LINUX_CTR1(exit, "thread detach(%d)", em->em_tid); @@ -297,7 +322,7 @@ linux_schedtail(struct thread *td) p = td->td_proc; em = em_find(td); - KASSERT(em != NULL, ("linux_schedtail: emuldata not found.\n")); + KASSERT(em != NULL, ("linux_schedtail: thread emuldata not found.\n")); child_set_tid = em->child_set_tid; if (child_set_tid != NULL) { @@ -336,3 +361,20 @@ linux_set_tid_address(struct thread *td, LIN_SDT_PROBE0(emul, linux_set_tid_address, return); return (0); } + +void +linux_proc_exit(void *arg __unused, struct proc *p) +{ + struct linux_pemuldata *pem; + + if (__predict_true(SV_PROC_ABI(p) != SV_ABI_LINUX)) + return; + + pem = pem_find(p); + KASSERT(pem != NULL, ("proc_exit: proc emuldata not found.\n")); + p->p_emuldata = NULL; + + sx_destroy(&pem->pem_sx); + free(pem, M_TEMP); +} + Modified: user/dchagin/lemul/sys/compat/linux/linux_emul.h ============================================================================== --- user/dchagin/lemul/sys/compat/linux/linux_emul.h Sun May 4 14:05:14 2014 (r265321) +++ user/dchagin/lemul/sys/compat/linux/linux_emul.h Sun May 4 15:05:53 2014 (r265322) @@ -41,7 +41,6 @@ struct linux_emuldata { int *child_clear_tid;/* in clone(): Child's TID to clear on exit */ int pdeath_signal; /* parent death signal */ - int flags; /* different emuldata flags */ int em_tid; /* thread id */ struct linux_robust_list_head *robust_futexes; @@ -50,15 +49,27 @@ struct linux_emuldata { struct linux_emuldata *em_find(struct thread *); -/* emuldata flags */ -#define LINUX_XDEPR_REQUEUEOP 0x00000001 /* uses deprecated - futex REQUEUE op*/ - int linux_common_execve(struct thread *, struct image_args *); void linux_proc_init(struct thread *, struct thread *, int); void linux_schedtail(struct thread *); void linux_proc_exec(void *, struct proc *, struct image_params *); +void linux_proc_exit(void *, struct proc *); void linux_thread_dtor(void *arg __unused, struct thread *); void linux_thread_detach(struct thread *); +/* process emuldata flags */ +#define LINUX_XDEPR_REQUEUEOP 0x00000001 /* uses deprecated + futex REQUEUE op*/ +struct linux_pemuldata { + uint32_t flags; /* different emuldata flags */ + struct sx pem_sx; /* lock for this struct */ +}; + +#define LINUX_PEM_XLOCK(p) sx_xlock(&(p)->pem_sx) +#define LINUX_PEM_XUNLOCK(p) sx_xunlock(&(p)->pem_sx) +#define LINUX_PEM_SLOCK(p) sx_slock(&(p)->pem_sx) +#define LINUX_PEM_SUNLOCK(p) sx_sunlock(&(p)->pem_sx) + +struct linux_pemuldata *pem_find(struct proc *); + #endif /* !_LINUX_EMUL_H_ */ Modified: user/dchagin/lemul/sys/compat/linux/linux_futex.c ============================================================================== --- user/dchagin/lemul/sys/compat/linux/linux_futex.c Sun May 4 14:05:14 2014 (r265321) +++ user/dchagin/lemul/sys/compat/linux/linux_futex.c Sun May 4 15:05:53 2014 (r265322) @@ -652,7 +652,7 @@ int linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) { int clockrt, nrwake, op_ret, ret, val; - struct linux_emuldata *em; + struct linux_pemuldata *pem; struct waiting_proc *wp; struct futex *f, *f2; struct l_timespec timeout; @@ -975,12 +975,12 @@ linux_sys_futex(struct thread *td, struc * Glibc versions prior to 2.3.3 fall back to FUTEX_WAKE when * FUTEX_REQUEUE returned EINVAL. */ - em = em_find(td); - if ((em->flags & LINUX_XDEPR_REQUEUEOP) == 0) { + pem = pem_find(td->td_proc); + if ((pem->flags & LINUX_XDEPR_REQUEUEOP) == 0) { linux_msg(td, "linux_sys_futex: " "unsupported futex_requeue op\n"); - em->flags |= LINUX_XDEPR_REQUEUEOP; + pem->flags |= LINUX_XDEPR_REQUEUEOP; LIN_SDT_PROBE0(futex, linux_sys_futex, deprecated_requeue); } Modified: user/dchagin/lemul/sys/i386/linux/linux_sysvec.c ============================================================================== --- user/dchagin/lemul/sys/i386/linux/linux_sysvec.c Sun May 4 14:05:14 2014 (r265321) +++ user/dchagin/lemul/sys/i386/linux/linux_sysvec.c Sun May 4 15:05:53 2014 (r265322) @@ -121,6 +121,7 @@ const char *linux_kplatform; static eventhandler_tag linux_exec_tag; static eventhandler_tag linux_thread_dtor_tag; +static eventhandler_tag linux_exit_tag; /* * Linux syscalls return negative errno's, we do positive and map them @@ -1148,8 +1149,10 @@ linux_elf_modevent(module_t mod, int typ linux_device_register_handler(*ldhp); LIST_INIT(&futex_list); mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF); - linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec, - NULL, 1000); + linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, + linux_proc_exit, NULL, 1000); + linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, + linux_proc_exec, NULL, 1000); linux_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor, linux_thread_dtor, NULL, EVENTHANDLER_PRI_ANY); linux_get_machine(&linux_kplatform); @@ -1179,6 +1182,7 @@ linux_elf_modevent(module_t mod, int typ SET_FOREACH(ldhp, linux_device_handler_set) linux_device_unregister_handler(*ldhp); mtx_destroy(&futex_mtx); + EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); EVENTHANDLER_DEREGISTER(thread_dtor, linux_thread_dtor_tag); linux_osd_jail_deregister();