On Sun, Nov 02, 2008 at 09:55:16PM -0800, Roman Shaposhnik wrote:
> Guys,
>
> when somebody tries to stop a process that is waiting for the IO the  
> process
> doesn't get transferred to a Stopped state immediately but only when
> the scheduler sees it for the first time. This leads to a process  
> writing to
> a /proc/n/ctl being put in a Stopwait state which is a bit inconvenient.
>
> Is there any way I can poke the target process so that it gets attention
> from the scheduler an can be put in a Stopped state?
>
> Thanks,
> Roman.

Thinking aloud, and looking mostly at the port/ and pc/ code:

port/devproc.c:/^procstopwait will be called when we write "stop" into
/proc/n/ctl.  Modulo details, this function will:
  qlock p->debug
  mark us as p's debugger
  set p->procctl to Proc_stopme
  drop p->debug
  wait until p->state == Stopped by using procstopped()
  return

If a process is stopped on I/O, that wait is going to take "a while" (until
I/O completes).  Eventually, however, it will return into
pc/trap.c:/^syscall and will eventually run the code:

>  if(scallnr!=RFORK && (up->procctl || up->nnote)){
>          splhi();
>          notify(ureg);
>  }

whereupon we expect [1] that it sees that up->procctl is nonzero and the
process will put itself to sleep inside notify(), awake the waiter above,
and everything will be fine.

So it seems like it wouldn't be very hard to define a "soonstop" command
which considered processes blocked on I/O "as good as stopped" since there
are two outcomes:
  After we set up->procctl, the target process returned to userland and will
  sleep on the next trap they take or syscall they make.  In this case, we
  should set ourselves as p's debugger and wait as we have a bounded wait:
  exactly one time quantum at most.

  After we set up->procctl, the process is still blocked (or blocked again)
  on I/O.  They will not make it back to userland after this I/O completes.
  In this case, we do not need to register ourselves as p's debugger and
  may immediately return.

Subject to appropriate fencing (if required, I'm not sure; sim. [1]) it
seems that we can distinguish these cases in the requesting process.

User memory and registers (probably just the return register, tho') would be
subject to change by the kernel during the period where the process is
asleep, but this is not too dissimilar from the state of the world when
shared memory is in flight.

Would this suffice?  Did I miss something obvious?
--nwf;

[1] It may be necessary to insert a memory fence after the setting of
    p->procctl or before the read of up->procctl, since several places
    do not acquire up->debug before reading up->procctl.  Can somebody
    comment?

Attachment: pgpFEoVHZMQkk.pgp
Description: PGP signature

Reply via email to