aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorjack wang <jack_wang@usish.com>2009-12-07 04:22:36 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-10 10:58:54 -0500
commit9e79e12554d651f586ff2364e69a8e9cd5e9dbcb (patch)
tree034b6b41675573b5458501a04a8c635229c33fcd /drivers/scsi
parentedd163687ea59f01d6b43c9e1fdaa0126fa30191 (diff)
[SCSI] pm8001: Fix for sata io circular lock dependency.
This patch fix for sata IO circular lock dependency. When we call task_done for SATA IO, we have got pm8001_ha->lock ,and in sas_ata_task_done, it will get (dev->sata_dev.ap->lock. then cause circular lock dependency .So we should drop pm8001_ha->lock when we call task_done for SATA task. Signed-off-by: Jack Wang <jack_wang@usish.com> Signed-off-by: Lindar Liu <lindar_liu@usish.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index a3de306b9045..68695b72e1ef 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1901,7 +1901,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
1901{ 1901{
1902 struct sas_task *t; 1902 struct sas_task *t;
1903 struct pm8001_ccb_info *ccb; 1903 struct pm8001_ccb_info *ccb;
1904 unsigned long flags; 1904 unsigned long flags = 0;
1905 u32 param; 1905 u32 param;
1906 u32 status; 1906 u32 status;
1907 u32 tag; 1907 u32 tag;
@@ -2040,7 +2040,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2040 ts->stat = SAS_QUEUE_FULL; 2040 ts->stat = SAS_QUEUE_FULL;
2041 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2041 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2042 mb();/*in order to force CPU ordering*/ 2042 mb();/*in order to force CPU ordering*/
2043 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
2043 t->task_done(t); 2044 t->task_done(t);
2045 spin_lock_irqsave(&pm8001_ha->lock, flags);
2044 return; 2046 return;
2045 } 2047 }
2046 break; 2048 break;
@@ -2058,7 +2060,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2058 ts->stat = SAS_QUEUE_FULL; 2060 ts->stat = SAS_QUEUE_FULL;
2059 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2061 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2060 mb();/*ditto*/ 2062 mb();/*ditto*/
2063 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
2061 t->task_done(t); 2064 t->task_done(t);
2065 spin_lock_irqsave(&pm8001_ha->lock, flags);
2062 return; 2066 return;
2063 } 2067 }
2064 break; 2068 break;
@@ -2084,7 +2088,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2084 ts->stat = SAS_QUEUE_FULL; 2088 ts->stat = SAS_QUEUE_FULL;
2085 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2089 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2086 mb();/* ditto*/ 2090 mb();/* ditto*/
2091 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
2087 t->task_done(t); 2092 t->task_done(t);
2093 spin_lock_irqsave(&pm8001_ha->lock, flags);
2088 return; 2094 return;
2089 } 2095 }
2090 break; 2096 break;
@@ -2149,7 +2155,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2149 ts->stat = SAS_QUEUE_FULL; 2155 ts->stat = SAS_QUEUE_FULL;
2150 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2156 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2151 mb();/*ditto*/ 2157 mb();/*ditto*/
2158 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
2152 t->task_done(t); 2159 t->task_done(t);
2160 spin_lock_irqsave(&pm8001_ha->lock, flags);
2153 return; 2161 return;
2154 } 2162 }
2155 break; 2163 break;
@@ -2171,7 +2179,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2171 ts->stat = SAS_QUEUE_FULL; 2179 ts->stat = SAS_QUEUE_FULL;
2172 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2180 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2173 mb();/*ditto*/ 2181 mb();/*ditto*/
2182 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
2174 t->task_done(t); 2183 t->task_done(t);
2184 spin_lock_irqsave(&pm8001_ha->lock, flags);
2175 return; 2185 return;
2176 } 2186 }
2177 break; 2187 break;
@@ -2200,11 +2210,20 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2200 " resp 0x%x stat 0x%x but aborted by upper layer!\n", 2210 " resp 0x%x stat 0x%x but aborted by upper layer!\n",
2201 t, status, ts->resp, ts->stat)); 2211 t, status, ts->resp, ts->stat));
2202 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2212 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2203 } else { 2213 } else if (t->uldd_task) {
2204 spin_unlock_irqrestore(&t->task_state_lock, flags); 2214 spin_unlock_irqrestore(&t->task_state_lock, flags);
2205 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2215 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2206 mb();/* ditto */ 2216 mb();/* ditto */
2217 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
2218 t->task_done(t);
2219 spin_lock_irqsave(&pm8001_ha->lock, flags);
2220 } else if (!t->uldd_task) {
2221 spin_unlock_irqrestore(&t->task_state_lock, flags);
2222 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2223 mb();/*ditto*/
2224 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
2207 t->task_done(t); 2225 t->task_done(t);
2226 spin_lock_irqsave(&pm8001_ha->lock, flags);
2208 } 2227 }
2209} 2228}
2210 2229
@@ -2212,7 +2231,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2212static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) 2231static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
2213{ 2232{
2214 struct sas_task *t; 2233 struct sas_task *t;
2215 unsigned long flags; 2234 unsigned long flags = 0;
2216 struct task_status_struct *ts; 2235 struct task_status_struct *ts;
2217 struct pm8001_ccb_info *ccb; 2236 struct pm8001_ccb_info *ccb;
2218 struct pm8001_device *pm8001_dev; 2237 struct pm8001_device *pm8001_dev;
@@ -2292,7 +2311,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
2292 ts->stat = SAS_QUEUE_FULL; 2311 ts->stat = SAS_QUEUE_FULL;
2293 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2312 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2294 mb();/*ditto*/ 2313 mb();/*ditto*/
2314 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
2295 t->task_done(t); 2315 t->task_done(t);
2316 spin_lock_irqsave(&pm8001_ha->lock, flags);
2296 return; 2317 return;
2297 } 2318 }
2298 break; 2319 break;
@@ -2401,11 +2422,20 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
2401 " resp 0x%x stat 0x%x but aborted by upper layer!\n", 2422 " resp 0x%x stat 0x%x but aborted by upper layer!\n",
2402 t, event, ts->resp, ts->stat)); 2423 t, event, ts->resp, ts->stat));
2403 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2424 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2404 } else { 2425 } else if (t->uldd_task) {
2405 spin_unlock_irqrestore(&t->task_state_lock, flags); 2426 spin_unlock_irqrestore(&t->task_state_lock, flags);
2406 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2427 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2407 mb();/* in order to force CPU ordering */ 2428 mb();/* ditto */
2429 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
2430 t->task_done(t);
2431 spin_lock_irqsave(&pm8001_ha->lock, flags);
2432 } else if (!t->uldd_task) {
2433 spin_unlock_irqrestore(&t->task_state_lock, flags);
2434 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2435 mb();/*ditto*/
2436 spin_unlock_irqrestore(&pm8001_ha->lock, flags);
2408 t->task_done(t); 2437 t->task_done(t);
2438 spin_lock_irqsave(&pm8001_ha->lock, flags);
2409 } 2439 }
2410} 2440}
2411 2441