Commit 9295311d authored by Federico Vaga's avatar Federico Vaga

sw:drv: bugfix concurrent tasklet scheduling

One process was able to perform a complete DMA transfer, and
communicate the success to the client. Then it would try to schedule
the next pending transfer, **but** the client could be fast enough to
submit a new request **before** the end of the IRQ handler.

This leads to this status: gn412x_dma_schedule_next() is called twice,
once from the IRQ handler, once from the client (issue_pending()). In
both cases they will see a pending transfer, and they will schedule
gn412x_dma_start_task() twice. One will successfully start a new DMA
transfer, the other one will fail printing an error.

------8<---------
         python3-19944 [002] ....... 15660.640429: spec_fpga_dbg_dma_write <-vfs_write
         python3-19944 [002] ....... 15660.640898: gn412x_dma_issue_pending <-spec_fpga_dbg_dma_transfer
         python3-19944 [002] ....... 15660.640898: gn412x_dma_schedule_next <-gn412x_dma_issue_pending
     ksoftirqd/2-31    [002] .....11 15660.640902: gn412x_dma_start_task <-__tasklet_action.isra.11
 irq/17-gn412x-g-5469  [000] ....... 15660.651980: gn412x_dma_irq_handler <-handle_nested_irq
         python3-19944 [002] ....... 15660.652086: spec_fpga_dbg_dma_read <-vfs_read
         python3-19944 [002] ....... 15660.652087: gn412x_dma_issue_pending <-spec_fpga_dbg_dma_transfer
         python3-19944 [002] ....... 15660.652087: gn412x_dma_schedule_next <-gn412x_dma_issue_pending
 irq/17-gn412x-g-5469  [000] ....... 15660.652089: gn412x_dma_schedule_next <-gn412x_dma_irq_handler
     ksoftirqd/2-31    [002] .....11 15660.652089: gn412x_dma_start_task <-__tasklet_action.isra.11
     ksoftirqd/2-31    [002] .....11 15660.652093: gn412x_dma_start_task <-__tasklet_action.isra.11
     ksoftirqd/2-31    [002] .....11 15660.652098: dev_err <-gn412x_dma_start_task
 irq/17-gn412x-g-5469  [000] ....... 15660.661041: gn412x_dma_irq_handler <-handle_nested_irq
 irq/17-gn412x-g-5469  [000] ....... 15660.661044: gn412x_dma_schedule_next <-gn412x_dma_irq_handler
------8<---------
[15660.652101] spec_gn412x_dma spec-gn412x-dma.3.auto: Failed to start DMA transfer: channel busy
------8<---------
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
Signed-off-by: Tristan Gingold's avatarTristan Gingold <tristan.gingold@cern.ch>
parent fc859af6
......@@ -713,6 +713,7 @@ static irqreturn_t gn412x_dma_irq_handler(int irq, void *arg)
spin_unlock_irqrestore(&chan->lock, flags);
state = gn412x_dma_state(gn412x_dma);
gn412x_dma_schedule_next(chan);
switch (state) {
case GN412X_DMA_STAT_IDLE:
dma_cookie_complete(&tx->tx);
......@@ -748,7 +749,6 @@ static irqreturn_t gn412x_dma_irq_handler(int irq, void *arg)
/* Clean up memory */
gn412x_dma_tx_free(tx);
gn412x_dma_schedule_next(chan);
return IRQ_HANDLED;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment