aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip J Kelleher <pjk1939@linux.vnet.ibm.com>2013-06-18 15:34:54 -0400
committerJens Axboe <axboe@kernel.dk>2013-06-19 07:52:09 -0400
commita3299ab18591d36ad5622f5064619123c439b779 (patch)
tree5a08d03af4ef28eea4f1638a385d10d3fa107856
parent9138125beabbb76b4a373d4a619870f6f5d86fc5 (diff)
rsxx: Individual workqueues for interruptible events.
Giving all interrupt based events their own workqueue to complete tasks on. This fixes a bug that would cause creg commands to timeout if too many are issued at once. 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/core.c23
-rw-r--r--drivers/block/rsxx/cregs.c5
-rw-r--r--drivers/block/rsxx/rsxx_priv.h2
3 files changed, 27 insertions, 3 deletions
diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c
index 5af21f2db29c..774f810c6a9c 100644
--- a/drivers/block/rsxx/core.c
+++ b/drivers/block/rsxx/core.c
@@ -163,12 +163,13 @@ static irqreturn_t rsxx_isr(int irq, void *pdata)
163 } 163 }
164 164
165 if (isr & CR_INTR_CREG) { 165 if (isr & CR_INTR_CREG) {
166 schedule_work(&card->creg_ctrl.done_work); 166 queue_work(card->creg_ctrl.creg_wq,
167 &card->creg_ctrl.done_work);
167 handled++; 168 handled++;
168 } 169 }
169 170
170 if (isr & CR_INTR_EVENT) { 171 if (isr & CR_INTR_EVENT) {
171 schedule_work(&card->event_work); 172 queue_work(card->event_wq, &card->event_work);
172 rsxx_disable_ier_and_isr(card, CR_INTR_EVENT); 173 rsxx_disable_ier_and_isr(card, CR_INTR_EVENT);
173 handled++; 174 handled++;
174 } 175 }
@@ -610,7 +611,11 @@ static int rsxx_pci_probe(struct pci_dev *dev,
610 } 611 }
611 612
612 /************* Setup Processor Command Interface *************/ 613 /************* Setup Processor Command Interface *************/
613 rsxx_creg_setup(card); 614 st = rsxx_creg_setup(card);
615 if (st) {
616 dev_err(CARD_TO_DEV(card), "Failed to setup creg interface.\n");
617 goto failed_creg_setup;
618 }
614 619
615 spin_lock_irq(&card->irq_lock); 620 spin_lock_irq(&card->irq_lock);
616 rsxx_enable_ier_and_isr(card, CR_INTR_CREG); 621 rsxx_enable_ier_and_isr(card, CR_INTR_CREG);
@@ -650,6 +655,12 @@ static int rsxx_pci_probe(struct pci_dev *dev,
650 } 655 }
651 656
652 /************* Setup Card Event Handler *************/ 657 /************* Setup Card Event Handler *************/
658 card->event_wq = create_singlethread_workqueue(DRIVER_NAME"_event");
659 if (!card->event_wq) {
660 dev_err(CARD_TO_DEV(card), "Failed card event setup.\n");
661 goto failed_event_handler;
662 }
663
653 INIT_WORK(&card->event_work, card_event_handler); 664 INIT_WORK(&card->event_work, card_event_handler);
654 665
655 st = rsxx_setup_dev(card); 666 st = rsxx_setup_dev(card);
@@ -688,9 +699,15 @@ static int rsxx_pci_probe(struct pci_dev *dev,
688 return 0; 699 return 0;
689 700
690failed_create_dev: 701failed_create_dev:
702 destroy_workqueue(card->event_wq);
703 card->event_wq = NULL;
704failed_event_handler:
691 rsxx_dma_destroy(card); 705 rsxx_dma_destroy(card);
692failed_dma_setup: 706failed_dma_setup:
693failed_compatiblity_check: 707failed_compatiblity_check:
708 destroy_workqueue(card->creg_ctrl.creg_wq);
709 card->creg_ctrl.creg_wq = NULL;
710failed_creg_setup:
694 spin_lock_irq(&card->irq_lock); 711 spin_lock_irq(&card->irq_lock);
695 rsxx_disable_ier_and_isr(card, CR_INTR_ALL); 712 rsxx_disable_ier_and_isr(card, CR_INTR_ALL);
696 spin_unlock_irq(&card->irq_lock); 713 spin_unlock_irq(&card->irq_lock);
diff --git a/drivers/block/rsxx/cregs.c b/drivers/block/rsxx/cregs.c
index 4b5c020a0a65..4914464c19fc 100644
--- a/drivers/block/rsxx/cregs.c
+++ b/drivers/block/rsxx/cregs.c
@@ -727,6 +727,11 @@ int rsxx_creg_setup(struct rsxx_cardinfo *card)
727{ 727{
728 card->creg_ctrl.active_cmd = NULL; 728 card->creg_ctrl.active_cmd = NULL;
729 729
730 card->creg_ctrl.creg_wq =
731 create_singlethread_workqueue(DRIVER_NAME"_creg");
732 if (!card->creg_ctrl.creg_wq)
733 return -ENOMEM;
734
730 INIT_WORK(&card->creg_ctrl.done_work, creg_cmd_done); 735 INIT_WORK(&card->creg_ctrl.done_work, creg_cmd_done);
731 mutex_init(&card->creg_ctrl.reset_lock); 736 mutex_init(&card->creg_ctrl.reset_lock);
732 INIT_LIST_HEAD(&card->creg_ctrl.queue); 737 INIT_LIST_HEAD(&card->creg_ctrl.queue);
diff --git a/drivers/block/rsxx/rsxx_priv.h b/drivers/block/rsxx/rsxx_priv.h
index 382e8bf5c03b..0dd62d966772 100644
--- a/drivers/block/rsxx/rsxx_priv.h
+++ b/drivers/block/rsxx/rsxx_priv.h
@@ -134,6 +134,7 @@ struct rsxx_cardinfo {
134 spinlock_t lock; 134 spinlock_t lock;
135 bool active; 135 bool active;
136 struct creg_cmd *active_cmd; 136 struct creg_cmd *active_cmd;
137 struct workqueue_struct *creg_wq;
137 struct work_struct done_work; 138 struct work_struct done_work;
138 struct list_head queue; 139 struct list_head queue;
139 unsigned int q_depth; 140 unsigned int q_depth;
@@ -154,6 +155,7 @@ struct rsxx_cardinfo {
154 int buf_len; 155 int buf_len;
155 } log; 156 } log;
156 157
158 struct workqueue_struct *event_wq;
157 struct work_struct event_work; 159 struct work_struct event_work;
158 unsigned int state; 160 unsigned int state;
159 u64 size8; 161 u64 size8;