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>
This commit is contained in:
committed by
Jens Axboe
parent
9138125bea
commit
a3299ab185
@ -163,12 +163,13 @@ static irqreturn_t rsxx_isr(int irq, void *pdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isr & CR_INTR_CREG) {
|
if (isr & CR_INTR_CREG) {
|
||||||
schedule_work(&card->creg_ctrl.done_work);
|
queue_work(card->creg_ctrl.creg_wq,
|
||||||
|
&card->creg_ctrl.done_work);
|
||||||
handled++;
|
handled++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isr & CR_INTR_EVENT) {
|
if (isr & CR_INTR_EVENT) {
|
||||||
schedule_work(&card->event_work);
|
queue_work(card->event_wq, &card->event_work);
|
||||||
rsxx_disable_ier_and_isr(card, CR_INTR_EVENT);
|
rsxx_disable_ier_and_isr(card, CR_INTR_EVENT);
|
||||||
handled++;
|
handled++;
|
||||||
}
|
}
|
||||||
@ -610,7 +611,11 @@ static int rsxx_pci_probe(struct pci_dev *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/************* Setup Processor Command Interface *************/
|
/************* Setup Processor Command Interface *************/
|
||||||
rsxx_creg_setup(card);
|
st = rsxx_creg_setup(card);
|
||||||
|
if (st) {
|
||||||
|
dev_err(CARD_TO_DEV(card), "Failed to setup creg interface.\n");
|
||||||
|
goto failed_creg_setup;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irq(&card->irq_lock);
|
spin_lock_irq(&card->irq_lock);
|
||||||
rsxx_enable_ier_and_isr(card, CR_INTR_CREG);
|
rsxx_enable_ier_and_isr(card, CR_INTR_CREG);
|
||||||
@ -650,6 +655,12 @@ static int rsxx_pci_probe(struct pci_dev *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/************* Setup Card Event Handler *************/
|
/************* Setup Card Event Handler *************/
|
||||||
|
card->event_wq = create_singlethread_workqueue(DRIVER_NAME"_event");
|
||||||
|
if (!card->event_wq) {
|
||||||
|
dev_err(CARD_TO_DEV(card), "Failed card event setup.\n");
|
||||||
|
goto failed_event_handler;
|
||||||
|
}
|
||||||
|
|
||||||
INIT_WORK(&card->event_work, card_event_handler);
|
INIT_WORK(&card->event_work, card_event_handler);
|
||||||
|
|
||||||
st = rsxx_setup_dev(card);
|
st = rsxx_setup_dev(card);
|
||||||
@ -688,9 +699,15 @@ static int rsxx_pci_probe(struct pci_dev *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
failed_create_dev:
|
failed_create_dev:
|
||||||
|
destroy_workqueue(card->event_wq);
|
||||||
|
card->event_wq = NULL;
|
||||||
|
failed_event_handler:
|
||||||
rsxx_dma_destroy(card);
|
rsxx_dma_destroy(card);
|
||||||
failed_dma_setup:
|
failed_dma_setup:
|
||||||
failed_compatiblity_check:
|
failed_compatiblity_check:
|
||||||
|
destroy_workqueue(card->creg_ctrl.creg_wq);
|
||||||
|
card->creg_ctrl.creg_wq = NULL;
|
||||||
|
failed_creg_setup:
|
||||||
spin_lock_irq(&card->irq_lock);
|
spin_lock_irq(&card->irq_lock);
|
||||||
rsxx_disable_ier_and_isr(card, CR_INTR_ALL);
|
rsxx_disable_ier_and_isr(card, CR_INTR_ALL);
|
||||||
spin_unlock_irq(&card->irq_lock);
|
spin_unlock_irq(&card->irq_lock);
|
||||||
|
@ -727,6 +727,11 @@ int rsxx_creg_setup(struct rsxx_cardinfo *card)
|
|||||||
{
|
{
|
||||||
card->creg_ctrl.active_cmd = NULL;
|
card->creg_ctrl.active_cmd = NULL;
|
||||||
|
|
||||||
|
card->creg_ctrl.creg_wq =
|
||||||
|
create_singlethread_workqueue(DRIVER_NAME"_creg");
|
||||||
|
if (!card->creg_ctrl.creg_wq)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
INIT_WORK(&card->creg_ctrl.done_work, creg_cmd_done);
|
INIT_WORK(&card->creg_ctrl.done_work, creg_cmd_done);
|
||||||
mutex_init(&card->creg_ctrl.reset_lock);
|
mutex_init(&card->creg_ctrl.reset_lock);
|
||||||
INIT_LIST_HEAD(&card->creg_ctrl.queue);
|
INIT_LIST_HEAD(&card->creg_ctrl.queue);
|
||||||
|
@ -134,6 +134,7 @@ struct rsxx_cardinfo {
|
|||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
bool active;
|
bool active;
|
||||||
struct creg_cmd *active_cmd;
|
struct creg_cmd *active_cmd;
|
||||||
|
struct workqueue_struct *creg_wq;
|
||||||
struct work_struct done_work;
|
struct work_struct done_work;
|
||||||
struct list_head queue;
|
struct list_head queue;
|
||||||
unsigned int q_depth;
|
unsigned int q_depth;
|
||||||
@ -154,6 +155,7 @@ struct rsxx_cardinfo {
|
|||||||
int buf_len;
|
int buf_len;
|
||||||
} log;
|
} log;
|
||||||
|
|
||||||
|
struct workqueue_struct *event_wq;
|
||||||
struct work_struct event_work;
|
struct work_struct event_work;
|
||||||
unsigned int state;
|
unsigned int state;
|
||||||
u64 size8;
|
u64 size8;
|
||||||
|
Reference in New Issue
Block a user