aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip J Kelleher <pjk1939@linux.vnet.ibm.com>2013-06-18 15:38:26 -0400
committerJens Axboe <axboe@kernel.dk>2013-06-19 07:52:09 -0400
commit31a70bb4440c963e69ce210389d8119c70b5c39d (patch)
tree70bb10af0da9ad240fef12bcd44968142d4bb202
parent0ab4743ebc18c23bddf3e288cfc6221ec71533ac (diff)
rsxx: Fixes soft-lockup issues during DMAs.
The workqueue mechanism has been reworked to prevent soft lockup issues from occuring by adding in mutex sychronization. Signed-off-by: Philip J Kelleher <pjk1939@linux.vnet.ibm.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--drivers/block/rsxx/dma.c35
-rw-r--r--drivers/block/rsxx/rsxx_priv.h1
2 files changed, 28 insertions, 8 deletions
diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c
index 213e40e4bd92..b485a65b8de1 100644
--- a/drivers/block/rsxx/dma.c
+++ b/drivers/block/rsxx/dma.c
@@ -381,15 +381,13 @@ static void dma_engine_stalled(unsigned long data)
381 } 381 }
382} 382}
383 383
384static void rsxx_issue_dmas(struct work_struct *work) 384static void rsxx_issue_dmas(struct rsxx_dma_ctrl *ctrl)
385{ 385{
386 struct rsxx_dma_ctrl *ctrl;
387 struct rsxx_dma *dma; 386 struct rsxx_dma *dma;
388 int tag; 387 int tag;
389 int cmds_pending = 0; 388 int cmds_pending = 0;
390 struct hw_cmd *hw_cmd_buf; 389 struct hw_cmd *hw_cmd_buf;
391 390
392 ctrl = container_of(work, struct rsxx_dma_ctrl, issue_dma_work);
393 hw_cmd_buf = ctrl->cmd.buf; 391 hw_cmd_buf = ctrl->cmd.buf;
394 392
395 if (unlikely(ctrl->card->halt) || 393 if (unlikely(ctrl->card->halt) ||
@@ -469,9 +467,8 @@ static void rsxx_issue_dmas(struct work_struct *work)
469 } 467 }
470} 468}
471 469
472static void rsxx_dma_done(struct work_struct *work) 470static void rsxx_dma_done(struct rsxx_dma_ctrl *ctrl)
473{ 471{
474 struct rsxx_dma_ctrl *ctrl;
475 struct rsxx_dma *dma; 472 struct rsxx_dma *dma;
476 unsigned long flags; 473 unsigned long flags;
477 u16 count; 474 u16 count;
@@ -479,7 +476,6 @@ static void rsxx_dma_done(struct work_struct *work)
479 u8 tag; 476 u8 tag;
480 struct hw_status *hw_st_buf; 477 struct hw_status *hw_st_buf;
481 478
482 ctrl = container_of(work, struct rsxx_dma_ctrl, dma_done_work);
483 hw_st_buf = ctrl->status.buf; 479 hw_st_buf = ctrl->status.buf;
484 480
485 if (unlikely(ctrl->card->halt) || 481 if (unlikely(ctrl->card->halt) ||
@@ -555,6 +551,28 @@ static void rsxx_dma_done(struct work_struct *work)
555 spin_unlock_bh(&ctrl->queue_lock); 551 spin_unlock_bh(&ctrl->queue_lock);
556} 552}
557 553
554static void rsxx_schedule_issue(struct work_struct *work)
555{
556 struct rsxx_dma_ctrl *ctrl;
557
558 ctrl = container_of(work, struct rsxx_dma_ctrl, issue_dma_work);
559
560 mutex_lock(&ctrl->work_lock);
561 rsxx_issue_dmas(ctrl);
562 mutex_unlock(&ctrl->work_lock);
563}
564
565static void rsxx_schedule_done(struct work_struct *work)
566{
567 struct rsxx_dma_ctrl *ctrl;
568
569 ctrl = container_of(work, struct rsxx_dma_ctrl, dma_done_work);
570
571 mutex_lock(&ctrl->work_lock);
572 rsxx_dma_done(ctrl);
573 mutex_unlock(&ctrl->work_lock);
574}
575
558static int rsxx_queue_discard(struct rsxx_cardinfo *card, 576static int rsxx_queue_discard(struct rsxx_cardinfo *card,
559 struct list_head *q, 577 struct list_head *q,
560 unsigned int laddr, 578 unsigned int laddr,
@@ -789,6 +807,7 @@ static int rsxx_dma_ctrl_init(struct pci_dev *dev,
789 spin_lock_init(&ctrl->trackers->lock); 807 spin_lock_init(&ctrl->trackers->lock);
790 808
791 spin_lock_init(&ctrl->queue_lock); 809 spin_lock_init(&ctrl->queue_lock);
810 mutex_init(&ctrl->work_lock);
792 INIT_LIST_HEAD(&ctrl->queue); 811 INIT_LIST_HEAD(&ctrl->queue);
793 812
794 setup_timer(&ctrl->activity_timer, dma_engine_stalled, 813 setup_timer(&ctrl->activity_timer, dma_engine_stalled,
@@ -802,8 +821,8 @@ static int rsxx_dma_ctrl_init(struct pci_dev *dev,
802 if (!ctrl->done_wq) 821 if (!ctrl->done_wq)
803 return -ENOMEM; 822 return -ENOMEM;
804 823
805 INIT_WORK(&ctrl->issue_dma_work, rsxx_issue_dmas); 824 INIT_WORK(&ctrl->issue_dma_work, rsxx_schedule_issue);
806 INIT_WORK(&ctrl->dma_done_work, rsxx_dma_done); 825 INIT_WORK(&ctrl->dma_done_work, rsxx_schedule_done);
807 826
808 st = rsxx_hw_buffers_init(dev, ctrl); 827 st = rsxx_hw_buffers_init(dev, ctrl);
809 if (st) 828 if (st)
diff --git a/drivers/block/rsxx/rsxx_priv.h b/drivers/block/rsxx/rsxx_priv.h
index 60b6ed6779ac..c968a6918b6e 100644
--- a/drivers/block/rsxx/rsxx_priv.h
+++ b/drivers/block/rsxx/rsxx_priv.h
@@ -115,6 +115,7 @@ struct rsxx_dma_ctrl {
115 struct timer_list activity_timer; 115 struct timer_list activity_timer;
116 struct dma_tracker_list *trackers; 116 struct dma_tracker_list *trackers;
117 struct rsxx_dma_stats stats; 117 struct rsxx_dma_stats stats;
118 struct mutex work_lock;
118}; 119};
119 120
120struct rsxx_cardinfo { 121struct rsxx_cardinfo {