diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_erp.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 62 |
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(¤t->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 | */ |
1328 | int zfcp_erp_thread_setup(struct zfcp_adapter *adapter) | 1323 | int 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 | */ |
1354 | void zfcp_erp_thread_kill(struct zfcp_adapter *adapter) | 1348 | void 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 | /** |