target: Add support for TMR percpu reference counting
This patch introduces TMR percpu reference counting using se_lun->lun_ref in transport_lookup_tmr_lun(), following how existing non TMR per se_lun reference counting works within transport_lookup_cmd_lun(). It also adds explicit transport_lun_remove_cmd() calls to drop the reference in the three tmr related locations that invoke transport_cmd_check_stop_to_fabric(); - target_tmr_work() during normal ->queue_tm_rsp() - target_complete_tmr_failure() during error ->queue_tm_rsp() - transport_generic_handle_tmr() during early failure Also, note the exception paths in transport_generic_free_cmd() and transport_cmd_finish_abort() already check SCF_SE_LUN_CMD, and will invoke transport_lun_remove_cmd() when necessary. Reviewed-by: Himanshu Madhani <himanshu.madhani@cavium.com> Reviewed-by: Quinn Tran <quinn.tran@cavium.com> Cc: Mike Christie <mchristi@redhat.com> Cc: Hannes Reinecke <hare@suse.com> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
12f66e4a0f
commit
eeb64d239e
|
@ -168,11 +168,20 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
|
|||
rcu_read_lock();
|
||||
deve = target_nacl_find_deve(nacl, unpacked_lun);
|
||||
if (deve) {
|
||||
se_cmd->se_lun = rcu_dereference(deve->se_lun);
|
||||
se_lun = rcu_dereference(deve->se_lun);
|
||||
|
||||
if (!percpu_ref_tryget_live(&se_lun->lun_ref)) {
|
||||
se_lun = NULL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
se_cmd->se_lun = rcu_dereference(deve->se_lun);
|
||||
se_cmd->pr_res_key = deve->pr_res_key;
|
||||
se_cmd->orig_fe_lun = unpacked_lun;
|
||||
se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
|
||||
se_cmd->lun_ref_active = true;
|
||||
}
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!se_lun) {
|
||||
|
@ -182,9 +191,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
|
|||
unpacked_lun);
|
||||
return -ENODEV;
|
||||
}
|
||||
/*
|
||||
* XXX: Add percpu se_lun->lun_ref reference count for TMR
|
||||
*/
|
||||
se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev);
|
||||
se_tmr->tmr_dev = rcu_dereference_raw(se_lun->lun_se_dev);
|
||||
|
||||
|
|
|
@ -1590,6 +1590,7 @@ static void target_complete_tmr_failure(struct work_struct *work)
|
|||
se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST;
|
||||
se_cmd->se_tfo->queue_tm_rsp(se_cmd);
|
||||
|
||||
transport_lun_remove_cmd(se_cmd);
|
||||
transport_cmd_check_stop_to_fabric(se_cmd);
|
||||
}
|
||||
|
||||
|
@ -3201,6 +3202,7 @@ static void target_tmr_work(struct work_struct *work)
|
|||
cmd->se_tfo->queue_tm_rsp(cmd);
|
||||
|
||||
check_stop:
|
||||
transport_lun_remove_cmd(cmd);
|
||||
transport_cmd_check_stop_to_fabric(cmd);
|
||||
}
|
||||
|
||||
|
@ -3223,6 +3225,7 @@ int transport_generic_handle_tmr(
|
|||
pr_warn_ratelimited("handle_tmr caught CMD_T_ABORTED TMR %d"
|
||||
"ref_tag: %llu tag: %llu\n", cmd->se_tmr_req->function,
|
||||
cmd->se_tmr_req->ref_task_tag, cmd->tag);
|
||||
transport_lun_remove_cmd(cmd);
|
||||
transport_cmd_check_stop_to_fabric(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue