bottom halves queued but not called

From: Sebastien Rougeaux (Sebastien.Rougeaux@syseng.anu.edu.au)
Date: Sat Jun 10 2000 - 01:26:40 EST


I am the maintainer of the firewire ohci driver in the 2.3.x kernel,
and I am experiencing some problems with bottom halves queued in the
irq handler, but sometimes not called. I am not a linux kernel guru so I
guess I am doing something wrong, but I can't spot the error.

Here is an edited sample of the irq_handler:

static void ohci_irq_handler(int irq, void *dev_id,
                             struct pt_regs *regs_are_unused)
{
        quadlet_t event;
        struct ti_ohci *ohci = (struct ti_ohci *)dev_id;

        /* read the interrupt event register */
        event=reg_read(ohci, OHCI1394_IntEventClear);

        /* clear the interrupt event register */
        reg_write(ohci, OHCI1394_IntEventClear, event);

        if (event & OHCI1394_RQPkt) {
                struct dma_rcv_ctx *d = ohci->ar_req_context;
                queue_task(&d->task, &tq_immediate);
                mark_bh(IMMEDIATE_BH);
        }
        if (event & OHCI1394_RSPkt) {
                struct dma_rcv_ctx *d = ohci->ar_resp_context;
                queue_task(&d->task, &tq_immediate);
                mark_bh(IMMEDIATE_BH);
        }
        if (event & OHCI1394_isochRx) {
                struct dma_rcv_ctx *d = ohci->ir_context;
                queue_task(&d->task, &tq_immediate);
                mark_bh(IMMEDIATE_BH);
        }
}

the variable d->task is initialized as:

        /* initialize bottom half handler */
        d->task.sync = 0;
        d->task.next = NULL;
        d->task.routine = dma_rcv_bh;
        d->task.data = (void*)d;

Here is an edited sample of the bottom-half:

/* Bottom half that processes dma receive buffers */
static void dma_rcv_bh(void *data)
{
        struct dma_rcv_ctx *d = (struct dma_rcv_ctx*)data;
        struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);
        int bytes_left,rescount,offset,idx;

        spin_lock(&d->lock);

        idx = d->buf_ind;
        rescount = d->prg[idx]->status&0xffff;
        bytes_left = d->buf_size - rescount - offset;

        while (bytes_left>0) {
              ...
        }
        spin_unlock(&d->lock);
}

Using debug messages, I can see that the bottom halves are always queued
when the appropriate event is received, but sometimes not called afterwards.
Is there something obviously wrong in the piece of code shown below, or
shall I dig deeper into the rest of the code to look for the cause
of the problem ? If you want more detail of the code, it can be found
in the 2.3.x tree in driver/ieee1394/ohci1394.c

Thanks for any help, and please CC your answer to:
sebastien.rougeaux@syseng.anu.edu.au

-- 
Sebastien Rougeaux
RSISE, The Australian National University

- 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 : Thu Jun 15 2000 - 21:00:20 EST