aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2016-07-20 16:13:55 -0400
committerVinod Koul <vinod.koul@intel.com>2016-08-07 22:41:42 -0400
commit9546d4cdc8445acdea415f70a330bbfbd016a0f0 (patch)
treedeed065e3d0e0f1d78acd80e9a0d42cc31b0a581
parentf067025bc676ba8d18fba5f959598339e39b86db (diff)
dmaengine: ioatdma: Add error handling to ioat driver
Adding error handling to the ioatdma driver so that when a read/write error occurs the error results are reported back and all the remaining descriptors are aborted. This utilizes the new dmaengine callback function that allows reporting of results. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r--drivers/dma/ioat/dma.c140
-rw-r--r--drivers/dma/ioat/registers.h2
2 files changed, 126 insertions, 16 deletions
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 6499de4b8e79..251f8be639c2 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -568,10 +568,14 @@ static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete)
568 568
569 tx = &desc->txd; 569 tx = &desc->txd;
570 if (tx->cookie) { 570 if (tx->cookie) {
571 struct dmaengine_result res;
572
571 dma_cookie_complete(tx); 573 dma_cookie_complete(tx);
572 dma_descriptor_unmap(tx); 574 dma_descriptor_unmap(tx);
575 res.result = DMA_TRANS_NOERROR;
573 dmaengine_desc_get_callback_invoke(tx, NULL); 576 dmaengine_desc_get_callback_invoke(tx, NULL);
574 tx->callback = NULL; 577 tx->callback = NULL;
578 tx->callback_result = NULL;
575 } 579 }
576 580
577 if (tx->phys == phys_complete) 581 if (tx->phys == phys_complete)
@@ -620,7 +624,8 @@ static void ioat_cleanup(struct ioatdma_chan *ioat_chan)
620 if (is_ioat_halted(*ioat_chan->completion)) { 624 if (is_ioat_halted(*ioat_chan->completion)) {
621 u32 chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); 625 u32 chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
622 626
623 if (chanerr & IOAT_CHANERR_HANDLE_MASK) { 627 if (chanerr &
628 (IOAT_CHANERR_HANDLE_MASK | IOAT_CHANERR_RECOVER_MASK)) {
624 mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); 629 mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
625 ioat_eh(ioat_chan); 630 ioat_eh(ioat_chan);
626 } 631 }
@@ -650,6 +655,61 @@ static void ioat_restart_channel(struct ioatdma_chan *ioat_chan)
650 __ioat_restart_chan(ioat_chan); 655 __ioat_restart_chan(ioat_chan);
651} 656}
652 657
658
659static void ioat_abort_descs(struct ioatdma_chan *ioat_chan)
660{
661 struct ioatdma_device *ioat_dma = ioat_chan->ioat_dma;
662 struct ioat_ring_ent *desc;
663 u16 active;
664 int idx = ioat_chan->tail, i;
665
666 /*
667 * We assume that the failed descriptor has been processed.
668 * Now we are just returning all the remaining submitted
669 * descriptors to abort.
670 */
671 active = ioat_ring_active(ioat_chan);
672
673 /* we skip the failed descriptor that tail points to */
674 for (i = 1; i < active; i++) {
675 struct dma_async_tx_descriptor *tx;
676
677 smp_read_barrier_depends();
678 prefetch(ioat_get_ring_ent(ioat_chan, idx + i + 1));
679 desc = ioat_get_ring_ent(ioat_chan, idx + i);
680
681 tx = &desc->txd;
682 if (tx->cookie) {
683 struct dmaengine_result res;
684
685 dma_cookie_complete(tx);
686 dma_descriptor_unmap(tx);
687 res.result = DMA_TRANS_ABORTED;
688 dmaengine_desc_get_callback_invoke(tx, &res);
689 tx->callback = NULL;
690 tx->callback_result = NULL;
691 }
692
693 /* skip extended descriptors */
694 if (desc_has_ext(desc)) {
695 WARN_ON(i + 1 >= active);
696 i++;
697 }
698
699 /* cleanup super extended descriptors */
700 if (desc->sed) {
701 ioat_free_sed(ioat_dma, desc->sed);
702 desc->sed = NULL;
703 }
704 }
705
706 smp_mb(); /* finish all descriptor reads before incrementing tail */
707 ioat_chan->tail = idx + active;
708
709 desc = ioat_get_ring_ent(ioat_chan, ioat_chan->tail);
710 ioat_chan->last_completion = *ioat_chan->completion = desc->txd.phys;
711}
712
653static void ioat_eh(struct ioatdma_chan *ioat_chan) 713static void ioat_eh(struct ioatdma_chan *ioat_chan)
654{ 714{
655 struct pci_dev *pdev = to_pdev(ioat_chan); 715 struct pci_dev *pdev = to_pdev(ioat_chan);
@@ -660,6 +720,8 @@ static void ioat_eh(struct ioatdma_chan *ioat_chan)
660 u32 err_handled = 0; 720 u32 err_handled = 0;
661 u32 chanerr_int; 721 u32 chanerr_int;
662 u32 chanerr; 722 u32 chanerr;
723 bool abort = false;
724 struct dmaengine_result res;
663 725
664 /* cleanup so tail points to descriptor that caused the error */ 726 /* cleanup so tail points to descriptor that caused the error */
665 if (ioat_cleanup_preamble(ioat_chan, &phys_complete)) 727 if (ioat_cleanup_preamble(ioat_chan, &phys_complete))
@@ -695,28 +757,50 @@ static void ioat_eh(struct ioatdma_chan *ioat_chan)
695 break; 757 break;
696 } 758 }
697 759
760 if (chanerr & IOAT_CHANERR_RECOVER_MASK) {
761 if (chanerr & IOAT_CHANERR_READ_DATA_ERR) {
762 res.result = DMA_TRANS_READ_FAILED;
763 err_handled |= IOAT_CHANERR_READ_DATA_ERR;
764 } else if (chanerr & IOAT_CHANERR_WRITE_DATA_ERR) {
765 res.result = DMA_TRANS_WRITE_FAILED;
766 err_handled |= IOAT_CHANERR_WRITE_DATA_ERR;
767 }
768
769 abort = true;
770 } else
771 res.result = DMA_TRANS_NOERROR;
772
698 /* fault on unhandled error or spurious halt */ 773 /* fault on unhandled error or spurious halt */
699 if (chanerr ^ err_handled || chanerr == 0) { 774 if (chanerr ^ err_handled || chanerr == 0) {
700 dev_err(to_dev(ioat_chan), "%s: fatal error (%x:%x)\n", 775 dev_err(to_dev(ioat_chan), "%s: fatal error (%x:%x)\n",
701 __func__, chanerr, err_handled); 776 __func__, chanerr, err_handled);
702 BUG(); 777 BUG();
703 } else { /* cleanup the faulty descriptor */
704 tx = &desc->txd;
705 if (tx->cookie) {
706 dma_cookie_complete(tx);
707 dma_descriptor_unmap(tx);
708 dmaengine_desc_get_callback_invoke(tx, NULL);
709 tx->callback = NULL;
710 }
711 } 778 }
712 779
713 writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET); 780 /* cleanup the faulty descriptor since we are continuing */
714 pci_write_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, chanerr_int); 781 tx = &desc->txd;
782 if (tx->cookie) {
783 dma_cookie_complete(tx);
784 dma_descriptor_unmap(tx);
785 dmaengine_desc_get_callback_invoke(tx, &res);
786 tx->callback = NULL;
787 tx->callback_result = NULL;
788 }
715 789
716 /* mark faulting descriptor as complete */ 790 /* mark faulting descriptor as complete */
717 *ioat_chan->completion = desc->txd.phys; 791 *ioat_chan->completion = desc->txd.phys;
718 792
719 spin_lock_bh(&ioat_chan->prep_lock); 793 spin_lock_bh(&ioat_chan->prep_lock);
794 /* we need abort all descriptors */
795 if (abort) {
796 ioat_abort_descs(ioat_chan);
797 /* clean up the channel, we could be in weird state */
798 ioat_reset_hw(ioat_chan);
799 }
800
801 writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
802 pci_write_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, chanerr_int);
803
720 ioat_restart_channel(ioat_chan); 804 ioat_restart_channel(ioat_chan);
721 spin_unlock_bh(&ioat_chan->prep_lock); 805 spin_unlock_bh(&ioat_chan->prep_lock);
722} 806}
@@ -749,10 +833,25 @@ void ioat_timer_event(unsigned long data)
749 chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); 833 chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
750 dev_err(to_dev(ioat_chan), "%s: Channel halted (%x)\n", 834 dev_err(to_dev(ioat_chan), "%s: Channel halted (%x)\n",
751 __func__, chanerr); 835 __func__, chanerr);
752 if (test_bit(IOAT_RUN, &ioat_chan->state)) 836 if (test_bit(IOAT_RUN, &ioat_chan->state)) {
753 BUG_ON(is_ioat_bug(chanerr)); 837 spin_lock_bh(&ioat_chan->cleanup_lock);
754 else /* we never got off the ground */ 838 spin_lock_bh(&ioat_chan->prep_lock);
755 return; 839 set_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
840 spin_unlock_bh(&ioat_chan->prep_lock);
841
842 ioat_abort_descs(ioat_chan);
843 dev_warn(to_dev(ioat_chan), "Reset channel...\n");
844 ioat_reset_hw(ioat_chan);
845 dev_warn(to_dev(ioat_chan), "Restart channel...\n");
846 ioat_restart_channel(ioat_chan);
847
848 spin_lock_bh(&ioat_chan->prep_lock);
849 clear_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
850 spin_unlock_bh(&ioat_chan->prep_lock);
851 spin_unlock_bh(&ioat_chan->cleanup_lock);
852 }
853
854 return;
756 } 855 }
757 856
758 spin_lock_bh(&ioat_chan->cleanup_lock); 857 spin_lock_bh(&ioat_chan->cleanup_lock);
@@ -776,14 +875,23 @@ void ioat_timer_event(unsigned long data)
776 u32 chanerr; 875 u32 chanerr;
777 876
778 chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); 877 chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
779 dev_warn(to_dev(ioat_chan), "Restarting channel...\n");
780 dev_warn(to_dev(ioat_chan), "CHANSTS: %#Lx CHANERR: %#x\n", 878 dev_warn(to_dev(ioat_chan), "CHANSTS: %#Lx CHANERR: %#x\n",
781 status, chanerr); 879 status, chanerr);
782 dev_warn(to_dev(ioat_chan), "Active descriptors: %d\n", 880 dev_warn(to_dev(ioat_chan), "Active descriptors: %d\n",
783 ioat_ring_active(ioat_chan)); 881 ioat_ring_active(ioat_chan));
784 882
785 spin_lock_bh(&ioat_chan->prep_lock); 883 spin_lock_bh(&ioat_chan->prep_lock);
884 set_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
885 spin_unlock_bh(&ioat_chan->prep_lock);
886
887 ioat_abort_descs(ioat_chan);
888 dev_warn(to_dev(ioat_chan), "Resetting channel...\n");
889 ioat_reset_hw(ioat_chan);
890 dev_warn(to_dev(ioat_chan), "Restarting channel...\n");
786 ioat_restart_channel(ioat_chan); 891 ioat_restart_channel(ioat_chan);
892
893 spin_lock_bh(&ioat_chan->prep_lock);
894 clear_bit(IOAT_CHAN_DOWN, &ioat_chan->state);
787 spin_unlock_bh(&ioat_chan->prep_lock); 895 spin_unlock_bh(&ioat_chan->prep_lock);
788 spin_unlock_bh(&ioat_chan->cleanup_lock); 896 spin_unlock_bh(&ioat_chan->cleanup_lock);
789 return; 897 return;
diff --git a/drivers/dma/ioat/registers.h b/drivers/dma/ioat/registers.h
index 70534981a49b..48fa4cf9f64a 100644
--- a/drivers/dma/ioat/registers.h
+++ b/drivers/dma/ioat/registers.h
@@ -240,6 +240,8 @@
240#define IOAT_CHANERR_DESCRIPTOR_COUNT_ERR 0x40000 240#define IOAT_CHANERR_DESCRIPTOR_COUNT_ERR 0x40000
241 241
242#define IOAT_CHANERR_HANDLE_MASK (IOAT_CHANERR_XOR_P_OR_CRC_ERR | IOAT_CHANERR_XOR_Q_ERR) 242#define IOAT_CHANERR_HANDLE_MASK (IOAT_CHANERR_XOR_P_OR_CRC_ERR | IOAT_CHANERR_XOR_Q_ERR)
243#define IOAT_CHANERR_RECOVER_MASK (IOAT_CHANERR_READ_DATA_ERR | \
244 IOAT_CHANERR_WRITE_DATA_ERR)
243 245
244#define IOAT_CHANERR_MASK_OFFSET 0x2C /* 32-bit Channel Error Register */ 246#define IOAT_CHANERR_MASK_OFFSET 0x2C /* 32-bit Channel Error Register */
245 247