forked from Minki/linux
scsi: be2iscsi: Take iscsi_task ref in abort handler
Hold the reference of iscsi_task till invalidation completes. This prevents use of ICD when invalidation of that ICD is being processed. Signed-off-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
987132167f
commit
faa0a22d54
@ -218,47 +218,40 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
|
||||
|
||||
static int beiscsi_eh_abort(struct scsi_cmnd *sc)
|
||||
{
|
||||
struct iscsi_task *abrt_task = (struct iscsi_task *)sc->SCp.ptr;
|
||||
struct iscsi_cls_session *cls_session;
|
||||
struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr;
|
||||
struct beiscsi_io_task *aborted_io_task;
|
||||
struct iscsi_conn *conn;
|
||||
struct beiscsi_io_task *abrt_io_task;
|
||||
struct beiscsi_conn *beiscsi_conn;
|
||||
struct beiscsi_hba *phba;
|
||||
struct iscsi_session *session;
|
||||
struct invldt_cmd_tbl inv_tbl;
|
||||
unsigned int cid;
|
||||
struct beiscsi_hba *phba;
|
||||
struct iscsi_conn *conn;
|
||||
int rc;
|
||||
|
||||
cls_session = starget_to_session(scsi_target(sc->device));
|
||||
session = cls_session->dd_data;
|
||||
|
||||
spin_lock_bh(&session->frwd_lock);
|
||||
if (!aborted_task || !aborted_task->sc) {
|
||||
/* we raced */
|
||||
spin_unlock_bh(&session->frwd_lock);
|
||||
/* check if we raced, task just got cleaned up under us */
|
||||
spin_lock_bh(&session->back_lock);
|
||||
if (!abrt_task || !abrt_task->sc) {
|
||||
spin_unlock_bh(&session->back_lock);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
aborted_io_task = aborted_task->dd_data;
|
||||
if (!aborted_io_task->scsi_cmnd) {
|
||||
/* raced or invalid command */
|
||||
spin_unlock_bh(&session->frwd_lock);
|
||||
return SUCCESS;
|
||||
}
|
||||
spin_unlock_bh(&session->frwd_lock);
|
||||
|
||||
conn = aborted_task->conn;
|
||||
/* get a task ref till FW processes the req for the ICD used */
|
||||
__iscsi_get_task(abrt_task);
|
||||
abrt_io_task = abrt_task->dd_data;
|
||||
conn = abrt_task->conn;
|
||||
beiscsi_conn = conn->dd_data;
|
||||
phba = beiscsi_conn->phba;
|
||||
/* Invalidate WRB Posted for this Task */
|
||||
/* mark WRB invalid which have been not processed by FW yet */
|
||||
AMAP_SET_BITS(struct amap_iscsi_wrb, invld,
|
||||
aborted_io_task->pwrb_handle->pwrb,
|
||||
1);
|
||||
/* invalidate iocb */
|
||||
cid = beiscsi_conn->beiscsi_conn_cid;
|
||||
inv_tbl.cid = cid;
|
||||
inv_tbl.icd = aborted_io_task->psgl_handle->sgl_index;
|
||||
abrt_io_task->pwrb_handle->pwrb, 1);
|
||||
inv_tbl.cid = beiscsi_conn->beiscsi_conn_cid;
|
||||
inv_tbl.icd = abrt_io_task->psgl_handle->sgl_index;
|
||||
spin_unlock_bh(&session->back_lock);
|
||||
|
||||
rc = beiscsi_mgmt_invalidate_icds(phba, &inv_tbl, 1);
|
||||
iscsi_put_task(abrt_task);
|
||||
if (rc) {
|
||||
beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_EH,
|
||||
"BM_%d : sc %p invalidation failed %d\n",
|
||||
|
Loading…
Reference in New Issue
Block a user