Skip to content

Commit

Permalink
nvmet-fc: take ref count on tgtport before delete assoc
Browse files Browse the repository at this point in the history
We have to ensure that the tgtport is not going away
before be have remove all the associations.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Daniel Wagner <dwagner@suse.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
  • Loading branch information
Daniel Wagner authored and Keith Busch committed Feb 1, 2024
1 parent 710c69d commit fe506a7
Showing 1 changed file with 23 additions and 8 deletions.
31 changes: 23 additions & 8 deletions drivers/nvme/target/fc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1090,13 +1090,28 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
}

static void
nvmet_fc_delete_assoc(struct work_struct *work)
nvmet_fc_delete_assoc(struct nvmet_fc_tgt_assoc *assoc)
{
nvmet_fc_delete_target_assoc(assoc);
nvmet_fc_tgt_a_put(assoc);
}

static void
nvmet_fc_delete_assoc_work(struct work_struct *work)
{
struct nvmet_fc_tgt_assoc *assoc =
container_of(work, struct nvmet_fc_tgt_assoc, del_work);
struct nvmet_fc_tgtport *tgtport = assoc->tgtport;

nvmet_fc_delete_target_assoc(assoc);
nvmet_fc_tgt_a_put(assoc);
nvmet_fc_delete_assoc(assoc);
nvmet_fc_tgtport_put(tgtport);
}

static void
nvmet_fc_schedule_delete_assoc(struct nvmet_fc_tgt_assoc *assoc)
{
nvmet_fc_tgtport_get(assoc->tgtport);
queue_work(nvmet_wq, &assoc->del_work);
}

static struct nvmet_fc_tgt_assoc *
Expand Down Expand Up @@ -1127,7 +1142,7 @@ nvmet_fc_alloc_target_assoc(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
assoc->a_id = idx;
INIT_LIST_HEAD(&assoc->a_list);
kref_init(&assoc->ref);
INIT_WORK(&assoc->del_work, nvmet_fc_delete_assoc);
INIT_WORK(&assoc->del_work, nvmet_fc_delete_assoc_work);
atomic_set(&assoc->terminating, 0);

while (needrandom) {
Expand Down Expand Up @@ -1483,7 +1498,7 @@ __nvmet_fc_free_assocs(struct nvmet_fc_tgtport *tgtport)
list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) {
if (!nvmet_fc_tgt_a_get(assoc))
continue;
queue_work(nvmet_wq, &assoc->del_work);
nvmet_fc_schedule_delete_assoc(assoc);
nvmet_fc_tgt_a_put(assoc);
}
rcu_read_unlock();
Expand Down Expand Up @@ -1536,7 +1551,7 @@ nvmet_fc_invalidate_host(struct nvmet_fc_target_port *target_port,
continue;
assoc->hostport->invalid = 1;
noassoc = false;
queue_work(nvmet_wq, &assoc->del_work);
nvmet_fc_schedule_delete_assoc(assoc);
nvmet_fc_tgt_a_put(assoc);
}
spin_unlock_irqrestore(&tgtport->lock, flags);
Expand Down Expand Up @@ -1581,7 +1596,7 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl)
nvmet_fc_tgtport_put(tgtport);

if (found_ctrl) {
queue_work(nvmet_wq, &assoc->del_work);
nvmet_fc_schedule_delete_assoc(assoc);
nvmet_fc_tgt_a_put(assoc);
return;
}
Expand Down Expand Up @@ -1888,7 +1903,7 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
nvmet_fc_xmt_ls_rsp(tgtport, oldls);
}

queue_work(nvmet_wq, &assoc->del_work);
nvmet_fc_schedule_delete_assoc(assoc);
nvmet_fc_tgt_a_put(assoc);

return false;
Expand Down

0 comments on commit fe506a7

Please sign in to comment.