Commit 347c6a96 authored by Christof Schmitt's avatar Christof Schmitt Committed by James Bottomley

[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: default avatarSwen Schillig <swen@vnet.ibm.com>
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent ea945ff8
...@@ -529,7 +529,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) ...@@ -529,7 +529,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
goto generic_services_failed; goto generic_services_failed;
init_waitqueue_head(&adapter->remove_wq); init_waitqueue_head(&adapter->remove_wq);
init_waitqueue_head(&adapter->erp_thread_wqh); init_waitqueue_head(&adapter->erp_ready_wq);
init_waitqueue_head(&adapter->erp_done_wqh); init_waitqueue_head(&adapter->erp_done_wqh);
INIT_LIST_HEAD(&adapter->port_list_head); INIT_LIST_HEAD(&adapter->port_list_head);
...@@ -541,8 +541,6 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) ...@@ -541,8 +541,6 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
rwlock_init(&adapter->erp_lock); rwlock_init(&adapter->erp_lock);
rwlock_init(&adapter->abort_lock); rwlock_init(&adapter->abort_lock);
sema_init(&adapter->erp_ready_sem, 0);
INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler); INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later); INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later);
......
...@@ -222,8 +222,6 @@ struct zfcp_ls_adisc { ...@@ -222,8 +222,6 @@ struct zfcp_ls_adisc {
#define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002 #define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002
#define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008 #define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008
#define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010 #define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010
#define ZFCP_STATUS_ADAPTER_ERP_THREAD_UP 0x00000020
#define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL 0x00000080
#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100 #define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100
#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200 #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200
...@@ -481,10 +479,9 @@ struct zfcp_adapter { ...@@ -481,10 +479,9 @@ struct zfcp_adapter {
atomic_t status; /* status of this adapter */ atomic_t status; /* status of this adapter */
struct list_head erp_ready_head; /* error recovery for this struct list_head erp_ready_head; /* error recovery for this
adapter/devices */ adapter/devices */
wait_queue_head_t erp_ready_wq;
struct list_head erp_running_head; struct list_head erp_running_head;
rwlock_t erp_lock; rwlock_t erp_lock;
struct semaphore erp_ready_sem;
wait_queue_head_t erp_thread_wqh;
wait_queue_head_t erp_done_wqh; wait_queue_head_t erp_done_wqh;
struct zfcp_erp_action erp_action; /* pending error recovery */ struct zfcp_erp_action erp_action; /* pending error recovery */
atomic_t erp_counter; atomic_t erp_counter;
...@@ -492,6 +489,7 @@ struct zfcp_adapter { ...@@ -492,6 +489,7 @@ struct zfcp_adapter {
actions */ actions */
u32 erp_low_mem_count; /* nr of erp actions waiting u32 erp_low_mem_count; /* nr of erp actions waiting
for memory */ for memory */
struct task_struct *erp_thread;
struct zfcp_wka_ports *gs; /* generic services */ struct zfcp_wka_ports *gs; /* generic services */
struct zfcp_dbf *dbf; /* debug traces */ struct zfcp_dbf *dbf; /* debug traces */
struct zfcp_adapter_mempool pool; /* Adapter memory pools */ struct zfcp_adapter_mempool pool; /* Adapter memory pools */
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define KMSG_COMPONENT "zfcp" #define KMSG_COMPONENT "zfcp"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/kthread.h>
#include "zfcp_ext.h" #include "zfcp_ext.h"
#define ZFCP_MAX_ERPS 3 #define ZFCP_MAX_ERPS 3
...@@ -75,7 +76,7 @@ static void zfcp_erp_action_ready(struct zfcp_erp_action *act) ...@@ -75,7 +76,7 @@ static void zfcp_erp_action_ready(struct zfcp_erp_action *act)
list_move(&act->list, &act->adapter->erp_ready_head); list_move(&act->list, &act->adapter->erp_ready_head);
zfcp_dbf_rec_action("erardy1", act); zfcp_dbf_rec_action("erardy1", act);
up(&adapter->erp_ready_sem); wake_up(&adapter->erp_ready_wq);
zfcp_dbf_rec_thread("erardy2", adapter->dbf); zfcp_dbf_rec_thread("erardy2", adapter->dbf);
} }
...@@ -212,8 +213,7 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, ...@@ -212,8 +213,7 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
int retval = 1, need; int retval = 1, need;
struct zfcp_erp_action *act = NULL; struct zfcp_erp_action *act = NULL;
if (!(atomic_read(&adapter->status) & if (!adapter->erp_thread)
ZFCP_STATUS_ADAPTER_ERP_THREAD_UP))
return -EIO; return -EIO;
need = zfcp_erp_required_act(want, adapter, port, unit); 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,7 +226,7 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
goto out; goto out;
++adapter->erp_total_count; ++adapter->erp_total_count;
list_add_tail(&act->list, &adapter->erp_ready_head); list_add_tail(&act->list, &adapter->erp_ready_head);
up(&adapter->erp_ready_sem); wake_up(&adapter->erp_ready_wq);
zfcp_dbf_rec_thread("eracte1", adapter->dbf); zfcp_dbf_rec_thread("eracte1", adapter->dbf);
retval = 0; retval = 0;
out: out:
...@@ -641,7 +641,8 @@ static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action) ...@@ -641,7 +641,8 @@ static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
} }
zfcp_dbf_rec_thread_lock("erasfx1", adapter->dbf); zfcp_dbf_rec_thread_lock("erasfx1", adapter->dbf);
down(&adapter->erp_ready_sem); wait_event(adapter->erp_ready_wq,
!list_empty(&adapter->erp_ready_head));
zfcp_dbf_rec_thread_lock("erasfx2", adapter->dbf); zfcp_dbf_rec_thread_lock("erasfx2", adapter->dbf);
if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT)
break; break;
...@@ -682,7 +683,8 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act) ...@@ -682,7 +683,8 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act)
return ZFCP_ERP_FAILED; return ZFCP_ERP_FAILED;
zfcp_dbf_rec_thread_lock("erasox1", adapter->dbf); zfcp_dbf_rec_thread_lock("erasox1", adapter->dbf);
down(&adapter->erp_ready_sem); wait_event(adapter->erp_ready_wq,
!list_empty(&adapter->erp_ready_head));
zfcp_dbf_rec_thread_lock("erasox2", adapter->dbf); zfcp_dbf_rec_thread_lock("erasox2", adapter->dbf);
if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
return ZFCP_ERP_FAILED; return ZFCP_ERP_FAILED;
...@@ -1285,21 +1287,17 @@ static int zfcp_erp_thread(void *data) ...@@ -1285,21 +1287,17 @@ static int zfcp_erp_thread(void *data)
struct list_head *next; struct list_head *next;
struct zfcp_erp_action *act; struct zfcp_erp_action *act;
unsigned long flags; unsigned long flags;
int ignore;
daemonize("zfcperp%s", dev_name(&adapter->ccw_device->dev));
/* Block all signals */
siginitsetinv(&current->blocked, 0);
atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
wake_up(&adapter->erp_thread_wqh);
while (!(atomic_read(&adapter->status) &
ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL)) {
for (;;) {
zfcp_dbf_rec_thread_lock("erthrd1", adapter->dbf); zfcp_dbf_rec_thread_lock("erthrd1", adapter->dbf);
ignore = down_interruptible(&adapter->erp_ready_sem); wait_event_interruptible(adapter->erp_ready_wq,
!list_empty(&adapter->erp_ready_head) ||
kthread_should_stop());
zfcp_dbf_rec_thread_lock("erthrd2", adapter->dbf); zfcp_dbf_rec_thread_lock("erthrd2", adapter->dbf);
if (kthread_should_stop())
break;
write_lock_irqsave(&adapter->erp_lock, flags); write_lock_irqsave(&adapter->erp_lock, flags);
next = adapter->erp_ready_head.next; next = adapter->erp_ready_head.next;
write_unlock_irqrestore(&adapter->erp_lock, flags); write_unlock_irqrestore(&adapter->erp_lock, flags);
...@@ -1313,9 +1311,6 @@ static int zfcp_erp_thread(void *data) ...@@ -1313,9 +1311,6 @@ static int zfcp_erp_thread(void *data)
} }
} }
atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
wake_up(&adapter->erp_thread_wqh);
return 0; return 0;
} }
...@@ -1327,18 +1322,17 @@ static int zfcp_erp_thread(void *data) ...@@ -1327,18 +1322,17 @@ static int zfcp_erp_thread(void *data)
*/ */
int zfcp_erp_thread_setup(struct zfcp_adapter *adapter) int zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
{ {
int retval; struct task_struct *thread;
atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); thread = kthread_run(zfcp_erp_thread, adapter, "zfcperp%s",
retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD); dev_name(&adapter->ccw_device->dev));
if (retval < 0) { if (IS_ERR(thread)) {
dev_err(&adapter->ccw_device->dev, dev_err(&adapter->ccw_device->dev,
"Creating an ERP thread for the FCP device failed.\n"); "Creating an ERP thread for the FCP device failed.\n");
return retval; return PTR_ERR(thread);
} }
wait_event(adapter->erp_thread_wqh,
atomic_read(&adapter->status) & adapter->erp_thread = thread;
ZFCP_STATUS_ADAPTER_ERP_THREAD_UP);
return 0; return 0;
} }
...@@ -1353,16 +1347,8 @@ int zfcp_erp_thread_setup(struct zfcp_adapter *adapter) ...@@ -1353,16 +1347,8 @@ int zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
*/ */
void zfcp_erp_thread_kill(struct zfcp_adapter *adapter) void zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
{ {
atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status); kthread_stop(adapter->erp_thread);
up(&adapter->erp_ready_sem); adapter->erp_thread = NULL;
zfcp_dbf_rec_thread_lock("erthrk1", adapter->dbf);
wait_event(adapter->erp_thread_wqh,
!(atomic_read(&adapter->status) &
ZFCP_STATUS_ADAPTER_ERP_THREAD_UP));
atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
&adapter->status);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment