Hallo zusammen,

ich schreibe gerade einen Treiber für ein embedded-System (Linux-Version 2.6.16.11-rt18). Mein Problem ist, dass sich der schlafende Thread nicht mehr aufwecken lässt.

Hier ein kleiner Ausschnitt des Codes:
Code:
u8 u8tmp = 0;   //that wake_up isn't called before sleeping
u8 condition = 0; //...for wait_event_interruptible()

struct dd_private_t {
   (...)
   pid_t thr_pid;
   wait_queue_head_t thr_wait;
   (...)
}

static int dd_open(struct net_device* dev)
{
   (...)
   int result;
   result = request_irq(dev->irq, my_irq_handler, SA_INTERRUPT|SA_SHIRQ, dev->name, dev);
   if(result)
      printk("can't get assign IRQ\n");
   (...)
}

static int dd_start(struct net_device *dev)
{
   struct dd_private_t* priv = (struct dd_private_t*)dev->priv;
   (...)
   init_waitqueue_head(&priv->thr_wait);
   priv->thr_pid = kernel_thread(dd_thread, dev, CLONE_FS|CLONE_FILES);
   (...)
}

irqreturn_t my_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
   struct net_device *dev = dev_id;
   struct dd_private_t *priv = (struct dd_private_t*)dev->priv;

   if(u8tmp) {
      condition = 1;
      wake_up_interruptible(&priv->thr_wait);
      return IRQ_HANDLED;
   }
   return IRQ_NONE;
}

static int dd_thread(void* data)
{
   struct net_device* dev = data;
   struct dd_private_t* priv = (struct dd_private_t*)dev->priv;
   int tmpVal;

   daemonize("%s", dev->name);
   allow_signal(SIGTERM);

   while(1) {
      u8tmp = 1; //now you can try to wake up...
      tmpVal = wait_event_interruptible(priv->thr_wait, condition);
      printk("juhuu! - woke up\n");
      (...)
}
Ich bin mir sicher, dass die Funktion wake_up_interruptible aus der ISR aufgerufen wird. (Festgestellt durch printk's in der Zeile drüber und drunter), aber der Thread will irgendwie nicht aufwachen (Keine "juhuu!"-Ausgabe zu sehen.

Fehlt noch irgendwas in dem Code, bzw. muss noch irgendwas früher oder später aufgerufen werden?
Mir kommt's irgendwie so vor, als ob der schlafende Prozess nicht gefunden wird.

Ich hab auch die Funktion interruptible_sleep_on() ausprobiert, bekomme dann aber einen Kernel-Oops:

Code:
BUG: scheduling with  irqs disabled: eth1/0x00000000/746
caller is interruptible_sleep_on+0x58/0xa4
Call Trace:
[C7803F40] [C000B98C] show_stack+0x40/0x194 (unreliable)
[C7803F70] [C0210A18] schedule+0xd8/0x110
[C7803F80] [C0210F6C] interruptible_sleep_on+0x58/0xa4
...
für jegliche Tipps wäre ich sehr dankbar!

Beste Grüße von hier aus!

a.ti