aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/scsi/zfcp_aux.c4
-rw-r--r--drivers/s390/scsi/zfcp_def.h6
-rw-r--r--drivers/s390/scsi/zfcp_erp.c62
3 files changed, 27 insertions, 45 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index ed9a8a1517c6..e8f39f02bc3b 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -529,7 +529,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
529 goto generic_services_failed; 529 goto generic_services_failed;
530 530
531 init_waitqueue_head(&adapter->remove_wq); 531 init_waitqueue_head(&adapter->remove_wq);
532 init_waitqueue_head(&adapter->erp_thread_wqh); 532 init_waitqueue_head(&adapter->erp_ready_wq);
533 init_waitqueue_head(&adapter->erp_done_wqh); 533 init_waitqueue_head(&adapter->erp_done_wqh);
534 534
535 INIT_LIST_HEAD(&adapter->port_list_head); 535 INIT_LIST_HEAD(&adapter->port_list_head);
@@ -541,8 +541,6 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
541 rwlock_init(&adapter->erp_lock); 541 rwlock_init(&adapter->erp_lock);
542 rwlock_init(&adapter->abort_lock); 542 rwlock_init(&adapter->abort_lock);
543 543
544 sema_init(&adapter->erp_ready_sem, 0);
545
546 INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler); 544 INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
547 INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later); 545 INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later);
548 546
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 9a8ff0553421..ce65d88e280c 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -222,8 +222,6 @@ struct zfcp_ls_adisc {
222#define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002 222#define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002
223#define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008 223#define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008
224#define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010 224#define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010
225#define ZFCP_STATUS_ADAPTER_ERP_THREAD_UP 0x00000020
226#define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL 0x00000080
227#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100 225#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100
228#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200 226#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200
229 227
@@ -481,10 +479,9 @@ struct zfcp_adapter {
481 atomic_t status; /* status of this adapter */ 479 atomic_t status; /* status of this adapter */
482 struct list_head erp_ready_head; /* error recovery for this 480 struct list_head erp_ready_head; /* error recovery for this
483 adapter/devices */ 481 adapter/devices */
482 wait_queue_head_t erp_ready_wq;
484 struct list_head erp_running_head; 483 struct list_head erp_running_head;
485 rwlock_t erp_lock; 484 rwlock_t erp_lock;
486 struct semaphore erp_ready_sem;
487 wait_queue_head_t erp_thread_wqh;
488 wait_queue_head_t erp_done_wqh; 485 wait_queue_head_t erp_done_wqh;
489 struct zfcp_erp_action erp_action; /* pending error recovery */ 486 struct zfcp_erp_action erp_action; /* pending error recovery */
490 atomic_t erp_counter; 487 atomic_t erp_counter;
@@ -492,6 +489,7 @@ struct zfcp_adapter {
492 actions */ 489 actions */
493 u32 erp_low_mem_count; /* nr of erp actions waiting 490 u32 erp_low_mem_count; /* nr of erp actions waiting
494 for memory */ 491 for memory */
492 struct task_struct *erp_thread;
495 struct zfcp_wka_ports *gs; /* generic services */ 493 struct zfcp_wka_ports *gs; /* generic services */
496 struct zfcp_dbf *dbf; /* debug traces */ 494 struct zfcp_dbf *dbf; /* debug traces */
497 struct zfcp_adapter_mempool pool; /* Adapter memory pools */ 495 struct zfcp_adapter_mempool pool; /* Adapter memory pools */
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 373567eda8f6..577e15708598 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -9,6 +9,7 @@
9#define KMSG_COMPONENT "zfcp" 9#define KMSG_COMPONENT "zfcp"
10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11 11
12#include <linux/kthread.h>
12#include "zfcp_ext.h" 13#include "zfcp_ext.h"
13 14
14#define ZFCP_MAX_ERPS 3 15#define ZFCP_MAX_ERPS 3
@@ -75,7 +76,7 @@ static void zfcp_erp_action_ready(struct zfcp_erp_action *act)
75 76
76 list_move(&act->list, &act->adapter->erp_ready_head); 77 list_move(&act->list, &act->adapter->erp_ready_head);
77 zfcp_dbf_rec_action("erardy1", act); 78 zfcp_dbf_rec_action("erardy1", act);
78 up(&adapter->erp_ready_sem); 79 wake_up(&adapter->erp_ready_wq);
79 zfcp_dbf_rec_thread("erardy2", adapter->dbf); 80 zfcp_dbf_rec_thread("erardy2", adapter->dbf);
80} 81}
81 82
@@ -212,8 +213,7 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
212 int retval = 1, need; 213 int retval = 1, need;
213 struct zfcp_erp_action *act = NULL; 214 struct zfcp_erp_action *act = NULL;
214 215
215 if (!(atomic_read(&adapter->status) & 216 if (!adapter->erp_thread)
216 ZFCP_STATUS_ADAPTER_ERP_THREAD_UP))
217 return -EIO; 217 return -EIO;
218 218
219 need = zfcp_erp_required_act(want, adapter, port, unit); 219 need = zfcp_erp_required_act(want, adapter, port, unit);
@@ -226,7 +226,7 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
226 goto out; 226 goto out;
227 ++adapter->erp_total_count; 227 ++adapter->erp_total_count;
228 list_add_tail(&act->list, &adapter->erp_ready_head); 228 list_add_tail(&act->list, &adapter->erp_ready_head);
229 up(&adapter->erp_ready_sem); 229 wake_up(&adapter->erp_ready_wq);
230 zfcp_dbf_rec_thread("eracte1", adapter->dbf); 230 zfcp_dbf_rec_thread("eracte1", adapter->dbf);
231 retval = 0; 231 retval = 0;
232 out: 232 out:
@@ -641,7 +641,8 @@ static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
641 } 641 }
642 642
643 zfcp_dbf_rec_thread_lock("erasfx1", adapter->dbf); 643 zfcp_dbf_rec_thread_lock("erasfx1", adapter->dbf);
644 down(&adapter->erp_ready_sem); 644 wait_event(adapter->erp_ready_wq,
645 !list_empty(&adapter->erp_ready_head));
645 zfcp_dbf_rec_thread_lock("erasfx2", adapter->dbf); 646 zfcp_dbf_rec_thread_lock("erasfx2", adapter->dbf);
646 if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) 647 if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT)
647 break; 648 break;
@@ -682,7 +683,8 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act)
682 return ZFCP_ERP_FAILED; 683 return ZFCP_ERP_FAILED;
683 684
684 zfcp_dbf_rec_thread_lock("erasox1", adapter->dbf); 685 zfcp_dbf_rec_thread_lock("erasox1", adapter->dbf);
685 down(&adapter->erp_ready_sem); 686 wait_event(adapter->erp_ready_wq,
687 !list_empty(&adapter->erp_ready_head));
686 zfcp_dbf_rec_thread_lock("erasox2", adapter->dbf); 688 zfcp_dbf_rec_thread_lock("erasox2", adapter->dbf);
687 if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) 689 if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
688 return ZFCP_ERP_FAILED; 690 return ZFCP_ERP_FAILED;
@@ -1285,21 +1287,17 @@ static int zfcp_erp_thread(void *data)
1285 struct list_head *next; 1287 struct list_head *next;
1286 struct zfcp_erp_action *act; 1288 struct zfcp_erp_action *act;
1287 unsigned long flags; 1289 unsigned long flags;
1288 int ignore;
1289
1290 daemonize("zfcperp%s", dev_name(&adapter->ccw_device->dev));
1291 /* Block all signals */
1292 siginitsetinv(&current->blocked, 0);
1293 atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
1294 wake_up(&adapter->erp_thread_wqh);
1295
1296 while (!(atomic_read(&adapter->status) &
1297 ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL)) {
1298 1290
1291 for (;;) {
1299 zfcp_dbf_rec_thread_lock("erthrd1", adapter->dbf); 1292 zfcp_dbf_rec_thread_lock("erthrd1", adapter->dbf);
1300 ignore = down_interruptible(&adapter->erp_ready_sem); 1293 wait_event_interruptible(adapter->erp_ready_wq,
1294 !list_empty(&adapter->erp_ready_head) ||
1295 kthread_should_stop());
1301 zfcp_dbf_rec_thread_lock("erthrd2", adapter->dbf); 1296 zfcp_dbf_rec_thread_lock("erthrd2", adapter->dbf);
1302 1297
1298 if (kthread_should_stop())
1299 break;
1300
1303 write_lock_irqsave(&adapter->erp_lock, flags); 1301 write_lock_irqsave(&adapter->erp_lock, flags);
1304 next = adapter->erp_ready_head.next; 1302 next = adapter->erp_ready_head.next;
1305 write_unlock_irqrestore(&adapter->erp_lock, flags); 1303 write_unlock_irqrestore(&adapter->erp_lock, flags);
@@ -1313,9 +1311,6 @@ static int zfcp_erp_thread(void *data)
1313 } 1311 }
1314 } 1312 }
1315 1313
1316 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
1317 wake_up(&adapter->erp_thread_wqh);
1318
1319 return 0; 1314 return 0;
1320} 1315}
1321 1316
@@ -1327,18 +1322,17 @@ static int zfcp_erp_thread(void *data)
1327 */ 1322 */
1328int zfcp_erp_thread_setup(struct zfcp_adapter *adapter) 1323int zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
1329{ 1324{
1330 int retval; 1325 struct task_struct *thread;
1331 1326
1332 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); 1327 thread = kthread_run(zfcp_erp_thread, adapter, "zfcperp%s",
1333 retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD); 1328 dev_name(&adapter->ccw_device->dev));
1334 if (retval < 0) { 1329 if (IS_ERR(thread)) {
1335 dev_err(&adapter->ccw_device->dev, 1330 dev_err(&adapter->ccw_device->dev,
1336 "Creating an ERP thread for the FCP device failed.\n"); 1331 "Creating an ERP thread for the FCP device failed.\n");
1337 return retval; 1332 return PTR_ERR(thread);
1338 } 1333 }
1339 wait_event(adapter->erp_thread_wqh, 1334
1340 atomic_read(&adapter->status) & 1335 adapter->erp_thread = thread;
1341 ZFCP_STATUS_ADAPTER_ERP_THREAD_UP);
1342 return 0; 1336 return 0;
1343} 1337}
1344 1338
@@ -1353,16 +1347,8 @@ int zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
1353 */ 1347 */
1354void zfcp_erp_thread_kill(struct zfcp_adapter *adapter) 1348void zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
1355{ 1349{
1356 atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status); 1350 kthread_stop(adapter->erp_thread);
1357 up(&adapter->erp_ready_sem); 1351 adapter->erp_thread = NULL;
1358 zfcp_dbf_rec_thread_lock("erthrk1", adapter->dbf);
1359
1360 wait_event(adapter->erp_thread_wqh,
1361 !(atomic_read(&adapter->status) &
1362 ZFCP_STATUS_ADAPTER_ERP_THREAD_UP));
1363
1364 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
1365 &adapter->status);
1366} 1352}
1367 1353
1368/** 1354/**