aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHongbo Zhang <hongbo.zhang@freescale.com>2014-05-21 04:03:03 -0400
committerVinod Koul <vinod.koul@intel.com>2014-07-14 12:02:18 -0400
commit43452fadd614b62b84e950838cb7d2419f3aafb1 (patch)
tree241fe333208fd23b68c99f69b5821faf14204406
parent14c6a3333c8e885604fc98768d8b9a32e08110ac (diff)
dmaengine: Freescale: change descriptor release process for supporting async_tx
Fix the potential risk when enable config NET_DMA and ASYNC_TX. Async_tx is lack of support in current release process of dma descriptor, all descriptors will be released whatever is acked or no-acked by async_tx, so there is a potential race condition when dma engine is uesd by others clients (e.g. when enable NET_DMA to offload TCP). In our case, a race condition which is raised when use both of talitos and dmaengine to offload xor is because napi scheduler will sync all pending requests in dma channels, it affects the process of raid operations due to ack_tx is not checked in fsl dma. The no-acked descriptor is freed which is submitted just now, as a dependent tx, this freed descriptor trigger BUG_ON(async_tx_test_ack(depend_tx)) in async_tx_submit(). TASK = ee1a94a0[1390] 'md0_raid5' THREAD: ecf40000 CPU: 0 GPR00: 00000001 ecf41ca0 ee44/921a94a0 0000003f 00000001 c00593e4 00000000 00000001 GPR08: 00000000 a7a7a7a7 00000001 045/920000002 42028042 100a38d4 ed576d98 00000000 GPR16: ed5a11b0 00000000 2b162000 00000200 046/920000000 2d555000 ed3015e8 c15a7aa0 GPR24: 00000000 c155fc40 00000000 ecb63220 ecf41d28 e47/92f640bb0 ef640c30 ecf41ca0 NIP [c02b048c] async_tx_submit+0x6c/0x2b4 LR [c02b068c] async_tx_submit+0x26c/0x2b4 Call Trace: [ecf41ca0] [c02b068c] async_tx_submit+0x26c/0x2b448/92 (unreliable) [ecf41cd0] [c02b0a4c] async_memcpy+0x240/0x25c [ecf41d20] [c0421064] async_copy_data+0xa0/0x17c [ecf41d70] [c0421cf4] __raid_run_ops+0x874/0xe10 [ecf41df0] [c0426ee4] handle_stripe+0x820/0x25e8 [ecf41e90] [c0429080] raid5d+0x3d4/0x5b4 [ecf41f40] [c04329b8] md_thread+0x138/0x16c [ecf41f90] [c008277c] kthread+0x8c/0x90 [ecf41ff0] [c0011630] kernel_thread+0x4c/0x68 Another modification in this patch is the change of completed descriptors, there is a potential risk which caused by exception interrupt, all descriptors in ld_running list are seemed completed when an interrupt raised, it works fine under normal condition, but if there is an exception occured, it cannot work as our excepted. Hardware should not be depend on s/w list, the right way is to read current descriptor address register to find the last completed descriptor. If an interrupt is raised by an error, all descriptors in ld_running should not be seemed finished, or these unfinished descriptors in ld_running will be released wrongly. A simple way to reproduce: Enable dmatest first, then insert some bad descriptors which can trigger Programming Error interrupts before the good descriptors. Last, the good descriptors will be freed before they are processsed because of the exception intrerrupt. Note: the bad descriptors are only for simulating an exception interrupt. This case can illustrate the potential risk in current fsl-dma very well. Signed-off-by: Hongbo Zhang <hongbo.zhang@freescale.com> Signed-off-by: Qiang Liu <qiang.liu@freescale.com> Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r--drivers/dma/fsldma.c197
-rw-r--r--drivers/dma/fsldma.h17
2 files changed, 159 insertions, 55 deletions
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 465f16dd78e5..d5d6885ab341 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -466,6 +466,88 @@ static struct fsl_desc_sw *fsl_dma_alloc_descriptor(struct fsldma_chan *chan)
466} 466}
467 467
468/** 468/**
469 * fsldma_clean_completed_descriptor - free all descriptors which
470 * has been completed and acked
471 * @chan: Freescale DMA channel
472 *
473 * This function is used on all completed and acked descriptors.
474 * All descriptors should only be freed in this function.
475 */
476static void fsldma_clean_completed_descriptor(struct fsldma_chan *chan)
477{
478 struct fsl_desc_sw *desc, *_desc;
479
480 /* Run the callback for each descriptor, in order */
481 list_for_each_entry_safe(desc, _desc, &chan->ld_completed, node)
482 if (async_tx_test_ack(&desc->async_tx))
483 fsl_dma_free_descriptor(chan, desc);
484}
485
486/**
487 * fsldma_run_tx_complete_actions - cleanup a single link descriptor
488 * @chan: Freescale DMA channel
489 * @desc: descriptor to cleanup and free
490 * @cookie: Freescale DMA transaction identifier
491 *
492 * This function is used on a descriptor which has been executed by the DMA
493 * controller. It will run any callbacks, submit any dependencies.
494 */
495static dma_cookie_t fsldma_run_tx_complete_actions(struct fsldma_chan *chan,
496 struct fsl_desc_sw *desc, dma_cookie_t cookie)
497{
498 struct dma_async_tx_descriptor *txd = &desc->async_tx;
499 dma_cookie_t ret = cookie;
500
501 BUG_ON(txd->cookie < 0);
502
503 if (txd->cookie > 0) {
504 ret = txd->cookie;
505
506 /* Run the link descriptor callback function */
507 if (txd->callback) {
508 chan_dbg(chan, "LD %p callback\n", desc);
509 txd->callback(txd->callback_param);
510 }
511 }
512
513 /* Run any dependencies */
514 dma_run_dependencies(txd);
515
516 return ret;
517}
518
519/**
520 * fsldma_clean_running_descriptor - move the completed descriptor from
521 * ld_running to ld_completed
522 * @chan: Freescale DMA channel
523 * @desc: the descriptor which is completed
524 *
525 * Free the descriptor directly if acked by async_tx api, or move it to
526 * queue ld_completed.
527 */
528static void fsldma_clean_running_descriptor(struct fsldma_chan *chan,
529 struct fsl_desc_sw *desc)
530{
531 /* Remove from the list of transactions */
532 list_del(&desc->node);
533
534 /*
535 * the client is allowed to attach dependent operations
536 * until 'ack' is set
537 */
538 if (!async_tx_test_ack(&desc->async_tx)) {
539 /*
540 * Move this descriptor to the list of descriptors which is
541 * completed, but still awaiting the 'ack' bit to be set.
542 */
543 list_add_tail(&desc->node, &chan->ld_completed);
544 return;
545 }
546
547 dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
548}
549
550/**
469 * fsl_chan_xfer_ld_queue - transfer any pending transactions 551 * fsl_chan_xfer_ld_queue - transfer any pending transactions
470 * @chan : Freescale DMA channel 552 * @chan : Freescale DMA channel
471 * 553 *
@@ -533,31 +615,58 @@ static void fsl_chan_xfer_ld_queue(struct fsldma_chan *chan)
533} 615}
534 616
535/** 617/**
536 * fsldma_cleanup_descriptor - cleanup and free a single link descriptor 618 * fsldma_cleanup_descriptors - cleanup link descriptors which are completed
619 * and move them to ld_completed to free until flag 'ack' is set
537 * @chan: Freescale DMA channel 620 * @chan: Freescale DMA channel
538 * @desc: descriptor to cleanup and free
539 * 621 *
540 * This function is used on a descriptor which has been executed by the DMA 622 * This function is used on descriptors which have been executed by the DMA
541 * controller. It will run any callbacks, submit any dependencies, and then 623 * controller. It will run any callbacks, submit any dependencies, then
542 * free the descriptor. 624 * free these descriptors if flag 'ack' is set.
543 */ 625 */
544static void fsldma_cleanup_descriptor(struct fsldma_chan *chan, 626static void fsldma_cleanup_descriptors(struct fsldma_chan *chan)
545 struct fsl_desc_sw *desc)
546{ 627{
547 struct dma_async_tx_descriptor *txd = &desc->async_tx; 628 struct fsl_desc_sw *desc, *_desc;
629 dma_cookie_t cookie = 0;
630 dma_addr_t curr_phys = get_cdar(chan);
631 int seen_current = 0;
548 632
549 /* Run the link descriptor callback function */ 633 fsldma_clean_completed_descriptor(chan);
550 if (txd->callback) { 634
551 chan_dbg(chan, "LD %p callback\n", desc); 635 /* Run the callback for each descriptor, in order */
552 txd->callback(txd->callback_param); 636 list_for_each_entry_safe(desc, _desc, &chan->ld_running, node) {
637 /*
638 * do not advance past the current descriptor loaded into the
639 * hardware channel, subsequent descriptors are either in
640 * process or have not been submitted
641 */
642 if (seen_current)
643 break;
644
645 /*
646 * stop the search if we reach the current descriptor and the
647 * channel is busy
648 */
649 if (desc->async_tx.phys == curr_phys) {
650 seen_current = 1;
651 if (!dma_is_idle(chan))
652 break;
653 }
654
655 cookie = fsldma_run_tx_complete_actions(chan, desc, cookie);
656
657 fsldma_clean_running_descriptor(chan, desc);
553 } 658 }
554 659
555 /* Run any dependencies */ 660 /*
556 dma_run_dependencies(txd); 661 * Start any pending transactions automatically
662 *
663 * In the ideal case, we keep the DMA controller busy while we go
664 * ahead and free the descriptors below.
665 */
666 fsl_chan_xfer_ld_queue(chan);
557 667
558 dma_descriptor_unmap(txd); 668 if (cookie > 0)
559 chan_dbg(chan, "LD %p free\n", desc); 669 chan->common.completed_cookie = cookie;
560 dma_pool_free(chan->desc_pool, desc, txd->phys);
561} 670}
562 671
563/** 672/**
@@ -627,8 +736,10 @@ static void fsl_dma_free_chan_resources(struct dma_chan *dchan)
627 736
628 chan_dbg(chan, "free all channel resources\n"); 737 chan_dbg(chan, "free all channel resources\n");
629 spin_lock_bh(&chan->desc_lock); 738 spin_lock_bh(&chan->desc_lock);
739 fsldma_cleanup_descriptors(chan);
630 fsldma_free_desc_list(chan, &chan->ld_pending); 740 fsldma_free_desc_list(chan, &chan->ld_pending);
631 fsldma_free_desc_list(chan, &chan->ld_running); 741 fsldma_free_desc_list(chan, &chan->ld_running);
742 fsldma_free_desc_list(chan, &chan->ld_completed);
632 spin_unlock_bh(&chan->desc_lock); 743 spin_unlock_bh(&chan->desc_lock);
633 744
634 dma_pool_destroy(chan->desc_pool); 745 dma_pool_destroy(chan->desc_pool);
@@ -865,6 +976,7 @@ static int fsl_dma_device_control(struct dma_chan *dchan,
865 /* Remove and free all of the descriptors in the LD queue */ 976 /* Remove and free all of the descriptors in the LD queue */
866 fsldma_free_desc_list(chan, &chan->ld_pending); 977 fsldma_free_desc_list(chan, &chan->ld_pending);
867 fsldma_free_desc_list(chan, &chan->ld_running); 978 fsldma_free_desc_list(chan, &chan->ld_running);
979 fsldma_free_desc_list(chan, &chan->ld_completed);
868 chan->idle = true; 980 chan->idle = true;
869 981
870 spin_unlock_bh(&chan->desc_lock); 982 spin_unlock_bh(&chan->desc_lock);
@@ -923,6 +1035,17 @@ static enum dma_status fsl_tx_status(struct dma_chan *dchan,
923 dma_cookie_t cookie, 1035 dma_cookie_t cookie,
924 struct dma_tx_state *txstate) 1036 struct dma_tx_state *txstate)
925{ 1037{
1038 struct fsldma_chan *chan = to_fsl_chan(dchan);
1039 enum dma_status ret;
1040
1041 ret = dma_cookie_status(dchan, cookie, txstate);
1042 if (ret == DMA_COMPLETE)
1043 return ret;
1044
1045 spin_lock_bh(&chan->desc_lock);
1046 fsldma_cleanup_descriptors(chan);
1047 spin_unlock_bh(&chan->desc_lock);
1048
926 return dma_cookie_status(dchan, cookie, txstate); 1049 return dma_cookie_status(dchan, cookie, txstate);
927} 1050}
928 1051
@@ -1000,51 +1123,18 @@ static irqreturn_t fsldma_chan_irq(int irq, void *data)
1000static void dma_do_tasklet(unsigned long data) 1123static void dma_do_tasklet(unsigned long data)
1001{ 1124{
1002 struct fsldma_chan *chan = (struct fsldma_chan *)data; 1125 struct fsldma_chan *chan = (struct fsldma_chan *)data;
1003 struct fsl_desc_sw *desc, *_desc;
1004 LIST_HEAD(ld_cleanup);
1005 1126
1006 chan_dbg(chan, "tasklet entry\n"); 1127 chan_dbg(chan, "tasklet entry\n");
1007 1128
1008 spin_lock_bh(&chan->desc_lock); 1129 spin_lock_bh(&chan->desc_lock);
1009 1130
1010 /* update the cookie if we have some descriptors to cleanup */
1011 if (!list_empty(&chan->ld_running)) {
1012 dma_cookie_t cookie;
1013
1014 desc = to_fsl_desc(chan->ld_running.prev);
1015 cookie = desc->async_tx.cookie;
1016 dma_cookie_complete(&desc->async_tx);
1017
1018 chan_dbg(chan, "completed_cookie=%d\n", cookie);
1019 }
1020
1021 /*
1022 * move the descriptors to a temporary list so we can drop the lock
1023 * during the entire cleanup operation
1024 */
1025 list_splice_tail_init(&chan->ld_running, &ld_cleanup);
1026
1027 /* the hardware is now idle and ready for more */ 1131 /* the hardware is now idle and ready for more */
1028 chan->idle = true; 1132 chan->idle = true;
1029 1133
1030 /* 1134 /* Run all cleanup for descriptors which have been completed */
1031 * Start any pending transactions automatically 1135 fsldma_cleanup_descriptors(chan);
1032 *
1033 * In the ideal case, we keep the DMA controller busy while we go
1034 * ahead and free the descriptors below.
1035 */
1036 fsl_chan_xfer_ld_queue(chan);
1037 spin_unlock_bh(&chan->desc_lock);
1038
1039 /* Run the callback for each descriptor, in order */
1040 list_for_each_entry_safe(desc, _desc, &ld_cleanup, node) {
1041
1042 /* Remove from the list of transactions */
1043 list_del(&desc->node);
1044 1136
1045 /* Run all cleanup for this descriptor */ 1137 spin_unlock_bh(&chan->desc_lock);
1046 fsldma_cleanup_descriptor(chan, desc);
1047 }
1048 1138
1049 chan_dbg(chan, "tasklet exit\n"); 1139 chan_dbg(chan, "tasklet exit\n");
1050} 1140}
@@ -1228,6 +1318,7 @@ static int fsl_dma_chan_probe(struct fsldma_device *fdev,
1228 spin_lock_init(&chan->desc_lock); 1318 spin_lock_init(&chan->desc_lock);
1229 INIT_LIST_HEAD(&chan->ld_pending); 1319 INIT_LIST_HEAD(&chan->ld_pending);
1230 INIT_LIST_HEAD(&chan->ld_running); 1320 INIT_LIST_HEAD(&chan->ld_running);
1321 INIT_LIST_HEAD(&chan->ld_completed);
1231 chan->idle = true; 1322 chan->idle = true;
1232#ifdef CONFIG_PM 1323#ifdef CONFIG_PM
1233 chan->pm_state = RUNNING; 1324 chan->pm_state = RUNNING;
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index f2e0c4dcf901..239c20c84382 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -149,8 +149,21 @@ struct fsldma_chan {
149 char name[8]; /* Channel name */ 149 char name[8]; /* Channel name */
150 struct fsldma_chan_regs __iomem *regs; 150 struct fsldma_chan_regs __iomem *regs;
151 spinlock_t desc_lock; /* Descriptor operation lock */ 151 spinlock_t desc_lock; /* Descriptor operation lock */
152 struct list_head ld_pending; /* Link descriptors queue */ 152 /*
153 struct list_head ld_running; /* Link descriptors queue */ 153 * Descriptors which are queued to run, but have not yet been
154 * submitted to the hardware for execution
155 */
156 struct list_head ld_pending;
157 /*
158 * Descriptors which are currently being executed by the hardware
159 */
160 struct list_head ld_running;
161 /*
162 * Descriptors which have finished execution by the hardware. These
163 * descriptors have already had their cleanup actions run. They are
164 * waiting for the ACK bit to be set by the async_tx API.
165 */
166 struct list_head ld_completed; /* Link descriptors queue */
154 struct dma_chan common; /* DMA common channel */ 167 struct dma_chan common; /* DMA common channel */
155 struct dma_pool *desc_pool; /* Descriptors pool */ 168 struct dma_pool *desc_pool; /* Descriptors pool */
156 struct device *dev; /* Channel device */ 169 struct device *dev; /* Channel device */