scheduling problem...

From: Badrinath Venkatachari (badri@cs.wpi.edu)
Date: Sat Apr 01 2000 - 12:47:50 EST


Hi,
 I am trying to capture read requests in the kernel, make the requesting
process sleep and schedule them using a timer driven function (separate
from the context of the process trying to read) and wake up the process
that issued the request in the first place . For this purpose, I have a
structure (struct reqNode) that can encapsulate a request (major, rw, bh)
and also has a wait queue (reqNode->wq) to hold the context of the process
going to sleep to wake-up when the bufferhead is filled at a later time.
(I have done this to maintain a 1-1 correpondence between a reqNode
created to be Qed and the process that it must wake_up at a later time
when the reqNode has been scheduled and the buffer_head has been filled).

 So what I do is capture a read request, assign all parameters to the ones
in the structure (reqNode) and make the current line of execution do an
interruptible_sleep_on(&reqNode->wq); This I hoped would put the current
process (say pr) onto the wait_queue of rn->wq). The timer driven function
to deQ the requests (stored as reqNode s) and schedule them periodically
is started off by setting a flag in the kernel at a just before I want the
requests to start getting queued. The timer function deQs the reqNode,
issues make_request and then issues a wake_up_interruptible on that very
reqNode's wait_queue so that the process (say pr) and only one I hope)
gets woken up and returns the buffer_head read back to read().

 However, this scheme does not work at all. The kernel just starts
reporting a lot of errors (general protection, and lot others and after
sometime hangs). I even tried using sleep_on and wake_up since I saw that
when using interruptible_sleep_on the code calls schedule and tries to
wake_up the sleeping process.

 Can anyone pls. tell me what are the (huge) mistakes I am making
?? Snipped code pasted below....

thanks in advance

badri

-- code ---

/* this fn replaces make_request in ll_rw_block for reads alone*/
schedule_req(int major, int rw, buffer_head *bh)
{
  reqNode *rn;
  if (start_qing)
  {
     rn = (reqNode *) kmalloc(sizeof(reqNode), GFP_ATOMIC);
     rn->major = major; rn->rw = rw; rn->bh = bh;
     rn->wq = NULL;
     down(&semQ);
     addtoQ(rn);
     up(&semQ);
     interruptible_sleep_on(&rn->wq); /* or sleep_on(&rn->wq) */
     return; /* bh valid when woken up using rn->wq so can return */
  }
  else
     make_request(major, rw, bh);
}

/* timer function */

issue_req()
{
  reqNode *rn;
  /*initialize timer to call itself again after sometime */

  for (i = 0 ; i < 5; i++)
  {
    /* issue 5 requests every period */
    down(&semQ);
    deQ(&rn);
    up(&semQ);
    make_request(rn->major, rn->rw, rn->bh);
    wake_up_interruptible(&rn->wq); /* or wake_up((&rn->wq); */
  }
}

I am assuming that once a process is put on the wait_queue of the node it
created before going to sleep and the timer function uses that very
request node's wait_queue to wake the process there should not be any
problems with wake ups and everything should run normally....but obviously
I am missing a bit point...and there are probably timing constraints for
other system processes ????

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Apr 07 2000 - 21:00:07 EST