mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
[SCSI] ibmvfc: Fix rport add/delete race resulting in oops
Commit 43c8da907c
introduced a race
condition which can occur when adding/deleting rports. There are
two possible threads now that can be deleting rports in the ibmvfc
driver, which can result in list_del being called twice, resulting
in an oops. This patch adds a new state to the ibmvfc_target struct
to indicate the target has been removed from the list and is in
the process of being deleted.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
parent
161155519c
commit
d5da3040d7
2 changed files with 9 additions and 0 deletions
|
@ -433,6 +433,9 @@ static void ibmvfc_set_tgt_action(struct ibmvfc_target *tgt,
|
|||
{
|
||||
switch (tgt->action) {
|
||||
case IBMVFC_TGT_ACTION_DEL_RPORT:
|
||||
if (action == IBMVFC_TGT_ACTION_DELETED_RPORT)
|
||||
tgt->action = action;
|
||||
case IBMVFC_TGT_ACTION_DELETED_RPORT:
|
||||
break;
|
||||
default:
|
||||
if (action == IBMVFC_TGT_ACTION_DEL_RPORT)
|
||||
|
@ -4193,11 +4196,15 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt)
|
|||
if (rport && tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) {
|
||||
tgt_dbg(tgt, "Deleting rport\n");
|
||||
list_del(&tgt->queue);
|
||||
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DELETED_RPORT);
|
||||
spin_unlock_irqrestore(vhost->host->host_lock, flags);
|
||||
fc_remote_port_delete(rport);
|
||||
del_timer_sync(&tgt->timer);
|
||||
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
||||
return;
|
||||
} else if (rport && tgt->action == IBMVFC_TGT_ACTION_DELETED_RPORT) {
|
||||
spin_unlock_irqrestore(vhost->host->host_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rport) {
|
||||
|
@ -4297,6 +4304,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
|
|||
rport = tgt->rport;
|
||||
tgt->rport = NULL;
|
||||
list_del(&tgt->queue);
|
||||
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DELETED_RPORT);
|
||||
spin_unlock_irqrestore(vhost->host->host_lock, flags);
|
||||
if (rport)
|
||||
fc_remote_port_delete(rport);
|
||||
|
|
|
@ -597,6 +597,7 @@ enum ibmvfc_target_action {
|
|||
IBMVFC_TGT_ACTION_INIT,
|
||||
IBMVFC_TGT_ACTION_INIT_WAIT,
|
||||
IBMVFC_TGT_ACTION_DEL_RPORT,
|
||||
IBMVFC_TGT_ACTION_DELETED_RPORT,
|
||||
};
|
||||
|
||||
struct ibmvfc_target {
|
||||
|
|
Loading…
Reference in a new issue