Commit 4fde02ad authored by John Garry's avatar John Garry Committed by Martin K. Petersen

scsi: hisi_sas: save delivery queue write pointer

Optimise by saving an avoidable read in the get_free_slot function.  The
delivery queue write pointer will only be updated by software, so don't
bother re-reading what was already written in the previous call to
start_delivery function.
Signed-off-by: default avatarJohn Garry <john.garry@huawei.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent e6c346f3
...@@ -98,6 +98,12 @@ struct hisi_sas_cq { ...@@ -98,6 +98,12 @@ struct hisi_sas_cq {
int id; int id;
}; };
struct hisi_sas_dq {
struct hisi_hba *hisi_hba;
int wr_point;
int id;
};
struct hisi_sas_device { struct hisi_sas_device {
enum sas_device_type dev_type; enum sas_device_type dev_type;
struct hisi_hba *hisi_hba; struct hisi_hba *hisi_hba;
...@@ -194,6 +200,7 @@ struct hisi_hba { ...@@ -194,6 +200,7 @@ struct hisi_hba {
struct Scsi_Host *shost; struct Scsi_Host *shost;
struct hisi_sas_cq cq[HISI_SAS_MAX_QUEUES]; struct hisi_sas_cq cq[HISI_SAS_MAX_QUEUES];
struct hisi_sas_dq dq[HISI_SAS_MAX_QUEUES];
struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS]; struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS];
struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; struct hisi_sas_port port[HISI_SAS_MAX_PHYS];
......
...@@ -1239,11 +1239,16 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) ...@@ -1239,11 +1239,16 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost)
for (i = 0; i < hisi_hba->queue_count; i++) { for (i = 0; i < hisi_hba->queue_count; i++) {
struct hisi_sas_cq *cq = &hisi_hba->cq[i]; struct hisi_sas_cq *cq = &hisi_hba->cq[i];
struct hisi_sas_dq *dq = &hisi_hba->dq[i];
/* Completion queue structure */ /* Completion queue structure */
cq->id = i; cq->id = i;
cq->hisi_hba = hisi_hba; cq->hisi_hba = hisi_hba;
/* Delivery queue structure */
dq->id = i;
dq->hisi_hba = hisi_hba;
/* Delivery queue */ /* Delivery queue */
s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS;
hisi_hba->cmd_hdr[i] = dma_alloc_coherent(dev, s, hisi_hba->cmd_hdr[i] = dma_alloc_coherent(dev, s,
......
...@@ -875,12 +875,13 @@ static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id) ...@@ -875,12 +875,13 @@ static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id)
static int get_free_slot_v1_hw(struct hisi_hba *hisi_hba, int *q, int *s) static int get_free_slot_v1_hw(struct hisi_hba *hisi_hba, int *q, int *s)
{ {
struct device *dev = &hisi_hba->pdev->dev; struct device *dev = &hisi_hba->pdev->dev;
struct hisi_sas_dq *dq;
u32 r, w; u32 r, w;
int queue = hisi_hba->queue; int queue = hisi_hba->queue;
while (1) { while (1) {
w = hisi_sas_read32_relaxed(hisi_hba, dq = &hisi_hba->dq[queue];
DLVRY_Q_0_WR_PTR + (queue * 0x14)); w = dq->wr_point;
r = hisi_sas_read32_relaxed(hisi_hba, r = hisi_sas_read32_relaxed(hisi_hba,
DLVRY_Q_0_RD_PTR + (queue * 0x14)); DLVRY_Q_0_RD_PTR + (queue * 0x14));
if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) {
...@@ -903,10 +904,11 @@ static void start_delivery_v1_hw(struct hisi_hba *hisi_hba) ...@@ -903,10 +904,11 @@ static void start_delivery_v1_hw(struct hisi_hba *hisi_hba)
{ {
int dlvry_queue = hisi_hba->slot_prep->dlvry_queue; int dlvry_queue = hisi_hba->slot_prep->dlvry_queue;
int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot; int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot;
struct hisi_sas_dq *dq = &hisi_hba->dq[dlvry_queue];
hisi_sas_write32(hisi_hba, dq->wr_point = ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS;
DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14),
++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS); dq->wr_point);
} }
static int prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba, static int prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba,
......
...@@ -1023,12 +1023,13 @@ static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id) ...@@ -1023,12 +1023,13 @@ static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id)
static int get_free_slot_v2_hw(struct hisi_hba *hisi_hba, int *q, int *s) static int get_free_slot_v2_hw(struct hisi_hba *hisi_hba, int *q, int *s)
{ {
struct device *dev = &hisi_hba->pdev->dev; struct device *dev = &hisi_hba->pdev->dev;
struct hisi_sas_dq *dq;
u32 r, w; u32 r, w;
int queue = hisi_hba->queue; int queue = hisi_hba->queue;
while (1) { while (1) {
w = hisi_sas_read32_relaxed(hisi_hba, dq = &hisi_hba->dq[queue];
DLVRY_Q_0_WR_PTR + (queue * 0x14)); w = dq->wr_point;
r = hisi_sas_read32_relaxed(hisi_hba, r = hisi_sas_read32_relaxed(hisi_hba,
DLVRY_Q_0_RD_PTR + (queue * 0x14)); DLVRY_Q_0_RD_PTR + (queue * 0x14));
if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) {
...@@ -1051,9 +1052,11 @@ static void start_delivery_v2_hw(struct hisi_hba *hisi_hba) ...@@ -1051,9 +1052,11 @@ static void start_delivery_v2_hw(struct hisi_hba *hisi_hba)
{ {
int dlvry_queue = hisi_hba->slot_prep->dlvry_queue; int dlvry_queue = hisi_hba->slot_prep->dlvry_queue;
int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot; int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot;
struct hisi_sas_dq *dq = &hisi_hba->dq[dlvry_queue];
dq->wr_point = ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS;
hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14),
++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS); dq->wr_point);
} }
static int prep_prd_sge_v2_hw(struct hisi_hba *hisi_hba, static int prep_prd_sge_v2_hw(struct hisi_hba *hisi_hba,
......
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