aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2009-08-18 09:43:25 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-05 09:49:37 -0400
commit347c6a965dc110c91a77f65181fc011ee257a4a6 (patch)
tree9f25d7da6b49f9d23029edc0221fe4f27fe61745
parentea945ff84c2ce1089edb7914ffdd998c24c25903 (diff)
[SCSI] zfcp: Use kthread API for zfcp erp thread
Switch the creation of the zfcp erp thread from the deprecated kernel_thread API to the kthread API. This allows also the removal of some flags in zfcp since the kthread API handles thread creation and shutdown internally. To allow the usage of the kthread_stop function, replace the erp ready semaphore with a waitqueue for waiting until erp actions arrive on the ready queue. Reviewed-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-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/**