]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: zfcp: avoid false ERP complete task due to semaphore race. | |
3 | References: bnc#484767,LTC#55250 | |
4 | ||
5 | Symptom: The adapter is not able to perform an initial exchange config. | |
6 | Problem: The ERP thread is performing a task before it is executing the | |
7 | corresponding down on the semaphore. The response handler of the | |
8 | just started exchange config should wait for the completion by | |
9 | performing a down on this semaphore. Since this semaphore is still | |
10 | positive from the ERP enqueue the handler won't wait and therefore | |
11 | the exchange config will always fail leaving the adapter in error. | |
12 | Solution: Perform the down on the semaphore before starting an ERP task. | |
13 | This is the logically correct order. Only walk the ERP loop | |
14 | if there is a task to perform. | |
15 | ||
16 | Acked-by: John Jolly <jjolly@suse.de> | |
17 | ||
18 | --- | |
19 | drivers/s390/scsi/zfcp_erp.c | 10 ++++++---- | |
20 | 1 file changed, 6 insertions(+), 4 deletions(-) | |
21 | ||
22 | Index: linux-sles11/drivers/s390/scsi/zfcp_erp.c | |
23 | =================================================================== | |
24 | --- linux-sles11.orig/drivers/s390/scsi/zfcp_erp.c | |
25 | +++ linux-sles11/drivers/s390/scsi/zfcp_erp.c | |
26 | @@ -1310,6 +1310,7 @@ static int zfcp_erp_thread(void *data) | |
27 | struct list_head *next; | |
28 | struct zfcp_erp_action *act; | |
29 | unsigned long flags; | |
30 | + int ignore; | |
31 | ||
32 | daemonize("zfcperp%s", adapter->ccw_device->dev.bus_id); | |
33 | /* Block all signals */ | |
34 | @@ -1319,6 +1320,11 @@ static int zfcp_erp_thread(void *data) | |
35 | ||
36 | while (!(atomic_read(&adapter->status) & | |
37 | ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL)) { | |
38 | + | |
39 | + zfcp_rec_dbf_event_thread_lock(4, adapter); | |
40 | + ignore = down_interruptible(&adapter->erp_ready_sem); | |
41 | + zfcp_rec_dbf_event_thread_lock(5, adapter); | |
42 | + | |
43 | write_lock_irqsave(&adapter->erp_lock, flags); | |
44 | next = adapter->erp_ready_head.next; | |
45 | write_unlock_irqrestore(&adapter->erp_lock, flags); | |
46 | @@ -1330,10 +1336,6 @@ static int zfcp_erp_thread(void *data) | |
47 | if (zfcp_erp_strategy(act) != ZFCP_ERP_DISMISSED) | |
48 | zfcp_erp_wakeup(adapter); | |
49 | } | |
50 | - | |
51 | - zfcp_rec_dbf_event_thread_lock(4, adapter); | |
52 | - down_interruptible(&adapter->erp_ready_sem); | |
53 | - zfcp_rec_dbf_event_thread_lock(5, adapter); | |
54 | } | |
55 | ||
56 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); |