On Wed, Oct 09, 2019 at 04:58:12PM +0200, Alexander Gordeev wrote: > On Wed, Oct 09, 2019 at 03:14:41PM +0300, Dan Carpenter wrote: > > > +config AVALON_DMA_PCI_VENDOR_ID > > > + hex "PCI vendor ID" > > > + default "0x1172" > > > + > > > +config AVALON_DMA_PCI_DEVICE_ID > > > + hex "PCI device ID" > > > + default "0xe003" > > > > This feels wrong. Why isn't it known in advance. > > Because device designers would likely use they own IDs. The ones I > put are just defaults inherited from the (Altera) reference design. > > > > + u32 *rd_flags = hw->dma_desc_table_rd.cpu_addr->flags; > > > + u32 *wr_flags = hw->dma_desc_table_wr.cpu_addr->flags; > > > + struct avalon_dma_desc *desc; > > > + struct virt_dma_desc *vdesc; > > > + bool rd_done; > > > + bool wr_done; > > > + > > > + spin_lock(lock); > > > + > > > + rd_done = (hw->h2d_last_id < 0); > > > + wr_done = (hw->d2h_last_id < 0); > > > + > > > + if (rd_done && wr_done) { > > > + spin_unlock(lock); > > > + return IRQ_NONE; > > > + } > > > + > > > + do { > > > + if (!rd_done && rd_flags[hw->h2d_last_id]) > > > + rd_done = true; > > > + > > > + if (!wr_done && wr_flags[hw->d2h_last_id]) > > > + wr_done = true; > > > + } while (!rd_done || !wr_done); > > > > This loop is very strange. It feels like the last_id indexes needs > > to atomic or protected from racing somehow so we don't do an out of > > bounds read. > > My bad. I should have put a comment on this. This polling comes from my > reading of the Intel documentation: > > "The MSI interrupt notifies the host when a DMA operation has completed. > After the host receives this interrupt, it can poll the DMA read or write > status table to determine which entry or entries have the done bit set." > > "The Descriptor Controller writes a 1 to the done bit of the status DWORD > to indicate successful completion. The Descriptor Controller also sends > an MSI interrupt for the final descriptor. After receiving this MSI, > host software can poll the done bit to determine status." > > I sense an ambiguity above. It sounds possible an MSI interrupt could be > delivered before corresponding done bit is set. May be imperfect wording.. > Anyway, the loop does look weird and in reality I doubt I observed the > done bit unset even once. So I put this polling just in case. You're missing my point. When we set hw->d2h_last_id = 1; ... hw->d2h_last_id = 2; There is a tiny moment where ->d2h_last_id is transitioning from 1 to 2 where its value is unknown. We're in a busy loop here so we have a decent chance of hitting that 1/1000,000th of a second. If we happen to hit it at exactly the right time then we're reading from a random address and it will cause an oops. We have to use atomic_t types or something to handle race conditions. regards, dan carpenter