Re: [PATCH V2] pm80xx: Spinlock fix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 01/16/2014 11:15 AM, Viswas G wrote:
> From dfaae38ba7b6b7260fb3209d2dd12d70f0a8e306 Mon Sep 17 00:00:00 2001
> From: Suresh Thiagarajan <Suresh.Thiagarajan@xxxxxxxx>
> Date: Thu, 16 Jan 2014 15:26:21 +0530
> Subject: [PATCH V2] pm80xx: Spinlock fix
> 
> spin_lock_irqsave for the HBA lock is called in one function where flag
> is local to that function. Another function is called from the first
> function where lock has to be released using spin_unlock_irqrestore for 
> calling task_done of libsas. In the second function also flag is declared
> and used. For calling task_done there is no need to enable the irq. So 
> instead of using spin_lock_irqsave and spin_unlock_irqrestore, spin_lock
> and spin_unlock is used now. This also avoids passing the flags across all
> the functions where HBA lock is being used. Also removed redundant code. 
> 
> 
> Reported-by: Jason Seba <jason.seba42@xxxxxxxxx>
> Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx>
> Signed-off-by: Suresh Thiagarajan <Suresh.Thiagarajan@xxxxxxxx>
> Signed-off-by: Viswas G <viswas.g@xxxxxxxx>

Looks good to me, thanks.
Acked-by: Jack Wang <xjtuwjp@xxxxxxxxx>
> ---
>  drivers/scsi/pm8001/pm8001_hwi.c |   84 ++++++--------------------------------
>  drivers/scsi/pm8001/pm8001_sas.h |   12 +++++
>  drivers/scsi/pm8001/pm80xx_hwi.c |   84 ++++++--------------------------------
>  3 files changed, 38 insertions(+), 142 deletions(-)
> 
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 46ace52..d6a4b17 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -2502,11 +2502,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
>  			ts->resp = SAS_TASK_UNDELIVERED;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/*in order to force CPU ordering*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2522,11 +2518,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
>  			ts->resp = SAS_TASK_UNDELIVERED;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/*ditto*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2550,11 +2542,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  				IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY);
>  			ts->resp = SAS_TASK_UNDELIVERED;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/* ditto*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2617,11 +2605,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  				    IO_DS_NON_OPERATIONAL);
>  			ts->resp = SAS_TASK_UNDELIVERED;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/*ditto*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2641,11 +2625,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  				    IO_DS_IN_ERROR);
>  			ts->resp = SAS_TASK_UNDELIVERED;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/*ditto*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2674,20 +2654,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  			" resp 0x%x stat 0x%x but aborted by upper layer!\n",
>  			t, status, ts->resp, ts->stat));
>  		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -	} else if (t->uldd_task) {
> -		spin_unlock_irqrestore(&t->task_state_lock, flags);
> -		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -		mb();/* ditto */
> -		spin_unlock_irq(&pm8001_ha->lock);
> -		t->task_done(t);
> -		spin_lock_irq(&pm8001_ha->lock);
> -	} else if (!t->uldd_task) {
> +	} else {
>  		spin_unlock_irqrestore(&t->task_state_lock, flags);
> -		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -		mb();/*ditto*/
> -		spin_unlock_irq(&pm8001_ha->lock);
> -		t->task_done(t);
> -		spin_lock_irq(&pm8001_ha->lock);
> +		pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  	}
>  }
>  
> @@ -2796,11 +2765,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
>  				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
>  			ts->resp = SAS_TASK_COMPLETE;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/*ditto*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2909,20 +2874,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
>  			" resp 0x%x stat 0x%x but aborted by upper layer!\n",
>  			t, event, ts->resp, ts->stat));
>  		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -	} else if (t->uldd_task) {
> -		spin_unlock_irqrestore(&t->task_state_lock, flags);
> -		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -		mb();/* ditto */
> -		spin_unlock_irq(&pm8001_ha->lock);
> -		t->task_done(t);
> -		spin_lock_irq(&pm8001_ha->lock);
> -	} else if (!t->uldd_task) {
> +	} else {
>  		spin_unlock_irqrestore(&t->task_state_lock, flags);
> -		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -		mb();/*ditto*/
> -		spin_unlock_irq(&pm8001_ha->lock);
> -		t->task_done(t);
> -		spin_lock_irq(&pm8001_ha->lock);
> +		pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  	}
>  }
>  
> @@ -4467,23 +4421,11 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>  					" stat 0x%x but aborted by upper layer "
>  					"\n", task, ts->resp, ts->stat));
>  				pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
> -			} else if (task->uldd_task) {
> -				spin_unlock_irqrestore(&task->task_state_lock,
> -							flags);
> -				pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
> -				mb();/* ditto */
> -				spin_unlock_irq(&pm8001_ha->lock);
> -				task->task_done(task);
> -				spin_lock_irq(&pm8001_ha->lock);
> -				return 0;
> -			} else if (!task->uldd_task) {
> +			} else {
>  				spin_unlock_irqrestore(&task->task_state_lock,
>  							flags);
> -				pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
> -				mb();/*ditto*/
> -				spin_unlock_irq(&pm8001_ha->lock);
> -				task->task_done(task);
> -				spin_lock_irq(&pm8001_ha->lock);
> +				pm8001_ccb_task_free_done(pm8001_ha, task,
> +								ccb, tag);
>  				return 0;
>  			}
>  		}
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index 6c5fd5e..1ee06f2 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -708,5 +708,17 @@ ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf);
>  /* ctl shared API */
>  extern struct device_attribute *pm8001_host_attrs[];
>  
> +static inline void
> +pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
> +			struct sas_task *task, struct pm8001_ccb_info *ccb,
> +			u32 ccb_idx)
> +{
> +	pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb_idx);
> +	smp_mb(); /*in order to force CPU ordering*/
> +	spin_unlock(&pm8001_ha->lock);
> +	task->task_done(task);
> +	spin_lock(&pm8001_ha->lock);
> +}
> +
>  #endif
>  
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 65de79c..617c37f 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -2168,11 +2168,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
>  			ts->resp = SAS_TASK_UNDELIVERED;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/*in order to force CPU ordering*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2188,11 +2184,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
>  			ts->resp = SAS_TASK_UNDELIVERED;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/*ditto*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2214,11 +2206,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  				IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY);
>  			ts->resp = SAS_TASK_UNDELIVERED;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/* ditto*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2281,11 +2269,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  					IO_DS_NON_OPERATIONAL);
>  			ts->resp = SAS_TASK_UNDELIVERED;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/*ditto*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2305,11 +2289,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  					IO_DS_IN_ERROR);
>  			ts->resp = SAS_TASK_UNDELIVERED;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/*ditto*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2338,20 +2318,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  			" resp 0x%x stat 0x%x but aborted by upper layer!\n",
>  			t, status, ts->resp, ts->stat));
>  		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -	} else if (t->uldd_task) {
> -		spin_unlock_irqrestore(&t->task_state_lock, flags);
> -		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -		mb();/* ditto */
> -		spin_unlock_irq(&pm8001_ha->lock);
> -		t->task_done(t);
> -		spin_lock_irq(&pm8001_ha->lock);
> -	} else if (!t->uldd_task) {
> +	} else {
>  		spin_unlock_irqrestore(&t->task_state_lock, flags);
> -		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -		mb();/*ditto*/
> -		spin_unlock_irq(&pm8001_ha->lock);
> -		t->task_done(t);
> -		spin_lock_irq(&pm8001_ha->lock);
> +		pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  	}
>  }
>  
> @@ -2463,11 +2432,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
>  				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
>  			ts->resp = SAS_TASK_COMPLETE;
>  			ts->stat = SAS_QUEUE_FULL;
> -			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -			mb();/*ditto*/
> -			spin_unlock_irq(&pm8001_ha->lock);
> -			t->task_done(t);
> -			spin_lock_irq(&pm8001_ha->lock);
> +			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  			return;
>  		}
>  		break;
> @@ -2589,20 +2554,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
>  			" resp 0x%x stat 0x%x but aborted by upper layer!\n",
>  			t, event, ts->resp, ts->stat));
>  		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -	} else if (t->uldd_task) {
> -		spin_unlock_irqrestore(&t->task_state_lock, flags);
> -		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -		mb();/* ditto */
> -		spin_unlock_irq(&pm8001_ha->lock);
> -		t->task_done(t);
> -		spin_lock_irq(&pm8001_ha->lock);
> -	} else if (!t->uldd_task) {
> +	} else {
>  		spin_unlock_irqrestore(&t->task_state_lock, flags);
> -		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -		mb();/*ditto*/
> -		spin_unlock_irq(&pm8001_ha->lock);
> -		t->task_done(t);
> -		spin_lock_irq(&pm8001_ha->lock);
> +		pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
>  	}
>  }
>  
> @@ -4297,23 +4251,11 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>  					"\n", task, ts->resp, ts->stat));
>  				pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
>  				return 0;
> -			} else if (task->uldd_task) {
> -				spin_unlock_irqrestore(&task->task_state_lock,
> -							flags);
> -				pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
> -				mb();/* ditto */
> -				spin_unlock_irq(&pm8001_ha->lock);
> -				task->task_done(task);
> -				spin_lock_irq(&pm8001_ha->lock);
> -				return 0;
> -			} else if (!task->uldd_task) {
> +			} else {
>  				spin_unlock_irqrestore(&task->task_state_lock,
>  							flags);
> -				pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
> -				mb();/*ditto*/
> -				spin_unlock_irq(&pm8001_ha->lock);
> -				task->task_done(task);
> -				spin_lock_irq(&pm8001_ha->lock);
> +				pm8001_ccb_task_free_done(pm8001_ha, task,
> +								ccb, tag);
>  				return 0;
>  			}
>  		}
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux