Tasklet rescheduling: within tasklet forcing an rescheduling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all,
I've a little problem within linux2.4.2 in a driver for a pci-module.
A testprogram (userspace) is running slowly in a system with low load
but it is running fast in a system with heavy load.

following structure:

isr_handler(); // handle the real interrupt
tasklet tuser;  // to do jobs for user;
tasklet tbh; // as bottom-half for isr_handler()

tasklets tx1,tx2,tx3; //some_other_tasklets.

user-space: ioctl-call

------------------within kernel------------
user-context: from ioctl
dispatch_start_io_job_and_sleep(job_dsc_t *io) {

    init_waitqueue_head(&io->wq); // init for sleeping

     spin_lock_bh(&jobs_p->ios_lock); //insert into joblist
     list_add_tail(&io->job_in_queue, &jobs_p->jobs_req);
     spin_unlock_bh(&jobs_p->ios_lock);

     tasklet_hi_schedule(&tuser);
     interruptible_sleep_on(&io->wq); //
     if (signal_pending (current)) { /* a signal arrived */
          return -ERESTARTSYS;
    }
}

------------tasklets -------------------
tasklet_for_user_routine (void) {
 ..
 if (dma_transfer_done) {
   job_dsc_t *io=... //get job_info
     wake_up_interruptible(&io->wq); /* wake Process */
 }

 if (new_userjob_exists) {
   start_dma_over_pci(); // start job and wait to be woken up;
 }
 ..
}


void isr_hander(..) {
  .. //store some information in ringbuffer
  tasklet_hi_schedule(&tbh);
  ..
}

tasklet_bh_routine(void) {
  int determine_tasklet_to_wake_up=...;
  ..
  switch (determine_tasklet_to_wake_up) {
  case t_tuser:
    tasklet_hi_schedule(&tuser);
    break;
  case ...:
    tasklet_hi_schedule(&tx..);
    break;
  }
  ..
}


Now my problem:
if i am calling the main() with ioctl's in a big loop and there is NO load on my
system my main-routine is slow, but it works.

But if there is heavy load on my system, my main-program is much more faster.

Question:
1) Where is my mistake?
2) In my opinion the scheduler reschedules after the HW-interrupt and all
handled
   soft-IRQs e.g. all tasklets are finished.
   But in this Context my process must be woken up.
3) Which Solutions exist?
   -Force rescheduling from tasklet-context after
     callingwake_up_interruptible()
   -???





--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
IRC Channel:   irc.openprojects.net / #kernelnewbies
Web Page:      http://www.kernelnewbies.org/



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux