]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
scsi: hisi_sas: allocate slot buffer earlier
authorXiang Chen <chenxiang66@hisilicon.com>
Wed, 9 May 2018 15:10:47 +0000 (23:10 +0800)
committerKhalid Elmously <khalid.elmously@canonical.com>
Wed, 6 Jun 2018 19:13:20 +0000 (15:13 -0400)
BugLink: https://bugs.launchpad.net/bugs/1774472
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: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
(cherry picked from commit 3de0026dad6b8e83d8a699aef92638c50ba966f7 linux-next)
Signed-off-by: dann frazier <dann.frazier@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
drivers/scsi/hisi_sas/hisi_sas_main.c

index d696ce99ccf2803eb8a75fe397c34ef6afc80b89..a9ecc7bcbbce9681a1e977b855a194ea88dd7a01 100644 (file)
@@ -411,14 +411,22 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
        if (rc)
                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);
        if (rc)
-               goto err_out_tag;
+               goto err_out_buf;
 
        dlvry_queue = dq->id;
        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->n_elem = n_elem;
@@ -433,12 +441,6 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
        task->lldd_task = slot;
        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(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);
@@ -473,8 +475,9 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq
 
        return 0;
 
-err_out_slot_buf:
-       /* Nothing to be done */
+err_out_buf:
+       dma_pool_free(hisi_hba->buffer_pool, slot->buf,
+                     slot->buf_dma);
 err_out_tag:
        spin_lock_irqsave(&hisi_hba->lock, flags);
        hisi_sas_slot_index_free(hisi_hba, slot_idx);
@@ -1520,17 +1523,26 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
        }
        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);
        rc = hisi_hba->hw->get_free_slot(hisi_hba, dq);
-       if (rc)
-               goto err_out_tag;
+       if (rc) {
+               rc = -ENOMEM;
+               spin_unlock_irqrestore(&dq->lock, flags_dq);
+               goto err_out_buf;
+       }
 
        dlvry_queue = dq->id;
        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->n_elem = n_elem;
        slot->dlvry_queue = dlvry_queue;
@@ -1542,13 +1554,6 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
        slot->is_internal = true;
        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(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);
@@ -1571,11 +1576,13 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
 
        return 0;
 
+err_out_buf:
+       dma_pool_free(hisi_hba->buffer_pool, slot->buf,
+                     slot->buf_dma);
 err_out_tag:
        spin_lock_irqsave(&hisi_hba->lock, flags);
        hisi_sas_slot_index_free(hisi_hba, slot_idx);
        spin_unlock_irqrestore(&hisi_hba->lock, flags);
-       spin_unlock_irqrestore(&dq->lock, flags_dq);
 err_out:
        dev_err(dev, "internal abort task prep: failed[%d]!\n", rc);