Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 May 2003 14:40:10 +0800
From:      "David Xu" <davidxu@freebsd.org>
To:        "Julian Elischer" <julian@elischer.org>, "Daniel Eischen" <eischen@pcnet1.pcnet.com>
Cc:        threads@freebsd.org
Subject:   Re: kern_threads.c..  upcall question..
Message-ID:  <04ec01c3139a$579093d0$f001a8c0@davidw2k>
References:  <Pine.BSF.4.21.0305051713510.27399-100000@InterJet.elischer.org>

next in thread | previous in thread | raw e-mail | index | archive | help

----- Original Message -----=20
From: "Julian Elischer" <julian@elischer.org>
To: "Daniel Eischen" <eischen@pcnet1.pcnet.com>
Cc: <threads@freebsd.org>
Sent: Tuesday, May 06, 2003 8:39 AM
Subject: Re: kern_threads.c.. upcall question..


>=20
>=20
> On Mon, 5 May 2003, Daniel Eischen wrote:
>=20
> > On Mon, 5 May 2003, Julian Elischer wrote:
> >=20
> > >=20
> > > In kern_threads.c, in function thread_export_context()
> > > it first does a copyin() of the
> > > context storage area. I think this is un-needed (and a complete =
waste of
> > > cycles) but I am not sure if there is some strange condition
> > > regarding floating point registers or something that may want =
this..
> > >=20
> > > Dan, Jon, David?
> > > do any of you have a good reason why I shouldn't remove the =
copyin().??
> >=20
> > Yeah, the threads library keeps the thread's active signal
> > mask in the context area.  The stack and flags may also
> > be used in the context.
> >=20
> > You should be able to safely copy out the mcontext without
> > a copyin().  Is that what you're currently doing?  Or is
> > the entire context (ucontext) being exported?
>=20
> it does:
>=20
> *) copyin the ucontext_t
>=20
> *) load context into it using thread_getcontext() which uses
>   get_mcontext() and adds the kernel thread sigmask (this must have
>   been added by jeff in some way) (note it doesn't OR, just writes)
>=20
> *) copyout of the ucontext_t
>=20
> The ucontext is:
>=20
>         sigset_t        uc_sigmask;   <-- gets over-written (!)
>         mcontext_t      uc_mcontext;  <-- gets over-written
>         struct __ucontext *uc_link;   <-- one in userland MAY be
> valuable
>         stack_t         uc_stack;     <-- probably worth saving..
>         int             uc_flags;     <-- probably worth saving
>         int             __spare__[4];
>=20
>=20
>=20
>=20
> It seems to me that just copying out the sigset_t and mcontext_t
> may be all that is needed. (and I'm not so sure about the sigset_t
> at that..
>=20
>=20
> >=20
> > --=20
> > Dan Eischen
> >=20
> >=20

I think the following patch is enough:

Index: kern_thread.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/kern/kern_thread.c,v
retrieving revision 1.129
diff -u -r1.129 kern_thread.c
--- kern_thread.c 1 May 2003 12:16:06 -0000 1.129
+++ kern_thread.c 6 May 2003 06:32:10 -0000
@@ -721,41 +721,6 @@
 }
=20
 /*
- * Fill a ucontext_t with a thread's context information.
- *
- * This is an analogue to getcontext(3).
- */
-void
-thread_getcontext(struct thread *td, ucontext_t *uc)
-{
-
- get_mcontext(td, &uc->uc_mcontext, 0);
- PROC_LOCK(td->td_proc);
- uc->uc_sigmask =3D td->td_sigmask;
- PROC_UNLOCK(td->td_proc);
-}
-
-/*
- * Set a thread's context from a ucontext_t.
- *
- * This is an analogue to setcontext(3).
- */
-int
-thread_setcontext(struct thread *td, ucontext_t *uc)
-{
- int ret;
-
- ret =3D set_mcontext(td, &uc->uc_mcontext);
- if (ret =3D=3D 0) {
-  SIG_CANTMASK(uc->uc_sigmask);
-  PROC_LOCK(td->td_proc);
-  td->td_sigmask =3D uc->uc_sigmask;
-  PROC_UNLOCK(td->td_proc);
- }
- return (ret);
-}
-
-/*
  * Initialize global thread allocation resources.
  */
 void
@@ -962,27 +927,25 @@
  uintptr_t mbx;
  void *addr;
  int error,temp;
- ucontext_t uc;
+ mcontext_t mc;
=20
  p =3D td->td_proc;
  kg =3D td->td_ksegrp;
=20
  /* Export the user/machine context. */
- addr =3D (void *)(&td->td_mailbox->tm_context);
- error =3D copyin(addr, &uc, sizeof(ucontext_t));
- if (error)=20
-  goto bad;
-
- thread_getcontext(td, &uc);
- error =3D copyout(&uc, addr, sizeof(ucontext_t));
- if (error)=20
+ get_mcontext(td, &mc, 0);
+ addr =3D (void *)(&td->td_mailbox->tm_context.uc_mcontext);
+ error =3D copyout(&mc, addr, sizeof(mcontext_t));
+ if (error)
   goto bad;
=20
  /* Exports clock ticks in kernel mode */
  addr =3D (caddr_t)(&td->td_mailbox->tm_sticks);
  temp =3D fuword(addr) + td->td_usticks;
- if (suword(addr, temp))
+ if (suword(addr, temp)) {
+  error =3D EFAULT;
   goto bad;
+ }
=20
  /* Get address in latest mbox of list pointer */
  addr =3D (void *)(&td->td_mailbox->tm_next);


And should we disable single threading testing or do
double checking in thread_user_enter()? I think per-syscall
PROC_LOCK is too expensive for us.

David Xu




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?04ec01c3139a$579093d0$f001a8c0>