aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pm8001
diff options
context:
space:
mode:
authorSuresh Thiagarajan <Suresh.Thiagarajan@pmcs.com>2014-01-16 04:56:21 -0500
committerJames Bottomley <JBottomley@Parallels.com>2014-03-15 13:19:01 -0400
commit2b01d816f5f884d5ea16ab2498736b1221bc027c (patch)
tree5adfe6415c09702b8ae1a7d32adc28533d267459 /drivers/scsi/pm8001
parenteee0f03a547f50ca81a8d01ee9f1c84fecd1f64c (diff)
[SCSI] 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@gmail.com> Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Suresh Thiagarajan <Suresh.Thiagarajan@pmcs.com> Signed-off-by: Viswas G <viswas.g@pmcs.com> Acked-by: Jack Wang <xjtuwjp@gmail.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/pm8001')
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c84
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.h12
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.c84
3 files changed, 38 insertions, 142 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 561ca2c348d6..a97be015e52e 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)
2502 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); 2502 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
2503 ts->resp = SAS_TASK_UNDELIVERED; 2503 ts->resp = SAS_TASK_UNDELIVERED;
2504 ts->stat = SAS_QUEUE_FULL; 2504 ts->stat = SAS_QUEUE_FULL;
2505 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2505 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2506 mb();/*in order to force CPU ordering*/
2507 spin_unlock_irq(&pm8001_ha->lock);
2508 t->task_done(t);
2509 spin_lock_irq(&pm8001_ha->lock);
2510 return; 2506 return;
2511 } 2507 }
2512 break; 2508 break;
@@ -2522,11 +2518,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2522 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); 2518 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
2523 ts->resp = SAS_TASK_UNDELIVERED; 2519 ts->resp = SAS_TASK_UNDELIVERED;
2524 ts->stat = SAS_QUEUE_FULL; 2520 ts->stat = SAS_QUEUE_FULL;
2525 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2521 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2526 mb();/*ditto*/
2527 spin_unlock_irq(&pm8001_ha->lock);
2528 t->task_done(t);
2529 spin_lock_irq(&pm8001_ha->lock);
2530 return; 2522 return;
2531 } 2523 }
2532 break; 2524 break;
@@ -2550,11 +2542,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2550 IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY); 2542 IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY);
2551 ts->resp = SAS_TASK_UNDELIVERED; 2543 ts->resp = SAS_TASK_UNDELIVERED;
2552 ts->stat = SAS_QUEUE_FULL; 2544 ts->stat = SAS_QUEUE_FULL;
2553 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2545 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2554 mb();/* ditto*/
2555 spin_unlock_irq(&pm8001_ha->lock);
2556 t->task_done(t);
2557 spin_lock_irq(&pm8001_ha->lock);
2558 return; 2546 return;
2559 } 2547 }
2560 break; 2548 break;
@@ -2617,11 +2605,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2617 IO_DS_NON_OPERATIONAL); 2605 IO_DS_NON_OPERATIONAL);
2618 ts->resp = SAS_TASK_UNDELIVERED; 2606 ts->resp = SAS_TASK_UNDELIVERED;
2619 ts->stat = SAS_QUEUE_FULL; 2607 ts->stat = SAS_QUEUE_FULL;
2620 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2608 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2621 mb();/*ditto*/
2622 spin_unlock_irq(&pm8001_ha->lock);
2623 t->task_done(t);
2624 spin_lock_irq(&pm8001_ha->lock);
2625 return; 2609 return;
2626 } 2610 }
2627 break; 2611 break;
@@ -2641,11 +2625,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2641 IO_DS_IN_ERROR); 2625 IO_DS_IN_ERROR);
2642 ts->resp = SAS_TASK_UNDELIVERED; 2626 ts->resp = SAS_TASK_UNDELIVERED;
2643 ts->stat = SAS_QUEUE_FULL; 2627 ts->stat = SAS_QUEUE_FULL;
2644 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2628 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2645 mb();/*ditto*/
2646 spin_unlock_irq(&pm8001_ha->lock);
2647 t->task_done(t);
2648 spin_lock_irq(&pm8001_ha->lock);
2649 return; 2629 return;
2650 } 2630 }
2651 break; 2631 break;
@@ -2674,20 +2654,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2674 " resp 0x%x stat 0x%x but aborted by upper layer!\n", 2654 " resp 0x%x stat 0x%x but aborted by upper layer!\n",
2675 t, status, ts->resp, ts->stat)); 2655 t, status, ts->resp, ts->stat));
2676 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2656 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2677 } else if (t->uldd_task) { 2657 } else {
2678 spin_unlock_irqrestore(&t->task_state_lock, flags);
2679 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2680 mb();/* ditto */
2681 spin_unlock_irq(&pm8001_ha->lock);
2682 t->task_done(t);
2683 spin_lock_irq(&pm8001_ha->lock);
2684 } else if (!t->uldd_task) {
2685 spin_unlock_irqrestore(&t->task_state_lock, flags); 2658 spin_unlock_irqrestore(&t->task_state_lock, flags);
2686 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2659 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2687 mb();/*ditto*/
2688 spin_unlock_irq(&pm8001_ha->lock);
2689 t->task_done(t);
2690 spin_lock_irq(&pm8001_ha->lock);
2691 } 2660 }
2692} 2661}
2693 2662
@@ -2796,11 +2765,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
2796 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); 2765 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
2797 ts->resp = SAS_TASK_COMPLETE; 2766 ts->resp = SAS_TASK_COMPLETE;
2798 ts->stat = SAS_QUEUE_FULL; 2767 ts->stat = SAS_QUEUE_FULL;
2799 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2768 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2800 mb();/*ditto*/
2801 spin_unlock_irq(&pm8001_ha->lock);
2802 t->task_done(t);
2803 spin_lock_irq(&pm8001_ha->lock);
2804 return; 2769 return;
2805 } 2770 }
2806 break; 2771 break;
@@ -2909,20 +2874,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
2909 " resp 0x%x stat 0x%x but aborted by upper layer!\n", 2874 " resp 0x%x stat 0x%x but aborted by upper layer!\n",
2910 t, event, ts->resp, ts->stat)); 2875 t, event, ts->resp, ts->stat));
2911 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2876 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2912 } else if (t->uldd_task) { 2877 } else {
2913 spin_unlock_irqrestore(&t->task_state_lock, flags);
2914 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2915 mb();/* ditto */
2916 spin_unlock_irq(&pm8001_ha->lock);
2917 t->task_done(t);
2918 spin_lock_irq(&pm8001_ha->lock);
2919 } else if (!t->uldd_task) {
2920 spin_unlock_irqrestore(&t->task_state_lock, flags); 2878 spin_unlock_irqrestore(&t->task_state_lock, flags);
2921 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2879 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2922 mb();/*ditto*/
2923 spin_unlock_irq(&pm8001_ha->lock);
2924 t->task_done(t);
2925 spin_lock_irq(&pm8001_ha->lock);
2926 } 2880 }
2927} 2881}
2928 2882
@@ -4467,23 +4421,11 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
4467 " stat 0x%x but aborted by upper layer " 4421 " stat 0x%x but aborted by upper layer "
4468 "\n", task, ts->resp, ts->stat)); 4422 "\n", task, ts->resp, ts->stat));
4469 pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); 4423 pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
4470 } else if (task->uldd_task) { 4424 } else {
4471 spin_unlock_irqrestore(&task->task_state_lock,
4472 flags);
4473 pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
4474 mb();/* ditto */
4475 spin_unlock_irq(&pm8001_ha->lock);
4476 task->task_done(task);
4477 spin_lock_irq(&pm8001_ha->lock);
4478 return 0;
4479 } else if (!task->uldd_task) {
4480 spin_unlock_irqrestore(&task->task_state_lock, 4425 spin_unlock_irqrestore(&task->task_state_lock,
4481 flags); 4426 flags);
4482 pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); 4427 pm8001_ccb_task_free_done(pm8001_ha, task,
4483 mb();/*ditto*/ 4428 ccb, tag);
4484 spin_unlock_irq(&pm8001_ha->lock);
4485 task->task_done(task);
4486 spin_lock_irq(&pm8001_ha->lock);
4487 return 0; 4429 return 0;
4488 } 4430 }
4489 } 4431 }
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 6c5fd5ee22d3..1ee06f21803b 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);
708/* ctl shared API */ 708/* ctl shared API */
709extern struct device_attribute *pm8001_host_attrs[]; 709extern struct device_attribute *pm8001_host_attrs[];
710 710
711static inline void
712pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
713 struct sas_task *task, struct pm8001_ccb_info *ccb,
714 u32 ccb_idx)
715{
716 pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb_idx);
717 smp_mb(); /*in order to force CPU ordering*/
718 spin_unlock(&pm8001_ha->lock);
719 task->task_done(task);
720 spin_lock(&pm8001_ha->lock);
721}
722
711#endif 723#endif
712 724
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 9b5414249cc4..d70587f96184 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)
2168 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); 2168 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
2169 ts->resp = SAS_TASK_UNDELIVERED; 2169 ts->resp = SAS_TASK_UNDELIVERED;
2170 ts->stat = SAS_QUEUE_FULL; 2170 ts->stat = SAS_QUEUE_FULL;
2171 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2171 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2172 mb();/*in order to force CPU ordering*/
2173 spin_unlock_irq(&pm8001_ha->lock);
2174 t->task_done(t);
2175 spin_lock_irq(&pm8001_ha->lock);
2176 return; 2172 return;
2177 } 2173 }
2178 break; 2174 break;
@@ -2188,11 +2184,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2188 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); 2184 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
2189 ts->resp = SAS_TASK_UNDELIVERED; 2185 ts->resp = SAS_TASK_UNDELIVERED;
2190 ts->stat = SAS_QUEUE_FULL; 2186 ts->stat = SAS_QUEUE_FULL;
2191 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2187 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2192 mb();/*ditto*/
2193 spin_unlock_irq(&pm8001_ha->lock);
2194 t->task_done(t);
2195 spin_lock_irq(&pm8001_ha->lock);
2196 return; 2188 return;
2197 } 2189 }
2198 break; 2190 break;
@@ -2214,11 +2206,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2214 IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY); 2206 IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY);
2215 ts->resp = SAS_TASK_UNDELIVERED; 2207 ts->resp = SAS_TASK_UNDELIVERED;
2216 ts->stat = SAS_QUEUE_FULL; 2208 ts->stat = SAS_QUEUE_FULL;
2217 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2209 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2218 mb();/* ditto*/
2219 spin_unlock_irq(&pm8001_ha->lock);
2220 t->task_done(t);
2221 spin_lock_irq(&pm8001_ha->lock);
2222 return; 2210 return;
2223 } 2211 }
2224 break; 2212 break;
@@ -2281,11 +2269,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2281 IO_DS_NON_OPERATIONAL); 2269 IO_DS_NON_OPERATIONAL);
2282 ts->resp = SAS_TASK_UNDELIVERED; 2270 ts->resp = SAS_TASK_UNDELIVERED;
2283 ts->stat = SAS_QUEUE_FULL; 2271 ts->stat = SAS_QUEUE_FULL;
2284 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2272 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2285 mb();/*ditto*/
2286 spin_unlock_irq(&pm8001_ha->lock);
2287 t->task_done(t);
2288 spin_lock_irq(&pm8001_ha->lock);
2289 return; 2273 return;
2290 } 2274 }
2291 break; 2275 break;
@@ -2305,11 +2289,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2305 IO_DS_IN_ERROR); 2289 IO_DS_IN_ERROR);
2306 ts->resp = SAS_TASK_UNDELIVERED; 2290 ts->resp = SAS_TASK_UNDELIVERED;
2307 ts->stat = SAS_QUEUE_FULL; 2291 ts->stat = SAS_QUEUE_FULL;
2308 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2292 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2309 mb();/*ditto*/
2310 spin_unlock_irq(&pm8001_ha->lock);
2311 t->task_done(t);
2312 spin_lock_irq(&pm8001_ha->lock);
2313 return; 2293 return;
2314 } 2294 }
2315 break; 2295 break;
@@ -2338,20 +2318,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
2338 " resp 0x%x stat 0x%x but aborted by upper layer!\n", 2318 " resp 0x%x stat 0x%x but aborted by upper layer!\n",
2339 t, status, ts->resp, ts->stat)); 2319 t, status, ts->resp, ts->stat));
2340 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2320 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2341 } else if (t->uldd_task) { 2321 } else {
2342 spin_unlock_irqrestore(&t->task_state_lock, flags);
2343 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2344 mb();/* ditto */
2345 spin_unlock_irq(&pm8001_ha->lock);
2346 t->task_done(t);
2347 spin_lock_irq(&pm8001_ha->lock);
2348 } else if (!t->uldd_task) {
2349 spin_unlock_irqrestore(&t->task_state_lock, flags); 2322 spin_unlock_irqrestore(&t->task_state_lock, flags);
2350 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2323 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2351 mb();/*ditto*/
2352 spin_unlock_irq(&pm8001_ha->lock);
2353 t->task_done(t);
2354 spin_lock_irq(&pm8001_ha->lock);
2355 } 2324 }
2356} 2325}
2357 2326
@@ -2463,11 +2432,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
2463 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); 2432 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
2464 ts->resp = SAS_TASK_COMPLETE; 2433 ts->resp = SAS_TASK_COMPLETE;
2465 ts->stat = SAS_QUEUE_FULL; 2434 ts->stat = SAS_QUEUE_FULL;
2466 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2435 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2467 mb();/*ditto*/
2468 spin_unlock_irq(&pm8001_ha->lock);
2469 t->task_done(t);
2470 spin_lock_irq(&pm8001_ha->lock);
2471 return; 2436 return;
2472 } 2437 }
2473 break; 2438 break;
@@ -2589,20 +2554,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
2589 " resp 0x%x stat 0x%x but aborted by upper layer!\n", 2554 " resp 0x%x stat 0x%x but aborted by upper layer!\n",
2590 t, event, ts->resp, ts->stat)); 2555 t, event, ts->resp, ts->stat));
2591 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2556 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2592 } else if (t->uldd_task) { 2557 } else {
2593 spin_unlock_irqrestore(&t->task_state_lock, flags);
2594 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
2595 mb();/* ditto */
2596 spin_unlock_irq(&pm8001_ha->lock);
2597 t->task_done(t);
2598 spin_lock_irq(&pm8001_ha->lock);
2599 } else if (!t->uldd_task) {
2600 spin_unlock_irqrestore(&t->task_state_lock, flags); 2558 spin_unlock_irqrestore(&t->task_state_lock, flags);
2601 pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); 2559 pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
2602 mb();/*ditto*/
2603 spin_unlock_irq(&pm8001_ha->lock);
2604 t->task_done(t);
2605 spin_lock_irq(&pm8001_ha->lock);
2606 } 2560 }
2607} 2561}
2608 2562
@@ -4297,23 +4251,11 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
4297 "\n", task, ts->resp, ts->stat)); 4251 "\n", task, ts->resp, ts->stat));
4298 pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); 4252 pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
4299 return 0; 4253 return 0;
4300 } else if (task->uldd_task) { 4254 } else {
4301 spin_unlock_irqrestore(&task->task_state_lock,
4302 flags);
4303 pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
4304 mb();/* ditto */
4305 spin_unlock_irq(&pm8001_ha->lock);
4306 task->task_done(task);
4307 spin_lock_irq(&pm8001_ha->lock);
4308 return 0;
4309 } else if (!task->uldd_task) {
4310 spin_unlock_irqrestore(&task->task_state_lock, 4255 spin_unlock_irqrestore(&task->task_state_lock,
4311 flags); 4256 flags);
4312 pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); 4257 pm8001_ccb_task_free_done(pm8001_ha, task,
4313 mb();/*ditto*/ 4258 ccb, tag);
4314 spin_unlock_irq(&pm8001_ha->lock);
4315 task->task_done(task);
4316 spin_lock_irq(&pm8001_ha->lock);
4317 return 0; 4259 return 0;
4318 } 4260 }
4319 } 4261 }