I/OAT fixes
Subsystems (4)
cover I/OAT fixes
This patch series contains couple of fixes for I/OAT DMA and DCA.
Maciej Sosnowski (3):
I/OAT: fix channel resources free for not allocated channels I/OAT: fix dma_pin_iovec_pages() error handling I/OAT: fix async_tx.callback checking
Dan Williams (1):
dca: fixup initialization dependency
drivers/dca/dca-core.c | 2 +- drivers/dma/ioat_dma.c | 11 +++++++++-- drivers/dma/iovlock.c | 17 ++++++----------- 3 files changed, 16 insertions(+), 14 deletions(-)
--
Maciej
PATCH 1/4 I/OAT: fix channel resources free for not allocated channels
From: Maciej Sosnowski <[email protected]>
If the ioatdma driver is loaded but not used it does not allocate descriptors. Before it frees channel resources it should first be sure
that they have been previously allocated.
---
drivers/dma/ioat_dma.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/dma/ioat_dma.c +7 -0
@@ -807,6 +807,12 @@ static void ioat_dma_free_chan_resourcesstruct ioat_desc_sw *desc, *_desc;int in_use_descs =0 ; +/* Before freeing channel resources first check +* if they have been previously allocated for this channel. +*/ +if (ioat_chan->desccount ==0 ) +return ; +tasklet_disable (&ioat_chan->cleanup_task);ioat_dma_memcpy_cleanup (ioat_chan);
@@ -869,6 +875,7 @@ static void ioat_dma_free_chan_resources ioat_chan->last_completion = ioat_chan->completion_addr =0 ; ioat_chan->pending =0 ; ioat_chan->dmacount =0 ; + ioat_chan->desccount =0 ; ioat_chan->watchdog_completion =0 ; ioat_chan->last_compl_desc_addr_hw =0 ; ioat_chan->watchdog_tcp_cookie =
PATCH 2/4 I/OAT: fix dma_pin_iovec_pages() error handling
In reply to Maciej SosnowskiFrom: Maciej Sosnowski <[email protected]>
Error handling needs to be modified in dma_pin_iovec_pages(). It should return NULL instead of ERR_PTR (pinned_list is checked for NULL in tcp_recvmsg() to determine if iovec pages have been successfully pinned down). In case of error for the first iovec, local_list->nr_iovecs needs to be initialized.
---
drivers/dma/iovlock.c | 17 ++++++----------- 1 files changed, 6 insertions(+), 11 deletions(-)
drivers/dma/iovlock.c +6 -11
@@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_paint nr_iovecs =0 ;int iovec_len_used =0 ;int iovec_pages_used =0 ; -long err;/* don't pin down non-user-based iovecs */ if (segment_eq (get_fs (),KERNEL_DS ))
@@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pa local_list =kmalloc (sizeof (*local_list) + (nr_iovecs *sizeof (struct dma_page_list )) + (iovec_pages_used *sizeof (struct page *)),GFP_KERNEL ); -if (!local_list) { - err = -ENOMEM ; +if (!local_list) goto out; - }/* list of pages starts right after the page list array */ pages = (struct page **) &local_list->page_list[nr_iovecs]; + local_list->nr_iovecs =0 ; +for (i =0 ; i < nr_iovecs; i++) {struct dma_page_list *page_list = &local_list->page_list[i]; len -= iov[i].iov_len; -if (!access_ok (VERIFY_WRITE , iov[i].iov_base, iov[i].iov_len)) { - err = -EFAULT ; +if (!access_ok (VERIFY_WRITE , iov[i].iov_base, iov[i].iov_len)) goto unpin; - } page_list->nr_pages =num_pages_spanned (&iov[i]); page_list->base_address = iov[i].iov_base;
@@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pa NULL);up_read (¤t->mm->mmap_sem); -if (ret != page_list->nr_pages) { - err = -ENOMEM ; +if (ret != page_list->nr_pages) goto unpin; - } local_list->nr_iovecs = i +1 ; }
@@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pa unpin:dma_unpin_iovec_pages (local_list); out: -return ERR_PTR (err); +return NULL ; }void dma_unpin_iovec_pages (struct dma_pinned_list *pinned_list)
PATCH 3/4 I/OAT: fix async_tx.callback checking
In reply to Maciej SosnowskiFrom: Maciej Sosnowski <[email protected]>
async_tx.callback should be checked for the first
not the last descriptor in the chain.
---
drivers/dma/ioat_dma.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/dma/ioat_dma.c +2 -2
@@ -525,7 +525,7 @@ static dma_cookie_t ioat1_tx_submit(stru } hw->ctl =IOAT_DMA_DESCRIPTOR_CTL_CP_STS ; -if (new->async_tx.callback) { +if (first->async_tx.callback) { hw->ctl |=IOAT_DMA_DESCRIPTOR_CTL_INT_GN ;if (first != new) {/* move callback into to last desc */
@@ -617,7 +617,7 @@ static dma_cookie_t ioat2_tx_submit(stru } hw->ctl |=IOAT_DMA_DESCRIPTOR_CTL_CP_STS ; -if (new->async_tx.callback) { +if (first->async_tx.callback) { hw->ctl |=IOAT_DMA_DESCRIPTOR_CTL_INT_GN ;if (first != new) {/* move callback into to last desc */
PATCH 4/4 dca: fixup initialization dependency
In reply to Maciej SosnowskiFrom: Dan Williams <[email protected]>
Mark dca_init as a subsys_initcall since it needs to be ready to go before dependent drivers start registering themselves.
---
drivers/dca/dca-core.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/dca/dca-core.c +1 -1
@@ -270,6 +270,6 @@ static void __exit dca_exit(void)dca_sysfs_exit (); } -module_init (dca_init); +subsys_initcall (dca_init);module_exit (dca_exit);