From owner-p4-projects Sat Aug 31 15:20:53 2002 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 25BF037B401; Sat, 31 Aug 2002 15:20:11 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6DEFC37B400; Sat, 31 Aug 2002 15:20:10 -0700 (PDT) Received: from sccrmhc01.attbi.com (sccrmhc01.attbi.com [204.127.202.61]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6620C43E4A; Sat, 31 Aug 2002 15:20:09 -0700 (PDT) (envelope-from julian@elischer.org) Received: from InterJet.elischer.org ([12.232.206.8]) by sccrmhc01.attbi.com (InterMail vM.4.01.03.27 201-229-121-127-20010626) with ESMTP id <20020831222008.NAQQ11061.sccrmhc01.attbi.com@InterJet.elischer.org>; Sat, 31 Aug 2002 22:20:08 +0000 Received: from localhost (localhost.elischer.org [127.0.0.1]) by InterJet.elischer.org (8.9.1a/8.9.1) with ESMTP id PAA10643; Sat, 31 Aug 2002 15:02:03 -0700 (PDT) Date: Sat, 31 Aug 2002 15:02:02 -0700 (PDT) From: Julian Elischer To: Jonathan Mini Cc: Perforce Change Reviews Subject: Re: PERFORCE change 16871 for review In-Reply-To: <200208312153.g7VLrYd9023540@freefall.freebsd.org> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG sounds good, but I'd apreciate a 3 or 4 paragraph description of what you are doing as it varies a little from what we discussed.. pitty you aren't in the bay area any more.. A whiteboard would be good... On Sat, 31 Aug 2002, Jonathan Mini wrote: > http://people.freebsd.org/~peter/p4db/chv.cgi?CH=16871 > > Change 16871 by mini@mini_stylus on 2002/08/31 14:53:33 > > - Make ke_mailbox a pointer to the right type, so we can use -> > instead of offsetof() to perform address calculations. > - Add a UCF_CRITICAL flag to denote critical sections in a ucontext. > - Split flags in to options and states, and add the option > UCF_CLEARSTATE to request that setcontext() clear the state flags > when entering the context. > - Change the context-switch method from the UTS to a thread to > mark itself as a critical section, swap into the section, and > unset the critical flag at the last moment before jumping into > the new context's code. > > Now we needn't fear entering the kernel at any time during the > UTS's operation, including swapping contexts. > > Affected files ... > > .. //depot/projects/kse/lib/libc/i386/gen/getcontext.S#5 edit > .. //depot/projects/kse/sys/kern/kern_thread.c#95 edit > .. //depot/projects/kse/sys/sys/proc.h#124 edit > .. //depot/projects/kse/sys/sys/ucontext.h#5 edit > .. //depot/projects/kse/tools/KSE/uts/uts.c#3 edit > > Differences ... > > ==== //depot/projects/kse/lib/libc/i386/gen/getcontext.S#5 (text+ko) ==== > > @@ -40,8 +40,14 @@ > #define MC_FP_REGS_OFFSET 96 /* offset to FP regs from mcontext */ > #define MC_FP_CW_OFFSET 96 /* offset to FP control word */ > #define MC_OWNEDFP_OFFSET 88 /* offset to mc_ownedfp from mcontext */ > -#define UCF_SKIPSIGMASK 0x00000001 /* Don't set/restore signal mask. */ > -#define UCF_OBEYBUSY 0x00000002 /* Respect uc_busy marker. */ > +#define UCF_SKIPSIGMASK 0x00000001 /* Don't set/restore signal mask. */ > +#define UCF_OBEYBUSY 0x00000002 /* Respect uc_busy marker. */ > +#define UCF_CLEARSTATE 0x00000004 /* Clear UCF_STATE in setcontext. */ > +#define UCF_SWAPPED 0x00000100 /* Used by swapcontext(3). */ > +#define UCF_CRITICAL 0x00000200 /* In a critical section. */ > +#define UCF_STATE 0x0000ff00 /* State-related flags. */ > +#define UCF_OPTIONS 0x000000ff /* Behaviour-related flags. */ > + > > /* > * int setcontext(ucontext_t *ucp); > @@ -57,11 +63,11 @@ > cmpl $0, %eax /* check for null pointer */ > jne 1f > movl $-1, %eax > - jmp 7f > + jmp 8f > 1: cmpl $MC_SIZE, UC_MC_LEN_OFFSET(%eax) /* is context valid? */ > je 2f > movl $-1, %eax /* bzzzt, invalid context */ > - jmp 7f > + jmp 8f > 2: testl $UCF_SKIPSIGMASK, UC_FLAGS_OFFSET(%eax) /* Restore sigmask? */ > jnz 3f > PIC_PROLOGUE > @@ -72,7 +78,7 @@ > addl $12, %esp > PIC_EPILOGUE > testl %eax, %eax /* check for error */ > - jnz 7f > + jnz 8f > 3: movl 4(%esp), %edx /* get address of context */ > addl $UC_MC_OFFSET, %edx /* add offset to mcontext */ > movl 4(%edx), %gs > @@ -98,12 +104,15 @@ > movl 44(%edx), %ecx > pushl 68(%edx) /* flags on stack */ > pushl 40(%edx) /* %edx on stack */ > - testl $UCF_OBEYBUSY, MC_FLAGS_OFFSET(%edx) /* set uc_busy? */ > + testl $UCF_CLEARSTATE, MC_FLAGS_OFFSET(%edx) /* clear flag state? */ > jz 6f > + andl $UCF_OPTIONS, MX_FLAGS_OFFSET(%edx) > +6: testl $UCF_OBEYBUSY, MC_FLAGS_OFFSET(%edx) /* set uc_busy? */ > + jz 7f > movl $1, MC_BUSY_OFFSET(%edx) /* set uc_busy */ > -6: popl %edx /* %edx off stack */ > +7: popl %edx /* %edx off stack */ > popf /* flags off stack */ > -7: ret > +8: ret > > /* > * int getcontext(ucontext_t *ucp); > > ==== //depot/projects/kse/sys/kern/kern_thread.c#95 (text+ko) ==== > > @@ -501,6 +501,15 @@ > struct thread *td, struct trapframe *frame) > { > int discard, error; > + struct thread_mailbox *tmp; > + > + /* > + * If we are in a critical section, return to this thread. > + */ > + tmp = (struct thread_mailbox *)fuword(&ke->ke_mailbox->km_curthread); > + if ((tmp != NULL) && > + (fuword(&tmp->tm_context.uc_flags) & UCF_CRITICAL)) > + return (0); > > /* > * Save the thread's context, and link it > @@ -517,7 +526,7 @@ > return (error); > > /* > - * Second, decide whether to perfom an upcall now. > + * Decide whether to perfom an upcall now. > */ > discard = 0; > > @@ -540,9 +549,7 @@ > discard = 1; > > /* Make sure the KSE's UTS context is free for use. */ > - if (fuword((caddr_t)ke->ke_mailbox + > - offsetof(struct kse_mailbox, km_context) + > - offsetof(ucontext_t, uc_busy)) != 0) > + if (fuword(&ke->ke_mailbox->km_context.uc_busy) != 0) > /* > * The KSE's UTS context is currently marked busy. This > * means the UTS is currently running, so switch to it > @@ -597,22 +604,19 @@ > struct thread *td, struct trapframe *frame) > { > int error; > - caddr_t ucp; > ucontext_t uc; > > /* > * Ensure that we have a spare thread available. > */ > - if (ke->ke_tdspare == NULL) { > + if (ke->ke_tdspare == NULL) > ke->ke_tdspare = thread_alloc(); > - } > > /* > * Bound threads need no additional work. > */ > - if ((td->td_flags & TDF_UNBOUND) == 0) { > + if ((td->td_flags & TDF_UNBOUND) == 0) > return (0); > - } > error = 0; > > /* > @@ -639,9 +643,8 @@ > /* > * Fetch the current UTS context from userland. > */ > - ucp = (caddr_t)ke->ke_mailbox + > - offsetof(struct kse_mailbox, km_context); > - error = copyin(ucp, &uc, sizeof(ucontext_t)); > + error = copyin(&ke->ke_mailbox->km_context, &uc, > + sizeof(ucontext_t)); > if (error) > /* > * Failing to do the KSE operation just defaults > @@ -655,8 +658,15 @@ > * > * XXX - Add the busy marker to thread_setcontext(). > */ > - thread_setcontext(td, &uc); > - suword(ucp + offsetof(ucontext_t, uc_busy), (intptr_t)td); > + error = thread_setcontext(td, &uc); > + if (error) > + /* > + * Failing to do the KSE operation just defaults > + * back to synchonous operation, so just return from > + * the syscall. > + */ > + goto cont; > + suword(&ke->ke_mailbox->km_context.uc_busy, (intptr_t)td); > > /* > * Set state and mailbox. > > ==== //depot/projects/kse/sys/sys/proc.h#124 (text+ko) ==== > > @@ -372,7 +372,7 @@ > KES_UNQUEUED, /* in transit */ > KES_THREAD /* slaved to thread state */ > } ke_state; /* (j) S* process status. */ > - void *ke_mailbox; /* the userland mailbox address */ > + struct kse_mailbox *ke_mailbox; /* the userland mailbox address */ > struct thread *ke_tdspare; /* spare thread for upcalls */ > #define ke_endzero ke_dummy > char ke_dummy; > > ==== //depot/projects/kse/sys/sys/ucontext.h#5 (text+ko) ==== > > @@ -51,7 +51,11 @@ > int uc_flags; > #define UCF_SKIPSIGMASK 0x00000001 /* Don't set/restore signal mask. */ > #define UCF_OBEYBUSY 0x00000002 /* Respect uc_busy marker. */ > -#define UCF_SWAPPED 0x00000004 /* Used by swapcontext(3). */ > +#define UCF_CLEARSTATE 0x00000004 /* Clear UCF_STATE in setcontext. */ > +#define UCF_SWAPPED 0x00000100 /* Used by swapcontext(3). */ > +#define UCF_CRITICAL 0x00000200 /* In a critical section. */ > +#define UCF_STATE 0x0000ff00 /* State-related flags. */ > +#define UCF_OPTIONS 0x000000ff /* Behaviour-related flags. */ > int __spare__[4]; > } ucontext_t; > > > ==== //depot/projects/kse/tools/KSE/uts/uts.c#3 (text+ko) ==== > > @@ -23,7 +23,7 @@ > * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > * SUCH DAMAGE. > * > - * $P4: //depot/projects/kse/tools/KSE/uts/uts.c#2 $ > + * $P4: //depot/projects/kse/tools/KSE/uts/uts.c#3 $ > */ > > #include > @@ -287,6 +287,10 @@ > pfmt("-- uts() scheduling 0x%x--\n", p); > pfmt("eip -> 0x%x progress -> %d\n", > p->tm_context.uc_mcontext.mc_eip, progress); > + if ((p->tm_context.uc_flags & UCF_CRITICAL) == 0) > + p->tm_context.uc_flags |= > + UCF_CRITICAL | UCF_CLEARSTATE; > + uts_mb.km_curthread = p; > pstr("curthread set\n"); > ret = myswapcontext(&uts_mb.km_context, &p->tm_context, > p); > @@ -344,7 +348,6 @@ > ret = getcontext(oucp); > if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) { > oucp->uc_flags |= UCF_SWAPPED; > - uts_mb.km_curthread = p; > oucp->uc_busy = 0; > ret = setcontext(ucp); > } > To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message