Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Aug 2002 00:19:19 -0700 (PDT)
From:      Jonathan Mini <mini@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 16252 for review
Message-ID:  <200208190719.g7J7JJow018343@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=16252

Change 16252 by mini@mini_stylus on 2002/08/19 00:19:18

	- Use ucontext_t to store state for threads, as well as for the UTS.
	- Instead of repeatedly returning to the same location in the UTS,
	  act as if we have swapcontext()'d in.

Affected files ...

.. //depot/projects/kse/sys/i386/i386/trap.c#60 edit
.. //depot/projects/kse/sys/i386/i386/vm_machdep.c#62 edit
.. //depot/projects/kse/sys/kern/kern_exit.c#60 edit
.. //depot/projects/kse/sys/kern/kern_fork.c#77 edit
.. //depot/projects/kse/sys/kern/kern_proc.c#78 edit
.. //depot/projects/kse/sys/kern/kern_thread.c#86 edit
.. //depot/projects/kse/sys/sys/kse.h#16 edit
.. //depot/projects/kse/sys/sys/proc.h#122 edit
.. //depot/projects/kse/sys/sys/ucontext.h#3 edit

Differences ...

==== //depot/projects/kse/sys/i386/i386/trap.c#60 (text+ko) ====

@@ -971,7 +971,7 @@
 		 * but for now do it every time.
 		 */
 		td->td_mailbox = (void *)fuword((caddr_t)td->td_kse->ke_mailbox
-		    + offsetof(struct kse_mailbox, kmbx_current_thread));
+		    + offsetof(struct kse_mailbox, km_curthread));
 		if ((td->td_mailbox == NULL) ||
 		(td->td_mailbox == (void *)-1)) {
 			td->td_mailbox = NULL;	/* single thread it.. */

==== //depot/projects/kse/sys/i386/i386/vm_machdep.c#62 (text+ko) ====

@@ -313,132 +313,6 @@
 };
 
 void
-cpu_save_upcall(struct thread *td, struct kse *newkse)
-{
-	struct trapframe *tf;
-
-	newkse->ke_mdstorage = malloc(sizeof(struct md_store), M_TEMP,
-	    M_WAITOK);
-	/* Note: use of M_WAITOK means it won't fail. */
-	/* set up shortcuts in MI section */
-	newkse->ke_pcb =
-	    &(((struct md_store *)(newkse->ke_mdstorage))->mds_pcb);
-	newkse->ke_frame =
-	    &(((struct md_store *)(newkse->ke_mdstorage))->mds_frame);
-	tf = newkse->ke_frame;
-
-	/* Copy the upcall pcb. Kernel mode & fp regs are here. */
-	/* XXXKSE this may be un-needed */
-	bcopy(td->td_pcb, newkse->ke_pcb, sizeof(struct pcb));
-
-	/*
-	 * This initialises most of the user mode register values
-	 * to good values. Eventually set them explicitly to know values
-	 */
-	bcopy(td->td_frame, newkse->ke_frame, sizeof(struct trapframe));
-	tf->tf_edi = 0;
-	tf->tf_esi = 0;		    /* trampoline arg */
-	tf->tf_ebp = 0;
-	tf->tf_esp = (int)newkse->ke_stackbase + newkse->ke_stacksize - 16;
-	tf->tf_ebx = 0;		    /* trampoline arg */
-	tf->tf_eip = (int)newkse->ke_upcall;
-}
-
-void
-cpu_set_upcall(struct thread *td, void *pcb)
-{
-	struct pcb *pcb2;
-
-	td->td_flags |= TDF_UPCALLING;
-
-	/* Point the pcb to the top of the stack. */
-	pcb2 = td->td_pcb;
-
-	/*
-	 * Copy the upcall pcb.  This loads kernel regs.
-	 * Those not loaded individually below get their default
-	 * values here.
-	 *
-	 * XXXKSE It might be a good idea to simply skip this as
-	 * the values of the other registers may be unimportant.
-	 * This would remove any requirement for knowing the KSE
-	 * at this time (see the matching comment below for
-	 * more analysis) (need a good safe default).
-	 */
-	bcopy(pcb, pcb2, sizeof(*pcb2));
-
-	/*
-	 * Create a new fresh stack for the new thread.
-	 * The -16 is so we can expand the trapframe if we go to vm86.
-	 * Don't forget to set this stack value into whatever supplies
-	 * the address for the fault handlers.
-	 * The contexts are filled in at the time we actually DO the
-	 * upcall as only then do we know which KSE we got.
-	 */
-	td->td_frame = (struct trapframe *)((caddr_t)pcb2 - 16) - 1;
-
-	/*
-	 * Set registers for trampoline to user mode.  Leave space for the
-	 * return address on stack.  These are the kernel mode register values.
-	 */
-	pcb2->pcb_cr3 = vtophys(vmspace_pmap(td->td_proc->p_vmspace)->pm_pdir);
-	pcb2->pcb_edi = 0;
-	pcb2->pcb_esi = (int)fork_return;		    /* trampoline arg */
-	pcb2->pcb_ebp = 0;
-	pcb2->pcb_esp = (int)td->td_frame - sizeof(void *); /* trampoline arg */
-	pcb2->pcb_ebx = (int)td;			    /* trampoline arg */
-	pcb2->pcb_eip = (int)fork_trampoline;
-	pcb2->pcb_psl &= ~(PSL_I);	/* interrupts must be disabled */
-	/*
-	 * If we didn't copy the pcb, we'd need to do the following registers:
-	 * pcb2->pcb_dr*:	cloned above.
-	 * pcb2->pcb_savefpu:	cloned above.
-	 * pcb2->pcb_flags:	cloned above.
-	 * pcb2->pcb_onfault:	cloned above (always NULL here?).
-	 * pcb2->pcb_gs:	cloned above.  XXXKSE ???
-	 * pcb2->pcb_ext:	cleared below.
-	 */
-	 pcb2->pcb_ext = NULL;
-}
-
-void
-cpu_set_args(struct thread *td, struct kse *ke) 
-{
-	suword((void *)(ke->ke_frame->tf_esp + sizeof(void *)),
-	    (int)ke->ke_mailbox);
-}
-
-void
-cpu_free_kse_mdstorage(struct kse *kse)
-{
-
-	free(kse->ke_mdstorage, M_TEMP);
-	kse->ke_mdstorage = NULL;
-	kse->ke_pcb = NULL;
-	kse->ke_frame = NULL;
-}
-
-int
-cpu_export_context(struct thread *td)
-{
-	struct trapframe *frame;
-	struct thread_mailbox *tm;
-	struct trapframe *uframe;
-	int error;
-
-	frame = td->td_frame;
-	tm = td->td_mailbox;
-	uframe = &tm->ctx.tfrm.tf_tf;
-	error = copyout(frame, uframe, sizeof(*frame));
-	/*
-	 * "What about the fp regs?" I hear you ask.... XXXKSE
-	 * Don't know where gs and "onstack" come from.
-	 * May need to fiddle a few other values too.
-	 */
-	return (error);
-}
-
-void
 cpu_wait(p)
 	struct proc *p;
 {

==== //depot/projects/kse/sys/kern/kern_exit.c#60 (text+ko) ====

@@ -204,8 +204,6 @@
 
 	p->p_flag |= P_WEXIT;
 	PROC_UNLOCK(p);
-	if (td->td_kse->ke_mdstorage)
-		cpu_free_kse_mdstorage(td->td_kse);
 
 	/* Are we a task leader? */
 	PROC_LOCK(p);

==== //depot/projects/kse/sys/kern/kern_fork.c#77 (text+ko) ====

@@ -490,8 +490,6 @@
 
 	bcopy(&p1->p_startcopy, &p2->p_startcopy,
 	    (unsigned) RANGEOF(struct proc, p_startcopy, p_endcopy));
-	bcopy(&td->td_kse->ke_startcopy, &ke2->ke_startcopy,
-	    (unsigned) RANGEOF(struct kse, ke_startcopy, ke_endcopy));
 	bcopy(&td->td_startcopy, &td2->td_startcopy,
 	    (unsigned) RANGEOF(struct thread, td_startcopy, td_endcopy));
 	bcopy(&td->td_ksegrp->kg_startcopy, &kg2->kg_startcopy,

==== //depot/projects/kse/sys/kern/kern_proc.c#78 (text+ko) ====

@@ -345,11 +345,7 @@
 	mtx_lock_spin(&sched_lock);
 	mi_switch();	/* Save current registers to PCB. */
 	mtx_unlock_spin(&sched_lock);
-	newkse->ke_upcall = mbx.kmbx_upcall;
-	newkse->ke_stackbase  = mbx.kmbx_stackbase;
-	newkse->ke_stacksize = mbx.kmbx_stacksize;
 	newkse->ke_mailbox = uap->mbx;
-	cpu_save_upcall(td, newkse);
 	/* Note that we are the returning syscall */
 	td->td_retval[0] = 0;
 	td->td_retval[1] = 0;

==== //depot/projects/kse/sys/kern/kern_thread.c#86 (text+ko) ====

@@ -190,6 +190,14 @@
 	allocated_threads--;	/* XXXSMP */
 }
 
+void
+thread_getcontext(struct thread *td, ucontext_t *uc)
+{
+
+	get_mcontext(td, &uc->uc_mcontext);
+	uc->uc_sigmask = td->td_proc->p_sigmask;
+}
+
 int
 thread_setcontext(struct thread *td, ucontext_t *uc)
 {
@@ -283,18 +291,29 @@
 	void *addr1;
 	void *addr2;
 	int error;
+	ucontext_t uc;
 
 #ifdef __ia64__
 	td2_mbx = 0;		/* pacify gcc (!) */
 #endif
-	/* Export the register contents. */
-	error = cpu_export_context(td);
+	/* Export the user/machine context. */
+	error = copyin((caddr_t)td->td_mailbox +
+	    offsetof(struct thread_mailbox, tm_context),
+	    &uc,
+	    sizeof(ucontext_t));
+	if (error == 0) {
+		thread_getcontext(td, &uc);
+		uc.uc_busy = 0;
+		error = copyout(&uc, (caddr_t)td->td_mailbox +
+		offsetof(struct thread_mailbox, tm_context),
+		sizeof(ucontext_t));
+	}
 
 	ke = td->td_kse;
 	addr1 = (caddr_t)ke->ke_mailbox
-			+ offsetof(struct kse_mailbox, kmbx_completed_threads);
+			+ offsetof(struct kse_mailbox, km_completed);
 	addr2 = (caddr_t)td->td_mailbox
-			+ offsetof(struct thread_mailbox , next_completed);
+			+ offsetof(struct thread_mailbox , tm_next);
 	/* Then link it into it's KSE's list of completed threads. */
 	if (!error) {
 		error = td2_mbx = fuword(addr1);
@@ -425,6 +444,8 @@
 thread_schedule_upcall(struct thread *td, struct kse *ke)
 {
 	struct thread *td2;
+	caddr_t ucp;
+	ucontext_t uc;
 
 	mtx_assert(&sched_lock, MA_OWNED);
 	if (ke->ke_tdspare != NULL) {
@@ -438,7 +459,17 @@
 	CTR3(KTR_PROC, "thread_schedule_upcall: thread %p (pid %d, %s)",
 	     td, td->td_proc->p_pid, td->td_proc->p_comm);
 	thread_link(td2, ke->ke_ksegrp);
-	cpu_set_upcall(td2, ke->ke_pcb);
+	ucp = (caddr_t)ke->ke_mailbox +
+	    offsetof(struct kse_mailbox, km_context);
+	copyin(ucp, &uc, sizeof(ucontext_t));
+	/*
+	 * XXX: It is somewhat bogus to ignore the error
+	 * if copyin fails here, but the end result will be
+	 * that the process will crash from bogus state information,
+	 * which is what we want.
+	 */
+	thread_setcontext(td2, &uc);
+	suword(ucp + offsetof(ucontext_t, uc_busy), 1);
 	td2->td_ucred = crhold(td->td_ucred);
 	td2->td_flags = TDF_UNBOUND|TDF_UPCALLING;
 	td2->td_priority = td->td_priority;
@@ -544,6 +575,7 @@
 		if (td->td_flags & TDF_UPCALLING) {
 			CTR3(KTR_PROC, "userret: upcall thread %p (pid %d, %s)",
 			    td, p->p_pid, p->p_comm);
+#if 0
 			/*
 			 * Make sure that it has the correct frame loaded.
 			 * While we know that we are on the same KSEGRP
@@ -569,8 +601,13 @@
 			 */
 			td->td_flags &= ~TDF_UPCALLING;	/* Hmmmm. */
 			error = suword((caddr_t)td->td_kse->ke_mailbox +
-			    offsetof(struct kse_mailbox, kmbx_current_thread),
+			    offsetof(struct kse_mailbox, km_curthread),
 			    0);
+#else
+			/*
+			 * We are returning to the UTS.
+			 */
+#endif
 		}
 		/*
 		 * Stop any chance that we may be separated from

==== //depot/projects/kse/sys/sys/kse.h#16 (text+ko) ====

@@ -9,7 +9,7 @@
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice(s), this list of conditions and the following disclaimer as
- *    the first lines of this file unmodified other than the possible 
+ *    the first lines of this file unmodified other than the possible
  *    addition of one or more copyright notices.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice(s), this list of conditions and the following disclaimer in the
@@ -32,9 +32,11 @@
 
 #ifndef SYS_KSE_H
 #define SYS_KSE_H
+
 #include <machine/kse.h>
 #include <sys/ucontext.h>
-/* 
+
+/*
  * This file defines the structures needed for communication between
  * the userland and the kernel when running a KSE-based threading system.
  * The only programs that should see this file are the UTS and the kernel.
@@ -42,42 +44,34 @@
 struct kse_mailbox;
 typedef void kse_fn_t(struct kse_mailbox *mbx);
 
-/* 
- * Each userland thread has one of these buried in it's 
- * Thread control structure somewhere.
+/*
+ * Thread mailbox.
+ *
+ * This describes a user thread ot the kernel scheduler.
  */
-struct thread_mailbox
-{
-	struct thread_mailbox *next_completed;
-	unsigned int	flags;
-	void		*UTS_handle;	/* The UTS can use this for anything */
-	union kse_td_ctx ctx;		/* thread's saved context goes here. */
+struct thread_mailbox {
+	unsigned int		tm_flags;	/* Thread flags */
+	struct thread_mailbox	*tm_next;	/* Next thread in list */
+	ucontext_t		tm_context;	/* User and machine context */
+	void			*tm_udata;	/* For use by the UTS */
+	int			tm_spare[8];
 };
 
-/* 
- * You need to supply one of these as the argument to the 
- * kse_new() system call.
+/*
+ * KSE mailbox.
+ *
+ * Cummunication path between the UTS and the kernel scheduler specific to
+ * a single KSE.
  */
-struct kse_mailbox 
-{
-	kse_fn_t	*kmbx_upcall;
-	char *kmbx_stackbase;
-	unsigned long int kmbx_stacksize;
-	struct thread_mailbox *kmbx_current_thread;
-	struct thread_mailbox *kmbx_completed_threads;
-	unsigned int	kmbx_flags;
-	void		*kmbx_UTS_handle; /* UTS can use this for anything */
+struct kse_mailbox {
+	unsigned int		km_flags;	/* KSE flags */
+#define KSEKMF_CRITICAL 0x00000001
+	ucontext_t		km_context;	/* UTS context */
+	struct thread_mailbox	*km_curthread;	/* Currently running thread */
+	struct thread_mailbox	*km_completed;	/* Threads back from kernel */
+	sigset_t		km_sigscaught;	/* Caught signals */
+	void			*km_udata;	/* For use by the UTS */
+	int			tm_spare[8];
 };
-#define KEMBXF_CRITICAL 0x00000001
-
-struct kse_global_mailbox
-{
-	unsigned int	flags;
-};
-#define GMBXF_CRITICAL 0x00000001
-
-#ifdef _KERNEL
-int	thread_setcontext(struct thread *td, ucontext_t *uc);
-#endif	/* _KERNEL */
 
 #endif

==== //depot/projects/kse/sys/sys/proc.h#122 (text+ko) ====

@@ -55,6 +55,7 @@
 #else
 #include <sys/pcpu.h>
 #endif
+#include <sys/ucontext.h>
 #include <sys/ucred.h>
 #include <machine/proc.h>		/* Machine-dependent proc substruct. */
 #include <vm/uma.h>
@@ -376,18 +377,7 @@
 	void 		*ke_mailbox;	/* the userland mailbox address */
 	struct thread	*ke_tdspare;	/* spare thread for upcalls */
 #define	ke_endzero ke_dummy
-
-#define	ke_startcopy ke_endzero
-	u_char		ke_dummy;	/*   */
-#define	ke_endcopy ke_mdstorage
-
-	void		*ke_upcall;
-	void		*ke_stackbase;
-	u_long		ke_stacksize;
-	void 		*ke_mdstorage;	/* where we store the pcb and frame */
-	struct pcb	*ke_pcb;	/* the pcb saved for the upcalls */
-	struct trapframe *ke_frame;	/* the upcall trapframe */
-	void	*mdkse;			/* eventually you load from this in */
+	char		ke_dummy;
 					/* switch for our extension PCB x86 */
 };
 /* flags kept in ke_flags */
@@ -845,11 +835,6 @@
 /* New in KSE. */
 struct	thread *thread_alloc(void);
 void	thread_free(struct thread *td);
-int	cpu_export_context(struct thread *td);
-void	cpu_free_kse_mdstorage(struct kse *kse);
-void	cpu_save_upcall(struct thread *td, struct kse *newkse);
-void	cpu_set_args(struct thread *, struct kse *);
-void	cpu_set_upcall(struct thread *td, void *pcb);
 void	cpu_thread_exit(struct thread *);
 void	cpu_thread_setup(struct thread *td);
 void	kse_reassign(struct kse *ke);
@@ -862,6 +847,8 @@
 void	thread_link(struct thread *td, struct ksegrp *kg);
 void	thread_reap(void);
 struct thread *thread_schedule_upcall(struct thread *td, struct kse *ke);
+int	thread_setcontext(struct thread *td, ucontext_t *uc);
+void	thread_getcontext(struct thread *td, ucontext_t *uc);
 int	thread_single(int how);
 #define	SNGLE_NO_EXIT 0			/* values for 'how' */
 #define	SNGLE_EXIT 1

==== //depot/projects/kse/sys/sys/ucontext.h#3 (text+ko) ====

@@ -47,7 +47,8 @@
 
 	struct __ucontext *uc_link;
 	stack_t		uc_stack;
-	int		__spare__[8];
+	int		uc_busy;
+	int		__spare__[6];
 } ucontext_t;
 
 #ifndef _KERNEL

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200208190719.g7J7JJow018343>