aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_erp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi/zfcp_erp.c')
-rw-r--r--drivers/s390/scsi/zfcp_erp.c62
1 files changed, 24 insertions, 38 deletions
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/**