forked from Minki/linux
[SCSI] mvsas: bug fix of dead lock
TMF task should be issued with Interrupt Disabled, or Deadlock may take place. Clean-up unused parameters and conditonal lock. Signed-off-by: Ying Chu <jasonchu@marvell.com> Signed-off-by: Andy Yan <ayan@marvell.com> Signed-off-by: Ke Wei <kewei@marvell.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
2b288133ab
commit
0b84b7094e
@ -868,8 +868,8 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi,
|
|||||||
|
|
||||||
#define DEV_IS_GONE(mvi_dev) ((!mvi_dev || (mvi_dev->dev_type == NO_DEVICE)))
|
#define DEV_IS_GONE(mvi_dev) ((!mvi_dev || (mvi_dev->dev_type == NO_DEVICE)))
|
||||||
static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
|
static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
|
||||||
struct completion *completion, int lock,
|
struct completion *completion,int is_tmf,
|
||||||
int is_tmf, struct mvs_tmf_task *tmf)
|
struct mvs_tmf_task *tmf)
|
||||||
{
|
{
|
||||||
struct domain_device *dev = task->dev;
|
struct domain_device *dev = task->dev;
|
||||||
struct mvs_info *mvi;
|
struct mvs_info *mvi;
|
||||||
@ -892,8 +892,7 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
|
|||||||
|
|
||||||
mvi = mvs_find_dev_mvi(task->dev);
|
mvi = mvs_find_dev_mvi(task->dev);
|
||||||
|
|
||||||
if (lock)
|
spin_lock_irqsave(&mvi->lock, flags);
|
||||||
spin_lock_irqsave(&mvi->lock, flags);
|
|
||||||
do {
|
do {
|
||||||
dev = t->dev;
|
dev = t->dev;
|
||||||
mvi_dev = (struct mvs_device *)dev->lldd_dev;
|
mvi_dev = (struct mvs_device *)dev->lldd_dev;
|
||||||
@ -1020,15 +1019,14 @@ out_done:
|
|||||||
MVS_CHIP_DISP->start_delivery(mvi,
|
MVS_CHIP_DISP->start_delivery(mvi,
|
||||||
(mvi->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1));
|
(mvi->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1));
|
||||||
}
|
}
|
||||||
if (lock)
|
spin_unlock_irqrestore(&mvi->lock, flags);
|
||||||
spin_unlock_irqrestore(&mvi->lock, flags);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mvs_queue_command(struct sas_task *task, const int num,
|
int mvs_queue_command(struct sas_task *task, const int num,
|
||||||
gfp_t gfp_flags)
|
gfp_t gfp_flags)
|
||||||
{
|
{
|
||||||
return mvs_task_exec(task, num, gfp_flags, NULL, 1, 0, NULL);
|
return mvs_task_exec(task, num, gfp_flags, NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mvs_slot_free(struct mvs_info *mvi, u32 rx_desc)
|
static void mvs_slot_free(struct mvs_info *mvi, u32 rx_desc)
|
||||||
@ -1448,7 +1446,7 @@ static int mvs_exec_internal_tmf_task(struct domain_device *dev,
|
|||||||
task->timer.expires = jiffies + MVS_TASK_TIMEOUT*HZ;
|
task->timer.expires = jiffies + MVS_TASK_TIMEOUT*HZ;
|
||||||
add_timer(&task->timer);
|
add_timer(&task->timer);
|
||||||
|
|
||||||
res = mvs_task_exec(task, 1, GFP_KERNEL, NULL, 0, 1, tmf);
|
res = mvs_task_exec(task, 1, GFP_KERNEL, NULL, 1, tmf);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
del_timer(&task->timer);
|
del_timer(&task->timer);
|
||||||
|
Loading…
Reference in New Issue
Block a user