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