RE: userret() , ast() and the end of syscalls

2002-07-10 Thread John Baldwin


On 09-Jul-2002 Julian Elischer wrote:
 
 
 On Wed, 10 Jul 2002, Bruce Evans wrote:
 Can these flags be changed asynchronously?  If so, then everything needs
 to be handled by ast() anyway.  userret() should only check for work that
 needs doing in the usual case, and hopefully there is none (except for
 things like ktrace).
 
 That's an interestign way of thinking about it..
 in that case, shouldn't ast() be called from within userret()
 instead of the other way around?
 
 userret() is called unconditionally from both trap() and syscall()
 (or just trap() on architectures where syscall() is called by trap())
 
 
 if teh tast thing userret() did was to check if ast() should be called
 and to call it, it might simplify things..
 also, should userret() then loop back to it's start if trap is called?
 It would need to, to simulate what it is doing now..

The test you refer to is done in MD code because ensuring atomicity involves
doing MD things like disabling interrupts.  It really works quite well the
way it is atm.

-- 

John Baldwin [EMAIL PROTECTED]http://www.FreeBSD.org/~jhb/
Power Users Use the Power to Serve!  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



RE: userret() , ast() and the end of syscalls

2002-07-10 Thread Bruce Evans

On Wed, 10 Jul 2002, John Baldwin wrote:

 On 09-Jul-2002 Julian Elischer wrote:
  On Wed, 10 Jul 2002, Bruce Evans wrote:
  Can these flags be changed asynchronously?  If so, then everything needs
  to be handled by ast() anyway.  userret() should only check for work that
  needs doing in the usual case, and hopefully there is none (except for
  things like ktrace).
 
  That's an interestign way of thinking about it..

I think of ast() as the real userret().  Splitting them is an
implementation detail.  The real userret() has to be very close to the
return to user mode, since the return needs to be atomic with checking
for things that need to be done before return, so you need fairly
strong locking and don't want to hold the lock for very long.

  in that case, shouldn't ast() be called from within userret()
  instead of the other way around?

No; that would pessimize userret() and break ast().  ast() is the real
userret() so i needs to do more.

  userret() is called unconditionally from both trap() and syscall()
  (or just trap() on architectures where syscall() is called by trap())
 
  if teh tast thing userret() did was to check if ast() should be called
  and to call it, it might simplify things..
  also, should userret() then loop back to it's start if trap is called?
  It would need to, to simulate what it is doing now..

 The test you refer to is done in MD code because ensuring atomicity involves
 doing MD things like disabling interrupts.  It really works quite well the
 way it is atm.

John moved the loop into ast() where it is easier to understand, but Matt
made him move it back.

There would be little point in userret() repeating the loop, since it has
to open up a race window on return and then it would miss state changes.
These should be seen later by ast().

Bruce


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



userret() , ast() and the end of syscalls

2002-07-09 Thread Julian Elischer


A question to those who know..

why is userret() called both at the end of trap() or syscall()
and also almost immediatly again (often) at the end of ast().

It seems that really there is no one place that one can put code that will
be called ONCE and ONLY ONCE as a thread progresses to userland.

There is no one place where you can say after this point we are in
userland right up until that iret instruction. There is always the danger
that FTER ny insruction that decides that we are now definitly going to
user space, there could occur an interrupt that causes a reschedule so
that some OTHER thread goes to user land.

Is it possible to clear interrupts and have the iret instruction
itself re-enable them?
(that would give a few instructions 'atomically' with the iret
which may be all I need).

is this possible in other architectures?



To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: userret() , ast() and the end of syscalls

2002-07-09 Thread David Xu

I found the problem two weeks ago,  but I can not find a better way to
avoid userret() to be called twice. so I keep silence. :(

David Xu

Gartner: Apache is vulnerable, we recommend switching back to IIS to protect yourselves
- Original Message - 
From: Julian Elischer [EMAIL PROTECTED]
To: FreeBSD current users [EMAIL PROTECTED]
Sent: Tuesday, July 09, 2002 2:40 PM
Subject: userret() , ast() and the end of syscalls


 
 A question to those who know..
 
 why is userret() called both at the end of trap() or syscall()
 and also almost immediatly again (often) at the end of ast().
 
 It seems that really there is no one place that one can put code that will
 be called ONCE and ONLY ONCE as a thread progresses to userland.
 
 There is no one place where you can say after this point we are in
 userland right up until that iret instruction. There is always the danger
 that FTER ny insruction that decides that we are now definitly going to
 user space, there could occur an interrupt that causes a reschedule so
 that some OTHER thread goes to user land.
 
 Is it possible to clear interrupts and have the iret instruction
 itself re-enable them?
 (that would give a few instructions 'atomically' with the iret
 which may be all I need).
 
 is this possible in other architectures?
 
 
 
 To Unsubscribe: send mail to [EMAIL PROTECTED]
 with unsubscribe freebsd-current in the body of the message


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



RE: userret() , ast() and the end of syscalls

2002-07-09 Thread John Baldwin


On 09-Jul-2002 Julian Elischer wrote:
 
 A question to those who know..
 
 why is userret() called both at the end of trap() or syscall()
 and also almost immediatly again (often) at the end of ast().

ast() is really a special form of a trap that is triggered by doing
a last-minute type check on return to userland to see if we still
have work to do.

 It seems that really there is no one place that one can put code that will
 be called ONCE and ONLY ONCE as a thread progresses to userland.

Sure there is.  When you want an action done, set a thread flag marking
the request and set TDF_ASTPENDING.  Then handle it in ast() if the flag
is set.

 There is no one place where you can say after this point we are in
 userland right up until that iret instruction. There is always the danger
 that FTER ny insruction that decides that we are now definitly going to
 user space, there could occur an interrupt that causes a reschedule so
 that some OTHER thread goes to user land.
 
 Is it possible to clear interrupts and have the iret instruction
 itself re-enable them?
 (that would give a few instructions 'atomically' with the iret
 which may be all I need).

Remember how ast() used to do a critical_enter() before it grabbed
sched_lock to check flags and dropped the critical section while
handling the flags?  This is exactly what you have asked for above.
The loop and the critical sections then got pushed back into the MD
code but still work the same.

 is this possible in other architectures?

It already works that way on all architectures.

-- 

John Baldwin [EMAIL PROTECTED]http://www.FreeBSD.org/~jhb/
Power Users Use the Power to Serve!  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: userret() , ast() and the end of syscalls

2002-07-09 Thread John Baldwin


On 09-Jul-2002 David Xu wrote:
 I found the problem two weeks ago,  but I can not find a better way to
 avoid userret() to be called twice. so I keep silence. :(

It is only called twice if an AST is posted.  It is _not_ always called
twice.

-- 

John Baldwin [EMAIL PROTECTED]http://www.FreeBSD.org/~jhb/
Power Users Use the Power to Serve!  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



RE: userret() , ast() and the end of syscalls

2002-07-09 Thread John Baldwin


On 09-Jul-2002 John Baldwin wrote:
 
 On 09-Jul-2002 Julian Elischer wrote:
 
 A question to those who know..
 
 why is userret() called both at the end of trap() or syscall()
 and also almost immediatly again (often) at the end of ast().
 
 ast() is really a special form of a trap that is triggered by doing
 a last-minute type check on return to userland to see if we still
 have work to do.
 
 It seems that really there is no one place that one can put code that will
 be called ONCE and ONLY ONCE as a thread progresses to userland.
 
 Sure there is.  When you want an action done, set a thread flag marking
 the request and set TDF_ASTPENDING.  Then handle it in ast() if the flag
 is set.

Or, if this needs to happen on every return and not conditionally,
then do it in userret() and use the state of a variable or some flag
to note when you've already done it.

-- 

John Baldwin [EMAIL PROTECTED]http://www.FreeBSD.org/~jhb/
Power Users Use the Power to Serve!  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: userret() , ast() and the end of syscalls

2002-07-09 Thread David Xu


- Original Message - 
From: John Baldwin [EMAIL PROTECTED]
To: John Baldwin [EMAIL PROTECTED]
Cc: FreeBSD current users [EMAIL PROTECTED]; FreeBSD current users
[EMAIL PROTECTED]; Julian Elischer [EMAIL PROTECTED]
Sent: Tuesday, July 09, 2002 8:40 PM
Subject: RE: userret() , ast() and the end of syscalls


 
 On 09-Jul-2002 John Baldwin wrote:
  
  On 09-Jul-2002 Julian Elischer wrote:
  
  A question to those who know..
  
  why is userret() called both at the end of trap() or syscall()
  and also almost immediatly again (often) at the end of ast().
  
  ast() is really a special form of a trap that is triggered by doing
  a last-minute type check on return to userland to see if we still
  have work to do.
  
  It seems that really there is no one place that one can put code that will
  be called ONCE and ONLY ONCE as a thread progresses to userland.
  
  Sure there is.  When you want an action done, set a thread flag marking
  the request and set TDF_ASTPENDING.  Then handle it in ast() if the flag
  is set.
 
 Or, if this needs to happen on every return and not conditionally,
 then do it in userret() and use the state of a variable or some flag
 to note when you've already done it.
 
 -- 
 
 John Baldwin [EMAIL PROTECTED]http://www.FreeBSD.org/~jhb/
 Power Users Use the Power to Serve!  -  http://www.FreeBSD.org/

hope this won't increase per-thread memory requirement, I would like
to create more threads using same memory size. :)

David Xu


__
Do You Yahoo!?
Sign up for SBC Yahoo! Dial - First Month Free
http://sbc.yahoo.com

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



RE: userret() , ast() and the end of syscalls

2002-07-09 Thread Bruce Evans

On Tue, 9 Jul 2002, John Baldwin wrote:

 On 09-Jul-2002 John Baldwin wrote:
 
  On 09-Jul-2002 Julian Elischer wrote:
 
  A question to those who know..
 
  why is userret() called both at the end of trap() or syscall()
  and also almost immediatly again (often) at the end of ast().
 
  ast() is really a special form of a trap that is triggered by doing
  a last-minute type check on return to userland to see if we still
  have work to do.
 
  It seems that really there is no one place that one can put code that will
  be called ONCE and ONLY ONCE as a thread progresses to userland.
 
  Sure there is.  When you want an action done, set a thread flag marking
  the request and set TDF_ASTPENDING.  Then handle it in ast() if the flag
  is set.

 Or, if this needs to happen on every return and not conditionally,
 then do it in userret() and use the state of a variable or some flag
 to note when you've already done it.

Hopefully there won't be any unconditional code.  Unconditional code
in userret() pessimizes all syscalls.  Unconditional code added by KSEIII
pessimized basic syscall overhead by 10% according to lmbench2.

Bruce


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



RE: userret() , ast() and the end of syscalls

2002-07-09 Thread Julian Elischer



On Wed, 10 Jul 2002, Bruce Evans wrote:

 Hopefully there won't be any unconditional code.  Unconditional code
 in userret() pessimizes all syscalls.  Unconditional code added by KSEIII
 pessimized basic syscall overhead by 10% according to lmbench2.

Mostly it's conditional..
if (p-p_flag  P_KSES) 
in syscall()
and 
if (p-p_flag  P_KSES) {
in userret()

it's probably  
PROC_LOCK(p);
thread_suspend_check(0);/* Can suspend or kill */
PROC_UNLOCK(p);


try replace it with:
if (P_SHOULDSTOP(p) {
PROC_LOCK(p);
thread_suspend_check(0);/* Can suspend or kill */
PROC_UNLOCK(p);
}

 
 Bruce
 
 


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



RE: userret() , ast() and the end of syscalls

2002-07-09 Thread Julian Elischer



On Wed, 10 Jul 2002, Bruce Evans wrote:

 On Tue, 9 Jul 2002, Julian Elischer wrote:
 
  On Wed, 10 Jul 2002, Bruce Evans wrote:
 
   Hopefully there won't be any unconditional code.  Unconditional code
   in userret() pessimizes all syscalls.  Unconditional code added by KSEIII
   pessimized basic syscall overhead by 10% according to lmbench2.
 
  Mostly it's conditional..
  if (p-p_flag  P_KSES)
  in syscall()
  and
  if (p-p_flag  P_KSES) {
  in userret()
 
 The conditionals are unconditional, and together with the proc locking)
 (mainly the locking) are what gives the 10% pessimization.  It would be
 much more than 10% to actually do something :).
 
  it's probably
  PROC_LOCK(p);
  thread_suspend_check(0);/* Can suspend or kill */
  PROC_UNLOCK(p);
 
 
  try replace it with:
  if (P_SHOULDSTOP(p) {
  PROC_LOCK(p);
  thread_suspend_check(0);/* Can suspend or kill */
  PROC_UNLOCK(p);
  }
 
 Can these flags be changed asynchronously?  If so, then everything needs
 to be handled by ast() anyway.  userret() should only check for work that
 needs doing in the usual case, and hopefully there is none (except for
 things like ktrace).

That (use ast) is a sensible suggestion. I guess it belongs 
with the postsig in ast().
I can try that..  though it ;ll take a little work
in the mean time try the patch above with lmbench..


 
 Bruce
 
 


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



RE: userret() , ast() and the end of syscalls

2002-07-09 Thread Julian Elischer



On Wed, 10 Jul 2002, Bruce Evans wrote:
 Can these flags be changed asynchronously?  If so, then everything needs
 to be handled by ast() anyway.  userret() should only check for work that
 needs doing in the usual case, and hopefully there is none (except for
 things like ktrace).

That's an interestign way of thinking about it..
in that case, shouldn't ast() be called from within userret()
instead of the other way around?

userret() is called unconditionally from both trap() and syscall()
(or just trap() on architectures where syscall() is called by trap())


if teh tast thing userret() did was to check if ast() should be called
and to call it, it might simplify things..
also, should userret() then loop back to it's start if trap is called?
It would need to, to simulate what it is doing now..

now:

userret()
|
|
|
v
doreti() ? --ast()--userret()
|
|
|
v
userland


maybe:
userret() ? --ast()
(maybe loop back to top of userret)
|
|
|
v
doreti()
|
|
|
v
userland

One other question?
why is userret called again if ast() is called?
It seems about the only thing left in it is the profiling flags.
(under normal conditions)



To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message