Re: __wait_event_interruptible question

From: Kasper Dupont (kasperd_at_daimi.au.dk)
Date: 02/22/04

  • Next message: Kasper Dupont: "Re: documentation for vm86()"
    Date: Sun, 22 Feb 2004 11:39:12 +0100
    
    

    Capstar wrote:
    >
    > Hi NG,
    >
    > I got the next macro from sched.h from kernel 2.4.23_pre5.
    >
    > #define __wait_event_interruptible(wq, condition, ret) \
    > do { \
    > wait_queue_t __wait; \
    > init_waitqueue_entry(&__wait, current); \
    > \
    > add_wait_queue(&wq, &__wait); \
    > for (;;) { \
    > set_current_state(TASK_INTERRUPTIBLE); \
    > if (condition) \
    > break; \
    > if (!signal_pending(current)) { \
    > schedule(); \
    > continue; \
    > } \
    > ret = -ERESTARTSYS; \
    > break; \
    > } \
    > current->state = TASK_RUNNING; \
    > remove_wait_queue(&wq, &__wait); \
    > } while (0)
    >
    > This macro is internally used by wait_event_interruptible and is used to
    > wait for a condition to become true without polling it. SO what happens
    > is that the current process is added to a waitq specified in
    > wait_event_interruptible. After that it is set to TASK_INTERRUPTIBLE
    > and, if the condition is not yet met, the process is scheduled.
    >
    > So what worries me a bit is that if the wake_up_interruptible is called
    > from an interrupt service routine, I think it is possible that the
    > process never get woken up.
    > Let me explain. If the interrupt occurs right between the add_wait_queue
    > ad the set_current_state, the state will be set to TASK_RUNNING by
    > wake_up_interruptible in the ISR. Then the isr returns, and the process
    > will be set to TASK_INTERRUPTIBLE. This will usually not be much of a
    > problem, because before schedule() is called, the condition will be
    > tested again. This condition is probably met because that's what caused
    > the interrupt anyway. But what if the process get scheduled by the timer
    > tick or some other interrupt before it could set it's state back to
    > TASK_RUNNING, we have a serious problem. In that case there is no source
    > that will wake up this process anymore.
    >
    > Is this really an issue, or am I missing something,

    I have seen more code like this, so I guess it should
    work. The only reason I can find for the scenario you
    describe not to happen is the fact, that kernel code
    does not get preempted. So the process really cannot
    lose the CPU before it calls schedule(). I don't know
    how it would work with preemption.

    -- 
    Kasper Dupont -- der bruger for meget tid paa usenet.
    For sending spam use mailto:aaarep@daimi.au.dk
    /* Would you like fries with that? */
    

  • Next message: Kasper Dupont: "Re: documentation for vm86()"

    Relevant Pages

    • RE: Maximum frequency of re-scheduling (minimum time quantum) que stio n
      ... >interrupt will also schedule if necessary. ... >>The catch here is, without the preemptable kernel option, the kernel ... Even with the option, it can't preempt ...
      (Linux-Kernel)
    • Re: What is the PREEMPTION option good for?
      ... I found another setup where PREEMPTION help -- nfs servers. ... give correct scheduling of interrupt threads, and that seems to be all ... FULL_PREEMPTION is apparently needed to get kernel threads preempted by ...
      (freebsd-arch)
    • Re: kernel: return from interrupt
      ... why does the kernel refuse to schedule on ... > PREEMPTION turned on in 5.x you should see the same behavior. ... > interrupt handler. ...
      (freebsd-current)
    • Re: How linux schedules things when interrupts occur
      ... kernel deals with scheduling it's work. ... Suppose Linux is running on a single CPU system. ... When an APIC processed hardware interrupt comes and assuming the ... Then schedule is called and it will most likely schedule another process. ...
      (Linux-Kernel)
    • CONFIG_PREEMPT x86 assembly question
      ... Whily lazy-examining kernel code, I found the following interesting point. ... Why, after return from schedule(), first 0 is written to ... the idea of the preempt_count flag is to avoid ... causing nested interrupt while preempt_count flag is already reset. ...
      (Linux-Kernel)