diff options
author | John Garry <john.garry@huawei.com> | 2016-09-06 11:36:12 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-09-14 12:54:17 -0400 |
commit | 4fde02ad66dc9ceb0b55daca21ef33b43df30ded (patch) | |
tree | 4c707c92f64c6c18bfaa4dd62c6e24f70fc0abbd | |
parent | e6c346f303d41b8799ea224d0faf1b2caa1c98db (diff) |
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: John Garry <john.garry@huawei.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas.h | 7 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_main.c | 5 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 12 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 9 |
4 files changed, 25 insertions, 8 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 9410335caf41..72c98522bd26 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h | |||
@@ -98,6 +98,12 @@ struct hisi_sas_cq { | |||
98 | int id; | 98 | int id; |
99 | }; | 99 | }; |
100 | 100 | ||
101 | struct hisi_sas_dq { | ||
102 | struct hisi_hba *hisi_hba; | ||
103 | int wr_point; | ||
104 | int id; | ||
105 | }; | ||
106 | |||
101 | struct hisi_sas_device { | 107 | struct hisi_sas_device { |
102 | enum sas_device_type dev_type; | 108 | enum sas_device_type dev_type; |
103 | struct hisi_hba *hisi_hba; | 109 | struct hisi_hba *hisi_hba; |
@@ -194,6 +200,7 @@ struct hisi_hba { | |||
194 | struct Scsi_Host *shost; | 200 | struct Scsi_Host *shost; |
195 | 201 | ||
196 | struct hisi_sas_cq cq[HISI_SAS_MAX_QUEUES]; | 202 | struct hisi_sas_cq cq[HISI_SAS_MAX_QUEUES]; |
203 | struct hisi_sas_dq dq[HISI_SAS_MAX_QUEUES]; | ||
197 | struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS]; | 204 | struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS]; |
198 | struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; | 205 | struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; |
199 | 206 | ||
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 85c73d311e4d..5d5657670d4c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c | |||
@@ -1239,11 +1239,16 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) | |||
1239 | 1239 | ||
1240 | for (i = 0; i < hisi_hba->queue_count; i++) { | 1240 | for (i = 0; i < hisi_hba->queue_count; i++) { |
1241 | struct hisi_sas_cq *cq = &hisi_hba->cq[i]; | 1241 | struct hisi_sas_cq *cq = &hisi_hba->cq[i]; |
1242 | struct hisi_sas_dq *dq = &hisi_hba->dq[i]; | ||
1242 | 1243 | ||
1243 | /* Completion queue structure */ | 1244 | /* Completion queue structure */ |
1244 | cq->id = i; | 1245 | cq->id = i; |
1245 | cq->hisi_hba = hisi_hba; | 1246 | cq->hisi_hba = hisi_hba; |
1246 | 1247 | ||
1248 | /* Delivery queue structure */ | ||
1249 | dq->id = i; | ||
1250 | dq->hisi_hba = hisi_hba; | ||
1251 | |||
1247 | /* Delivery queue */ | 1252 | /* Delivery queue */ |
1248 | s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; | 1253 | s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; |
1249 | hisi_hba->cmd_hdr[i] = dma_alloc_coherent(dev, s, | 1254 | hisi_hba->cmd_hdr[i] = dma_alloc_coherent(dev, s, |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 3b31b2046559..b5374641bdb0 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | |||
@@ -875,12 +875,13 @@ static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id) | |||
875 | static int get_free_slot_v1_hw(struct hisi_hba *hisi_hba, int *q, int *s) | 875 | static int get_free_slot_v1_hw(struct hisi_hba *hisi_hba, int *q, int *s) |
876 | { | 876 | { |
877 | struct device *dev = &hisi_hba->pdev->dev; | 877 | struct device *dev = &hisi_hba->pdev->dev; |
878 | struct hisi_sas_dq *dq; | ||
878 | u32 r, w; | 879 | u32 r, w; |
879 | int queue = hisi_hba->queue; | 880 | int queue = hisi_hba->queue; |
880 | 881 | ||
881 | while (1) { | 882 | while (1) { |
882 | w = hisi_sas_read32_relaxed(hisi_hba, | 883 | dq = &hisi_hba->dq[queue]; |
883 | DLVRY_Q_0_WR_PTR + (queue * 0x14)); | 884 | w = dq->wr_point; |
884 | r = hisi_sas_read32_relaxed(hisi_hba, | 885 | r = hisi_sas_read32_relaxed(hisi_hba, |
885 | DLVRY_Q_0_RD_PTR + (queue * 0x14)); | 886 | DLVRY_Q_0_RD_PTR + (queue * 0x14)); |
886 | if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { | 887 | if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { |
@@ -903,10 +904,11 @@ static void start_delivery_v1_hw(struct hisi_hba *hisi_hba) | |||
903 | { | 904 | { |
904 | int dlvry_queue = hisi_hba->slot_prep->dlvry_queue; | 905 | int dlvry_queue = hisi_hba->slot_prep->dlvry_queue; |
905 | int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot; | 906 | int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot; |
907 | struct hisi_sas_dq *dq = &hisi_hba->dq[dlvry_queue]; | ||
906 | 908 | ||
907 | hisi_sas_write32(hisi_hba, | 909 | dq->wr_point = ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS; |
908 | DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), | 910 | hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), |
909 | ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS); | 911 | dq->wr_point); |
910 | } | 912 | } |
911 | 913 | ||
912 | static int prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba, | 914 | static int prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba, |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 11006c99de54..e0c124b6428e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | |||
@@ -1023,12 +1023,13 @@ static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id) | |||
1023 | static int get_free_slot_v2_hw(struct hisi_hba *hisi_hba, int *q, int *s) | 1023 | static int get_free_slot_v2_hw(struct hisi_hba *hisi_hba, int *q, int *s) |
1024 | { | 1024 | { |
1025 | struct device *dev = &hisi_hba->pdev->dev; | 1025 | struct device *dev = &hisi_hba->pdev->dev; |
1026 | struct hisi_sas_dq *dq; | ||
1026 | u32 r, w; | 1027 | u32 r, w; |
1027 | int queue = hisi_hba->queue; | 1028 | int queue = hisi_hba->queue; |
1028 | 1029 | ||
1029 | while (1) { | 1030 | while (1) { |
1030 | w = hisi_sas_read32_relaxed(hisi_hba, | 1031 | dq = &hisi_hba->dq[queue]; |
1031 | DLVRY_Q_0_WR_PTR + (queue * 0x14)); | 1032 | w = dq->wr_point; |
1032 | r = hisi_sas_read32_relaxed(hisi_hba, | 1033 | r = hisi_sas_read32_relaxed(hisi_hba, |
1033 | DLVRY_Q_0_RD_PTR + (queue * 0x14)); | 1034 | DLVRY_Q_0_RD_PTR + (queue * 0x14)); |
1034 | if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { | 1035 | if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { |
@@ -1051,9 +1052,11 @@ static void start_delivery_v2_hw(struct hisi_hba *hisi_hba) | |||
1051 | { | 1052 | { |
1052 | int dlvry_queue = hisi_hba->slot_prep->dlvry_queue; | 1053 | int dlvry_queue = hisi_hba->slot_prep->dlvry_queue; |
1053 | int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot; | 1054 | int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot; |
1055 | struct hisi_sas_dq *dq = &hisi_hba->dq[dlvry_queue]; | ||
1054 | 1056 | ||
1057 | dq->wr_point = ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS; | ||
1055 | hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), | 1058 | hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), |
1056 | ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS); | 1059 | dq->wr_point); |
1057 | } | 1060 | } |
1058 | 1061 | ||
1059 | static int prep_prd_sge_v2_hw(struct hisi_hba *hisi_hba, | 1062 | static int prep_prd_sge_v2_hw(struct hisi_hba *hisi_hba, |