Muli Ben-Yehuda wrote:
Trace; d0ee7f7f <[i810_audio]drain_dac+8f/140>
Trace; d0eea0d1 <[i810_audio]i810_release+21/b0>
    

But this is relevant probably. Looks like for some reason, drain_dac()
is not finishing properly. We even know at which point it's possibly
stuck.
Yes. Catch point marked in code snippet at the end of this message. Note that it survived the spinlock. And this specific code piece remains intact as of 2.6.0-test4.

This little discussion still hasn't answered my first, and most interesting question: How can a process be running, and yet not killable. I mean, as of 2.4, if it's stuck in the middle of a system call, within the kernel, I would expect the system to freeeze (with no oops). But if context is switched every now and then, I would expect the OS to check for signals. After all, it's not the process that volunteers to kill itself. It's the system that kills it.

Obviously, I got something wrong here. Who will correct me?

Another thing that makes me wonder, is that according to the source, there's a recurring check for pending signals. But since this code is run under the graces of kernel_lock() (in i810_release(), which calls the drain_dac), I wonder if this is not related to the problem.

   Eli

(Code snippet from i810_audio.c follows)

    for (;;) {

        spin_lock_irqsave(&state->card->lock, flags);
        i810_update_ptr(state); <----------------- This is where it was caught! ---------------
        count = dmabuf->count;
        spin_unlock_irqrestore(&state->card->lock, flags);

        if (count <= 0)
            break;

        /*
         * This will make sure that our LVI is correct, that our
         * pointer is updated, and that the DAC is running.  We
         * have to force the setting of dmabuf->trigger to avoid
         * any possible deadlocks.
         */
        if(!dmabuf->enable) {
            dmabuf->trigger = PCM_ENABLE_OUTPUT;
            i810_update_lvi(state,0);
        }
                if (signal_pending(current) && signals_allowed) {
                        break;
                }

        /* It seems that we have to set the current state to
         * TASK_INTERRUPTIBLE every time to make the process
         * really go to sleep.  This also has to be *after* the
         * update_ptr() call because update_ptr is likely to
         * do a wake_up() which will unset this before we ever
         * try to sleep, resuling in a tight loop in this code
         * instead of actually sleeping and waiting for an
         * interrupt to wake us up!
         */
        set_current_state(TASK_INTERRUPTIBLE);
        /*
         * set the timeout to significantly longer than it *should*
         * take for the DAC to drain the DMA buffer
         */
        tmo = (count * HZ) / (dmabuf->rate);
        if (!schedule_timeout(tmo >= 2 ? tmo : 2)){
            printk(KERN_ERR "i810_audio: drain_dac, dma timeout?\n");
            count = 0;
            break;
        }
    }


-- 
Web: http://www.billauer.co.il




Reply via email to