Commit 3de0026d authored by Xiang Chen's avatar Xiang Chen Committed by Martin K. Petersen

scsi: hisi_sas: allocate slot buffer earlier

Currently we allocate the slot's memory buffer after allocating the DQ
slot.

To aid DQ lockout reduction, and allow slots to be built in parallel,
move this step (which can fail) prior to allocating the slot.

Also a stray spin_unlock_irqrestore() is removed from internal task exec
function.
Signed-off-by: default avatarXiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: default avatarJohn Garry <john.garry@huawei.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent a2b3820b
...@@ -412,14 +412,22 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq ...@@ -412,14 +412,22 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
if (rc) if (rc)
goto err_out_dma_unmap; goto err_out_dma_unmap;
slot = &hisi_hba->slot_info[slot_idx];
memset(slot, 0, sizeof(struct hisi_sas_slot));
slot->buf = dma_pool_alloc(hisi_hba->buffer_pool,
GFP_ATOMIC, &slot->buf_dma);
if (!slot->buf) {
rc = -ENOMEM;
goto err_out_tag;
}
rc = hisi_hba->hw->get_free_slot(hisi_hba, dq); rc = hisi_hba->hw->get_free_slot(hisi_hba, dq);
if (rc) if (rc)
goto err_out_tag; goto err_out_buf;
dlvry_queue = dq->id; dlvry_queue = dq->id;
dlvry_queue_slot = dq->wr_point; dlvry_queue_slot = dq->wr_point;
slot = &hisi_hba->slot_info[slot_idx];
memset(slot, 0, sizeof(struct hisi_sas_slot));
slot->idx = slot_idx; slot->idx = slot_idx;
slot->n_elem = n_elem; slot->n_elem = n_elem;
...@@ -434,12 +442,6 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq ...@@ -434,12 +442,6 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
task->lldd_task = slot; task->lldd_task = slot;
INIT_WORK(&slot->abort_slot, hisi_sas_slot_abort); INIT_WORK(&slot->abort_slot, hisi_sas_slot_abort);
slot->buf = dma_pool_alloc(hisi_hba->buffer_pool,
GFP_ATOMIC, &slot->buf_dma);
if (!slot->buf) {
rc = -ENOMEM;
goto err_out_slot_buf;
}
memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr)); memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr));
memset(hisi_sas_cmd_hdr_addr_mem(slot), 0, HISI_SAS_COMMAND_TABLE_SZ); memset(hisi_sas_cmd_hdr_addr_mem(slot), 0, HISI_SAS_COMMAND_TABLE_SZ);
memset(hisi_sas_status_buf_addr_mem(slot), 0, HISI_SAS_STATUS_BUF_SZ); memset(hisi_sas_status_buf_addr_mem(slot), 0, HISI_SAS_STATUS_BUF_SZ);
...@@ -474,8 +476,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq ...@@ -474,8 +476,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
return 0; return 0;
err_out_slot_buf: err_out_buf:
/* Nothing to be done */ dma_pool_free(hisi_hba->buffer_pool, slot->buf,
slot->buf_dma);
err_out_tag: err_out_tag:
spin_lock_irqsave(&hisi_hba->lock, flags); spin_lock_irqsave(&hisi_hba->lock, flags);
hisi_sas_slot_index_free(hisi_hba, slot_idx); hisi_sas_slot_index_free(hisi_hba, slot_idx);
...@@ -1519,17 +1522,26 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id, ...@@ -1519,17 +1522,26 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
} }
spin_unlock_irqrestore(&hisi_hba->lock, flags); spin_unlock_irqrestore(&hisi_hba->lock, flags);
slot = &hisi_hba->slot_info[slot_idx];
memset(slot, 0, sizeof(struct hisi_sas_slot));
slot->buf = dma_pool_alloc(hisi_hba->buffer_pool,
GFP_ATOMIC, &slot->buf_dma);
if (!slot->buf) {
rc = -ENOMEM;
goto err_out_tag;
}
spin_lock_irqsave(&dq->lock, flags_dq); spin_lock_irqsave(&dq->lock, flags_dq);
rc = hisi_hba->hw->get_free_slot(hisi_hba, dq); rc = hisi_hba->hw->get_free_slot(hisi_hba, dq);
if (rc) if (rc) {
goto err_out_tag; rc = -ENOMEM;
spin_unlock_irqrestore(&dq->lock, flags_dq);
goto err_out_buf;
}
dlvry_queue = dq->id; dlvry_queue = dq->id;
dlvry_queue_slot = dq->wr_point; dlvry_queue_slot = dq->wr_point;
slot = &hisi_hba->slot_info[slot_idx];
memset(slot, 0, sizeof(struct hisi_sas_slot));
slot->idx = slot_idx; slot->idx = slot_idx;
slot->n_elem = n_elem; slot->n_elem = n_elem;
slot->dlvry_queue = dlvry_queue; slot->dlvry_queue = dlvry_queue;
...@@ -1541,13 +1553,6 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id, ...@@ -1541,13 +1553,6 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
slot->is_internal = true; slot->is_internal = true;
task->lldd_task = slot; task->lldd_task = slot;
slot->buf = dma_pool_alloc(hisi_hba->buffer_pool,
GFP_ATOMIC, &slot->buf_dma);
if (!slot->buf) {
rc = -ENOMEM;
goto err_out_tag;
}
memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr)); memset(slot->cmd_hdr, 0, sizeof(struct hisi_sas_cmd_hdr));
memset(hisi_sas_cmd_hdr_addr_mem(slot), 0, HISI_SAS_COMMAND_TABLE_SZ); memset(hisi_sas_cmd_hdr_addr_mem(slot), 0, HISI_SAS_COMMAND_TABLE_SZ);
memset(hisi_sas_status_buf_addr_mem(slot), 0, HISI_SAS_STATUS_BUF_SZ); memset(hisi_sas_status_buf_addr_mem(slot), 0, HISI_SAS_STATUS_BUF_SZ);
...@@ -1570,11 +1575,13 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id, ...@@ -1570,11 +1575,13 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
return 0; return 0;
err_out_buf:
dma_pool_free(hisi_hba->buffer_pool, slot->buf,
slot->buf_dma);
err_out_tag: err_out_tag:
spin_lock_irqsave(&hisi_hba->lock, flags); spin_lock_irqsave(&hisi_hba->lock, flags);
hisi_sas_slot_index_free(hisi_hba, slot_idx); hisi_sas_slot_index_free(hisi_hba, slot_idx);
spin_unlock_irqrestore(&hisi_hba->lock, flags); spin_unlock_irqrestore(&hisi_hba->lock, flags);
spin_unlock_irqrestore(&dq->lock, flags_dq);
err_out: err_out:
dev_err(dev, "internal abort task prep: failed[%d]!\n", rc); dev_err(dev, "internal abort task prep: failed[%d]!\n", rc);
......
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