svn commit: r265322 - in user/dchagin/lemul/sys: amd64/linux amd64/linux32 compat/linux i386/linux
Dmitry Chagin
dchagin at FreeBSD.org
Sun May 4 15:05:55 UTC 2014
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();
More information about the svn-src-user
mailing list