linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw as experimental
@ 2019-10-24 14:21 John Garry
  2019-10-24 14:21 ` [PATCH 1/6] scsi: hisi_sas: Use sbitmap for IPTT management John Garry
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: John Garry @ 2019-10-24 14:21 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linux-scsi, linuxarm, linux-kernel, hare, ming.lei, John Garry

This series adds support to expose multiple hw queues for SCSI mid-layer
as an experimental feature.

For now it is experimental due to known CPU hotplug issue for managed
interrupts.

So now we have two module parameters to enable managed interrupts for v3
hw driver:
- auto_affine_msi_experimental:
Use managed interrupts plus and manage reply map internally. Use
request tag for IPTT (apart from reserved commands).
- expose_mq_experimental
Use managed interrupts plus and expose multipe hw queues. Manage IPTT
internally with sbitmap.

Paramater auto_affine_msi_experimental shows better performance (than
expose_mq_experimental), so we need to maintain it for now to stop
complaints about performance regression (even though enabling this
parameter is unsafe).

I want to remove these module parameters ASAP.

This series also includes a change to convert the driver to use sbitmap
where possible for managing IPTT.

This series is based on 5.4 + [0], even though being advertised for
topic-sas-5.4 dev branch. Sorry for send before that is merged, but I just
wanted to get these posted.

[0] https://lore.kernel.org/linux-scsi/1571674935-108326-1-git-send-email-john.garry@huawei.com/T/#t


John Garry (6):
  scsi: hisi_sas: Use sbitmap for IPTT management
  scsi: hisi_sas: Pass scsi_cmnd pointer to hisi_sas_hw.slot_index_alloc
  scsi: hisi_sas: Add bitmaps_alloc_v3_hw()
  scsi: hisi_sas: Add slot_index_alloc_v3_hw() and
    slot_index_free_v3_hw()
  scsi: hisi_sas: Split interrupt_init_v3_hw()
  scsi: hisi_sas: Expose multiple hw queues for v3 as experimental

 drivers/scsi/hisi_sas/hisi_sas.h       |  12 ++-
 drivers/scsi/hisi_sas/hisi_sas_main.c  | 135 ++++++++++++-------------
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 110 +++++++++++++-------
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 100 ++++++++++++++++--
 4 files changed, 242 insertions(+), 115 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/6] scsi: hisi_sas: Use sbitmap for IPTT management
  2019-10-24 14:21 [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw as experimental John Garry
@ 2019-10-24 14:21 ` John Garry
  2019-10-24 14:21 ` [PATCH 2/6] scsi: hisi_sas: Pass scsi_cmnd pointer to hisi_sas_hw.slot_index_alloc John Garry
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: John Garry @ 2019-10-24 14:21 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linux-scsi, linuxarm, linux-kernel, hare, ming.lei, John Garry

Using sbitmap will be more efficient in scenarios where we generate the
IPTT in the driver, so make the transition.

For non-v2 hw, we only use the sbitmap to manage reserved tags.

For v2 hw, we use separate sbitmap sets to manage SAS/SMP and SATA tags.

Using separate SATA sbitmaps for v2 hw was suggested by Hannes Reinecke.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas.h       |   7 +-
 drivers/scsi/hisi_sas/hisi_sas_main.c  |  82 +++++++------------
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 107 +++++++++++++++++--------
 3 files changed, 109 insertions(+), 87 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 233c73e01246..fbfaa92765cf 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -279,6 +279,8 @@ struct hisi_sas_hw {
 			   struct hisi_sas_device *device);
 	int (*slot_index_alloc)(struct hisi_hba *hisi_hba,
 				struct domain_device *device);
+	void (*slot_index_free)(struct hisi_hba *hisi_hba, int slot_idx);
+	int (*bitmaps_alloc)(struct hisi_hba *hisi_hba);
 	struct hisi_sas_device *(*alloc_dev)(struct domain_device *device);
 	void (*sl_notify_ssp)(struct hisi_hba *hisi_hba, int phy_no);
 	void (*start_delivery)(struct hisi_sas_dq *dq);
@@ -388,10 +390,9 @@ struct hisi_hba {
 	struct timer_list timer;
 	struct workqueue_struct *wq;
 
-	int slot_index_count;
 	int last_slot_index;
 	int last_dev_id;
-	unsigned long *slot_index_tags;
+	struct sbitmap slot_index_tags;
 	unsigned long reject_stp_links_msk;
 
 	/* SCSI/SAS glue */
@@ -424,6 +425,8 @@ struct hisi_hba {
 	unsigned long flags;
 	const struct hisi_sas_hw *hw;	/* Low level hw interface */
 	unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)];
+	struct sbitmap sata_slot_index_tags[HISI_SAS_MAX_DEVICES];
+	int sbitmap_alloc_hint;
 	struct work_struct rst_work;
 	struct work_struct debugfs_work;
 	u32 phy_state;
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index a7af9483b678..f4937da9baf8 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -156,65 +156,36 @@ EXPORT_SYMBOL_GPL(hisi_sas_stop_phys);
 
 static void hisi_sas_slot_index_clear(struct hisi_hba *hisi_hba, int slot_idx)
 {
-	void *bitmap = hisi_hba->slot_index_tags;
+	struct sbitmap *slot_index_tags = &hisi_hba->slot_index_tags;
 
-	clear_bit(slot_idx, bitmap);
+	sbitmap_clear_bit(slot_index_tags, slot_idx);
 }
 
 static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx)
 {
-	unsigned long flags;
-
-	if (hisi_hba->hw->slot_index_alloc ||
-	    slot_idx >= HISI_SAS_UNRESERVED_IPTT) {
-		spin_lock_irqsave(&hisi_hba->lock, flags);
-		hisi_sas_slot_index_clear(hisi_hba, slot_idx);
-		spin_unlock_irqrestore(&hisi_hba->lock, flags);
-	}
-}
-
-static void hisi_sas_slot_index_set(struct hisi_hba *hisi_hba, int slot_idx)
-{
-	void *bitmap = hisi_hba->slot_index_tags;
-
-	set_bit(slot_idx, bitmap);
+	if (hisi_hba->hw->slot_index_free)
+		hisi_hba->hw->slot_index_free(hisi_hba, slot_idx);
+	else if (slot_idx >= HISI_SAS_UNRESERVED_IPTT)
+		hisi_sas_slot_index_clear(hisi_hba,
+					  slot_idx - HISI_SAS_UNRESERVED_IPTT);
 }
 
 static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba,
 				     struct scsi_cmnd *scsi_cmnd)
 {
+	struct sbitmap *slot_index_tags = &hisi_hba->slot_index_tags;
 	int index;
-	void *bitmap = hisi_hba->slot_index_tags;
-	unsigned long flags;
 
 	if (scsi_cmnd)
 		return scsi_cmnd->request->tag;
 
-	spin_lock_irqsave(&hisi_hba->lock, flags);
-	index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count,
-				   hisi_hba->last_slot_index + 1);
-	if (index >= hisi_hba->slot_index_count) {
-		index = find_next_zero_bit(bitmap,
-				hisi_hba->slot_index_count,
-				HISI_SAS_UNRESERVED_IPTT);
-		if (index >= hisi_hba->slot_index_count) {
-			spin_unlock_irqrestore(&hisi_hba->lock, flags);
-			return -SAS_QUEUE_FULL;
-		}
-	}
-	hisi_sas_slot_index_set(hisi_hba, index);
-	hisi_hba->last_slot_index = index;
-	spin_unlock_irqrestore(&hisi_hba->lock, flags);
+	index = sbitmap_get(slot_index_tags, hisi_hba->sbitmap_alloc_hint,
+			    false);
+	if (index == -1)
+		return index;
+	hisi_hba->sbitmap_alloc_hint = (index + 1) % slot_index_tags->depth;
 
-	return index;
-}
-
-static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba)
-{
-	int i;
-
-	for (i = 0; i < hisi_hba->slot_index_count; ++i)
-		hisi_sas_slot_index_clear(hisi_hba, i);
+	return index + HISI_SAS_UNRESERVED_IPTT;
 }
 
 void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
@@ -481,7 +452,7 @@ static int hisi_sas_task_prep(struct sas_task *task,
 				scsi_cmnd = task->uldd_task;
 			}
 		}
-		rc  = hisi_sas_slot_index_alloc(hisi_hba, scsi_cmnd);
+		rc = hisi_sas_slot_index_alloc(hisi_hba, scsi_cmnd);
 	}
 	if (rc < 0)
 		goto err_out_dif_dma_unmap;
@@ -1957,7 +1928,10 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
 	port = to_hisi_sas_port(sas_port);
 
 	/* simply get a slot and send abort command */
-	rc = hisi_sas_slot_index_alloc(hisi_hba, NULL);
+	if (hisi_hba->hw->slot_index_alloc)
+		rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device);
+	else
+		rc = hisi_sas_slot_index_alloc(hisi_hba, NULL);
 	if (rc < 0)
 		goto err_out;
 
@@ -2309,7 +2283,7 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba)
 	struct device *dev = hisi_hba->dev;
 	int i, j, s, max_command_entries = HISI_SAS_MAX_COMMANDS;
 	int max_command_entries_ru, sz_slot_buf_ru;
-	int blk_cnt, slots_per_blk;
+	int blk_cnt, slots_per_blk, rc;
 
 	sema_init(&hisi_hba->sem, 1);
 	spin_lock_init(&hisi_hba->lock);
@@ -2415,10 +2389,13 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba)
 	if (!hisi_hba->breakpoint)
 		goto err_out;
 
-	hisi_hba->slot_index_count = max_command_entries;
-	s = hisi_hba->slot_index_count / BITS_PER_BYTE;
-	hisi_hba->slot_index_tags = devm_kzalloc(dev, s, GFP_KERNEL);
-	if (!hisi_hba->slot_index_tags)
+	if (hisi_hba->hw->bitmaps_alloc)
+		rc = hisi_hba->hw->bitmaps_alloc(hisi_hba);
+	else
+		rc = sbitmap_init_node(&hisi_hba->slot_index_tags,
+				       HISI_SAS_RESERVED_IPTT, -1,
+				       GFP_KERNEL, dev_to_node(dev));
+	if (rc)
 		goto err_out;
 
 	s = sizeof(struct hisi_sas_initial_fis) * HISI_SAS_MAX_PHYS;
@@ -2435,7 +2412,6 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba)
 	if (!hisi_hba->sata_breakpoint)
 		goto err_out;
 
-	hisi_sas_slot_index_init(hisi_hba);
 	hisi_hba->last_slot_index = HISI_SAS_UNRESERVED_IPTT;
 
 	hisi_hba->wq = create_singlethread_workqueue(dev_name(dev));
@@ -2460,6 +2436,10 @@ void hisi_sas_free(struct hisi_hba *hisi_hba)
 		del_timer_sync(&phy->timer);
 	}
 
+	sbitmap_free(&hisi_hba->slot_index_tags);
+	for (i = 0; i < HISI_SAS_MAX_DEVICES; i++)
+		sbitmap_free(&hisi_hba->sata_slot_index_tags[i]);
+
 	if (hisi_hba->wq)
 		destroy_workqueue(hisi_hba->wq);
 }
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 61b1e2693b08..683e1b99c9ae 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -763,59 +763,96 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
 	return readl(regs);
 }
 
-/* This function needs to be protected from pre-emption. */
+static int bitmaps_alloc_v2_hw(struct hisi_hba *hisi_hba)
+{
+	struct device *dev = hisi_hba->dev;
+	int sata_idx, i;
+
+	if (sbitmap_init_node(&hisi_hba->slot_index_tags,
+			      HISI_SAS_MAX_COMMANDS / 2, -1,
+			      GFP_KERNEL, dev_to_node(hisi_hba->dev)))
+		return -ENOMEM;
+
+	for (sata_idx = 0; sata_idx < HISI_MAX_SATA_SUPPORT_V2_HW; sata_idx++) {
+		if (sbitmap_init_node(&hisi_hba->sata_slot_index_tags[sata_idx],
+				      32, -1, GFP_KERNEL, dev_to_node(dev)))
+			goto free_slot_index_tags;
+	}
+
+	return 0;
+
+free_slot_index_tags:
+	sbitmap_free(&hisi_hba->slot_index_tags);
+	for (i = 0; i < HISI_MAX_SATA_SUPPORT_V2_HW; i++)
+		sbitmap_free(&hisi_hba->sata_slot_index_tags[sata_idx]);
+
+	return -ENOMEM;
+}
+
 static int
 slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba,
 			     struct domain_device *device)
 {
+	struct sbitmap *slot_index_tags;
 	int sata_dev = dev_is_sata(device);
-	void *bitmap = hisi_hba->slot_index_tags;
 	struct hisi_sas_device *sas_dev = device->lldd_dev;
 	int sata_idx = sas_dev->sata_idx;
-	int start, end;
-	unsigned long flags;
+	int start;
+
+	if (sata_dev) {
+		int start;
+		int base = 64 * (sata_idx + 1);
 
-	if (!sata_dev) {
-		/*
-		 * STP link SoC bug workaround: index starts from 1.
-		 * additionally, we can only allocate odd IPTT(1~4095)
-		 * for SAS/SMP device.
-		 */
-		start = 1;
-		end = hisi_hba->slot_index_count;
-	} else {
 		if (sata_idx >= HISI_MAX_SATA_SUPPORT_V2_HW)
 			return -EINVAL;
-
 		/*
 		 * For SATA device: allocate even IPTT in this interval
 		 * [64*(sata_idx+1), 64*(sata_idx+2)], then each SATA device
 		 * own 32 IPTTs. IPTT 0 shall not be used duing to STP link
 		 * SoC bug workaround. So we ignore the first 32 even IPTTs.
 		 */
-		start = 64 * (sata_idx + 1);
-		end = 64 * (sata_idx + 2);
-	}
 
-	spin_lock_irqsave(&hisi_hba->lock, flags);
-	while (1) {
-		start = find_next_zero_bit(bitmap,
-					hisi_hba->slot_index_count, start);
-		if (start >= end) {
-			spin_unlock_irqrestore(&hisi_hba->lock, flags);
-			return -SAS_QUEUE_FULL;
-		}
-		/*
-		  * SAS IPTT bit0 should be 1, and SATA IPTT bit0 should be 0.
-		  */
-		if (sata_dev ^ (start & 1))
-			break;
-		start++;
+		slot_index_tags = &hisi_hba->sata_slot_index_tags[sata_idx];
+
+		start = sbitmap_get(slot_index_tags, 0, true);
+		if (start == -1)
+			return -ENOMEM;
+		start *= 2;
+		return start + base;
 	}
 
-	set_bit(start, bitmap);
-	spin_unlock_irqrestore(&hisi_hba->lock, flags);
-	return start;
+	slot_index_tags = &hisi_hba->slot_index_tags;
+	start = sbitmap_get(slot_index_tags, hisi_hba->sbitmap_alloc_hint,
+			    true);
+	if (start == -1)
+		return -ENOMEM;
+
+	/*
+	 * SAS/SMP IPTT bit0 should be 1, and SATA IPTT bit0 should be 0.
+	 */
+	return (start * 2) + 1;
+}
+
+static void slot_index_free_quirk_v2_hw(struct hisi_hba *hisi_hba, int slot_idx)
+{
+	struct sbitmap *slot_index_tags;
+
+	if (slot_idx & 1) {
+		int start = (slot_idx - 1) / 2;
+
+		slot_index_tags = &hisi_hba->slot_index_tags;
+		sbitmap_clear_bit(&hisi_hba->slot_index_tags, start);
+		hisi_hba->sbitmap_alloc_hint = (start + 1) %
+					       slot_index_tags->depth;
+	} else {
+		int sata_idx = (slot_idx / 64) - 1;
+		int base = 64 * (sata_idx + 1);
+
+		slot_index_tags = &hisi_hba->sata_slot_index_tags[sata_idx];
+		slot_idx -= base;
+		slot_idx /= 2;
+		sbitmap_clear_bit(slot_index_tags, slot_idx);
+	}
 }
 
 static bool sata_index_alloc_v2_hw(struct hisi_hba *hisi_hba, int *idx)
@@ -3559,6 +3596,8 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
 	.hw_init = hisi_sas_v2_init,
 	.setup_itct = setup_itct_v2_hw,
 	.slot_index_alloc = slot_index_alloc_quirk_v2_hw,
+	.slot_index_free = slot_index_free_quirk_v2_hw,
+	.bitmaps_alloc = bitmaps_alloc_v2_hw,
 	.alloc_dev = alloc_dev_quirk_v2_hw,
 	.sl_notify_ssp = sl_notify_ssp_v2_hw,
 	.get_wideport_bitmap = get_wideport_bitmap_v2_hw,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 2/6] scsi: hisi_sas: Pass scsi_cmnd pointer to hisi_sas_hw.slot_index_alloc
  2019-10-24 14:21 [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw as experimental John Garry
  2019-10-24 14:21 ` [PATCH 1/6] scsi: hisi_sas: Use sbitmap for IPTT management John Garry
@ 2019-10-24 14:21 ` John Garry
  2019-10-24 14:21 ` [PATCH 3/6] scsi: hisi_sas: Add bitmaps_alloc_v3_hw() John Garry
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: John Garry @ 2019-10-24 14:21 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linux-scsi, linuxarm, linux-kernel, hare, ming.lei, John Garry

In future we will want to pass both the domain_device and scsi_cmnd
pointers to hisi_sas_hw.slot_index_alloc.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas.h       | 3 ++-
 drivers/scsi/hisi_sas/hisi_sas_main.c  | 4 ++--
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 3 ++-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index fbfaa92765cf..4eb8f1c53f78 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -278,7 +278,8 @@ struct hisi_sas_hw {
 	void (*setup_itct)(struct hisi_hba *hisi_hba,
 			   struct hisi_sas_device *device);
 	int (*slot_index_alloc)(struct hisi_hba *hisi_hba,
-				struct domain_device *device);
+				struct domain_device *device,
+				struct scsi_cmnd *scmd);
 	void (*slot_index_free)(struct hisi_hba *hisi_hba, int slot_idx);
 	int (*bitmaps_alloc)(struct hisi_hba *hisi_hba);
 	struct hisi_sas_device *(*alloc_dev)(struct domain_device *device);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index f4937da9baf8..53802c1cc1d0 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -438,7 +438,7 @@ static int hisi_sas_task_prep(struct sas_task *task,
 	}
 
 	if (hisi_hba->hw->slot_index_alloc)
-		rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device);
+		rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device, NULL);
 	else {
 		struct scsi_cmnd *scsi_cmnd = NULL;
 
@@ -1929,7 +1929,7 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id,
 
 	/* simply get a slot and send abort command */
 	if (hisi_hba->hw->slot_index_alloc)
-		rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device);
+		rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device, NULL);
 	else
 		rc = hisi_sas_slot_index_alloc(hisi_hba, NULL);
 	if (rc < 0)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 683e1b99c9ae..b98ae960964b 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -791,7 +791,8 @@ static int bitmaps_alloc_v2_hw(struct hisi_hba *hisi_hba)
 
 static int
 slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba,
-			     struct domain_device *device)
+			     struct domain_device *device,
+			     struct scsi_cmnd *scmd)
 {
 	struct sbitmap *slot_index_tags;
 	int sata_dev = dev_is_sata(device);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 3/6] scsi: hisi_sas: Add bitmaps_alloc_v3_hw()
  2019-10-24 14:21 [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw as experimental John Garry
  2019-10-24 14:21 ` [PATCH 1/6] scsi: hisi_sas: Use sbitmap for IPTT management John Garry
  2019-10-24 14:21 ` [PATCH 2/6] scsi: hisi_sas: Pass scsi_cmnd pointer to hisi_sas_hw.slot_index_alloc John Garry
@ 2019-10-24 14:21 ` John Garry
  2019-10-24 14:21 ` [PATCH 4/6] scsi: hisi_sas: Add slot_index_alloc_v3_hw() and slot_index_free_v3_hw() John Garry
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: John Garry @ 2019-10-24 14:21 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linux-scsi, linuxarm, linux-kernel, hare, ming.lei, John Garry

We will want to make this non-generic in future.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 2ae7070db41a..a46717efb870 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -556,6 +556,13 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
 	readl_poll_timeout_atomic(regs, val, cond, delay_us, timeout_us);\
 })
 
+static int bitmaps_alloc_v3_hw(struct hisi_hba *hisi_hba)
+{
+	return sbitmap_init_node(&hisi_hba->slot_index_tags,
+				 HISI_SAS_UNRESERVED_IPTT, -1,
+				 GFP_KERNEL, dev_to_node(hisi_hba->dev));
+}
+
 static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
 {
 	int i;
@@ -3083,6 +3090,7 @@ static struct scsi_host_template sht_v3_hw = {
 static const struct hisi_sas_hw hisi_sas_v3_hw = {
 	.hw_init = hisi_sas_v3_init,
 	.setup_itct = setup_itct_v3_hw,
+	.bitmaps_alloc = bitmaps_alloc_v3_hw,
 	.get_wideport_bitmap = get_wideport_bitmap_v3_hw,
 	.complete_hdr_size = sizeof(struct hisi_sas_complete_v3_hdr),
 	.clear_itct = clear_itct_v3_hw,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 4/6] scsi: hisi_sas: Add slot_index_alloc_v3_hw() and slot_index_free_v3_hw()
  2019-10-24 14:21 [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw as experimental John Garry
                   ` (2 preceding siblings ...)
  2019-10-24 14:21 ` [PATCH 3/6] scsi: hisi_sas: Add bitmaps_alloc_v3_hw() John Garry
@ 2019-10-24 14:21 ` John Garry
  2019-10-24 14:21 ` [PATCH 5/6] scsi: hisi_sas: Split interrupt_init_v3_hw() John Garry
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: John Garry @ 2019-10-24 14:21 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linux-scsi, linuxarm, linux-kernel, hare, ming.lei, John Garry

We will want to make these non-generic in future.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 27 ++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index a46717efb870..497bbf6964f6 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -563,6 +563,31 @@ static int bitmaps_alloc_v3_hw(struct hisi_hba *hisi_hba)
 				 GFP_KERNEL, dev_to_node(hisi_hba->dev));
 }
 
+static int slot_index_alloc_v3_hw(struct hisi_hba *hisi_hba,
+				  struct domain_device *device,
+				  struct scsi_cmnd *scmd)
+{
+	struct sbitmap *slot_index_tags = &hisi_hba->slot_index_tags;
+	int index;
+
+	if (scmd)
+		return scmd->request->tag;
+
+	index = sbitmap_get(slot_index_tags, 0, false);
+	if (index == -1)
+		return index;
+	return index + HISI_SAS_UNRESERVED_IPTT;
+}
+
+static void slot_index_free_v3_hw(struct hisi_hba *hisi_hba, int slot_idx)
+{
+	struct sbitmap *slot_index_tags = &hisi_hba->slot_index_tags;
+
+	if (slot_idx >= HISI_SAS_UNRESERVED_IPTT)
+		sbitmap_clear_bit(slot_index_tags,
+				  slot_idx - HISI_SAS_UNRESERVED_IPTT);
+}
+
 static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
 {
 	int i;
@@ -3090,6 +3115,8 @@ static struct scsi_host_template sht_v3_hw = {
 static const struct hisi_sas_hw hisi_sas_v3_hw = {
 	.hw_init = hisi_sas_v3_init,
 	.setup_itct = setup_itct_v3_hw,
+	.slot_index_alloc = slot_index_alloc_v3_hw,
+	.slot_index_free = slot_index_free_v3_hw,
 	.bitmaps_alloc = bitmaps_alloc_v3_hw,
 	.get_wideport_bitmap = get_wideport_bitmap_v3_hw,
 	.complete_hdr_size = sizeof(struct hisi_sas_complete_v3_hdr),
-- 
2.17.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 5/6] scsi: hisi_sas: Split interrupt_init_v3_hw()
  2019-10-24 14:21 [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw as experimental John Garry
                   ` (3 preceding siblings ...)
  2019-10-24 14:21 ` [PATCH 4/6] scsi: hisi_sas: Add slot_index_alloc_v3_hw() and slot_index_free_v3_hw() John Garry
@ 2019-10-24 14:21 ` John Garry
  2019-10-24 14:21 ` [PATCH 6/6] scsi: hisi_sas: Expose multiple hw queues for v3 as experimental John Garry
  2019-10-25 16:04 ` [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw " John Garry
  6 siblings, 0 replies; 13+ messages in thread
From: John Garry @ 2019-10-24 14:21 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linux-scsi, linuxarm, linux-kernel, hare, ming.lei, John Garry

To expose multiple queues to the upper layer we will need to do some
interrupt initialisation earlier - that being to calculate the vectors -
so split interrupt_init_v3_hw().

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 497bbf6964f6..29119d0b27a7 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -2409,11 +2409,10 @@ static void setup_reply_map_v3_hw(struct hisi_hba *hisi_hba, int nvecs)
 	/* Don't clean all CQ masks */
 }
 
-static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
+static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
 {
 	struct device *dev = hisi_hba->dev;
-	struct pci_dev *pdev = hisi_hba->pci_dev;
-	int vectors, rc, i;
+	int vectors;
 	int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi;
 
 	if (auto_affine_msi_experimental) {
@@ -2445,6 +2444,14 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
 	}
 
 	hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW;
+	return 0;
+}
+
+static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
+{
+	struct device *dev = hisi_hba->dev;
+	struct pci_dev *pdev = hisi_hba->pci_dev;
+	int rc, i;
 
 	rc = devm_request_irq(dev, pci_irq_vector(pdev, 1),
 			      int_phy_up_down_bcast_v3_hw, 0,
@@ -3284,6 +3291,9 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	if (hisi_sas_debugfs_enable)
 		hisi_sas_debugfs_init(hisi_hba);
 
+	rc = interrupt_preinit_v3_hw(hisi_hba);
+	if (rc)
+		goto err_out_ha;
 	rc = scsi_add_host(shost, dev);
 	if (rc)
 		goto err_out_ha;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 6/6] scsi: hisi_sas: Expose multiple hw queues for v3 as experimental
  2019-10-24 14:21 [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw as experimental John Garry
                   ` (4 preceding siblings ...)
  2019-10-24 14:21 ` [PATCH 5/6] scsi: hisi_sas: Split interrupt_init_v3_hw() John Garry
@ 2019-10-24 14:21 ` John Garry
  2019-10-27  8:19   ` Ming Lei
  2019-10-25 16:04 ` [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw " John Garry
  6 siblings, 1 reply; 13+ messages in thread
From: John Garry @ 2019-10-24 14:21 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: linux-scsi, linuxarm, linux-kernel, hare, ming.lei, John Garry

Since we're not ready to expose mutliple queues to the upper layer always
due to CPU hotplug issue, add a new interim experimental command line
option to support it.

We still need to keep supporting auto_affine_msi_experimental, since
people are now replying the performance it provides, even though it is
unsafe.

If auto_affine_msi_experimental and expose_mq_experimental are both set,
then auto_affine_msi_experimental takes preference.

Signed-off-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/hisi_sas/hisi_sas.h       |  2 +
 drivers/scsi/hisi_sas/hisi_sas_main.c  | 55 ++++++++++++++++----------
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 51 +++++++++++++++++++++---
 3 files changed, 83 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 4eb8f1c53f78..884f2426d753 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -8,6 +8,8 @@
 #define _HISI_SAS_H_
 
 #include <linux/acpi.h>
+#include <linux/blk-mq.h>
+#include <linux/blk-mq-pci.h>
 #include <linux/clk.h>
 #include <linux/debugfs.h>
 #include <linux/dmapool.h>
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 53802c1cc1d0..c8c96a46acfd 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -389,9 +389,11 @@ static int hisi_sas_task_prep(struct sas_task *task,
 	struct hisi_sas_slot *slot;
 	struct hisi_sas_cmd_hdr	*cmd_hdr_base;
 	struct asd_sas_port *sas_port = device->port;
+	struct Scsi_Host *shost = hisi_hba->shost;
 	struct device *dev = hisi_hba->dev;
 	int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
 	int n_elem = 0, n_elem_dif = 0, n_elem_req = 0;
+	struct scsi_cmnd *scmd = NULL;
 	struct hisi_sas_dq *dq;
 	unsigned long flags;
 	int wr_q_index;
@@ -407,13 +409,38 @@ static int hisi_sas_task_prep(struct sas_task *task,
 		return -ECOMM;
 	}
 
-	if (hisi_hba->reply_map) {
-		int cpu = raw_smp_processor_id();
-		unsigned int dq_index = hisi_hba->reply_map[cpu];
+	if (task->uldd_task) {
+		struct ata_queued_cmd *qc;
 
-		*dq_pointer = dq = &hisi_hba->dq[dq_index];
-	} else {
+		if (dev_is_sata(device)) {
+			qc = task->uldd_task;
+			scmd = qc->scsicmd;
+		} else {
+			scmd = task->uldd_task;
+		}
+	}
+
+	/* We have to move to just a single mode: expose multiple queues */
+	if (!hisi_hba->reply_map && !shost->nr_hw_queues) {
 		*dq_pointer = dq = sas_dev->dq;
+	} else {
+		if (hisi_hba->reply_map) {
+			int cpu = raw_smp_processor_id();
+			unsigned int dq_index = hisi_hba->reply_map[cpu];
+
+			*dq_pointer = dq = &hisi_hba->dq[dq_index];
+		} else {
+			if (scmd) {
+				unsigned int dq_index;
+				u32 blk_tag;
+
+				blk_tag = blk_mq_unique_tag(scmd->request);
+				dq_index = blk_mq_unique_tag_to_hwq(blk_tag);
+				*dq_pointer = dq = &hisi_hba->dq[dq_index];
+			} else {
+				*dq_pointer = dq = sas_dev->dq;
+			}
+		}
 	}
 
 	port = to_hisi_sas_port(sas_port);
@@ -438,22 +465,10 @@ static int hisi_sas_task_prep(struct sas_task *task,
 	}
 
 	if (hisi_hba->hw->slot_index_alloc)
-		rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device, NULL);
-	else {
-		struct scsi_cmnd *scsi_cmnd = NULL;
-
-		if (task->uldd_task) {
-			struct ata_queued_cmd *qc;
+		rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device, scmd);
+	else
+		rc = hisi_sas_slot_index_alloc(hisi_hba, scmd);
 
-			if (dev_is_sata(device)) {
-				qc = task->uldd_task;
-				scsi_cmnd = qc->scsicmd;
-			} else {
-				scsi_cmnd = task->uldd_task;
-			}
-		}
-		rc = hisi_sas_slot_index_alloc(hisi_hba, scsi_cmnd);
-	}
 	if (rc < 0)
 		goto err_out_dif_dma_unmap;
 
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 29119d0b27a7..03ba0416f910 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -512,6 +512,11 @@ module_param(auto_affine_msi_experimental, bool, 0444);
 MODULE_PARM_DESC(auto_affine_msi_experimental, "Enable auto-affinity of MSI IRQs as experimental:\n"
 		 "default is off");
 
+static bool expose_mq_experimental;
+module_param(expose_mq_experimental, bool, 0444);
+MODULE_PARM_DESC(expose_mq_experimental, "Expose multiple hw queues to upper layer as experimental:\n"
+		 "default is off");
+
 static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
 {
 	void __iomem *regs = hisi_hba->regs + off;
@@ -558,6 +563,11 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
 
 static int bitmaps_alloc_v3_hw(struct hisi_hba *hisi_hba)
 {
+	if (expose_mq_experimental)
+		return sbitmap_init_node(&hisi_hba->slot_index_tags,
+					 HISI_SAS_MAX_COMMANDS, -1,
+					 GFP_KERNEL,
+					 dev_to_node(hisi_hba->dev));
 	return sbitmap_init_node(&hisi_hba->slot_index_tags,
 				 HISI_SAS_UNRESERVED_IPTT, -1,
 				 GFP_KERNEL, dev_to_node(hisi_hba->dev));
@@ -570,6 +580,10 @@ static int slot_index_alloc_v3_hw(struct hisi_hba *hisi_hba,
 	struct sbitmap *slot_index_tags = &hisi_hba->slot_index_tags;
 	int index;
 
+	if (expose_mq_experimental)
+		return sbitmap_get(slot_index_tags,
+				   hisi_hba->sbitmap_alloc_hint, false);
+
 	if (scmd)
 		return scmd->request->tag;
 
@@ -583,7 +597,10 @@ static void slot_index_free_v3_hw(struct hisi_hba *hisi_hba, int slot_idx)
 {
 	struct sbitmap *slot_index_tags = &hisi_hba->slot_index_tags;
 
-	if (slot_idx >= HISI_SAS_UNRESERVED_IPTT)
+	if (expose_mq_experimental) {
+		sbitmap_clear_bit(slot_index_tags, slot_idx);
+		hisi_hba->sbitmap_alloc_hint = slot_idx;
+	} else if (slot_idx >= HISI_SAS_UNRESERVED_IPTT)
 		sbitmap_clear_bit(slot_index_tags,
 				  slot_idx - HISI_SAS_UNRESERVED_IPTT);
 }
@@ -2414,8 +2431,9 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
 	struct device *dev = hisi_hba->dev;
 	int vectors;
 	int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi;
+	struct Scsi_Host *shost = hisi_hba->shost;
 
-	if (auto_affine_msi_experimental) {
+	if (auto_affine_msi_experimental || expose_mq_experimental) {
 		struct irq_affinity desc = {
 			.pre_vectors = BASE_VECTORS_V3_HW,
 		};
@@ -2434,7 +2452,9 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
 							 &desc);
 		if (vectors < 0)
 			return -ENOENT;
-		setup_reply_map_v3_hw(hisi_hba, vectors - BASE_VECTORS_V3_HW);
+		if (auto_affine_msi_experimental)
+			setup_reply_map_v3_hw(hisi_hba,
+					      vectors - BASE_VECTORS_V3_HW);
 	} else {
 		min_msi = max_msi;
 		vectors = pci_alloc_irq_vectors(hisi_hba->pci_dev, min_msi,
@@ -2444,6 +2464,9 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
 	}
 
 	hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW;
+	if (expose_mq_experimental)
+		shost->nr_hw_queues = hisi_hba->cq_nvecs;
+
 	return 0;
 }
 
@@ -3096,6 +3119,17 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable)
 	return 0;
 }
 
+static int hisi_sas_map_queues(struct Scsi_Host *shost)
+{
+	struct hisi_hba *hisi_hba = shost_priv(shost);
+	struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
+
+	if (expose_mq_experimental)
+		return blk_mq_pci_map_queues(qmap, hisi_hba->pci_dev,
+					     BASE_VECTORS_V3_HW);
+	return blk_mq_map_queues(qmap);
+}
+
 static struct scsi_host_template sht_v3_hw = {
 	.name			= DRV_NAME,
 	.module			= THIS_MODULE,
@@ -3104,6 +3138,7 @@ static struct scsi_host_template sht_v3_hw = {
 	.slave_configure	= hisi_sas_slave_configure,
 	.scan_finished		= hisi_sas_scan_finished,
 	.scan_start		= hisi_sas_scan_start,
+	.map_queues		= hisi_sas_map_queues,
 	.change_queue_depth	= sas_change_queue_depth,
 	.bios_param		= sas_bios_param,
 	.this_id		= -1,
@@ -3265,8 +3300,14 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	shost->max_lun = ~0;
 	shost->max_channel = 1;
 	shost->max_cmd_len = 16;
-	shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
-	shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
+
+	if (expose_mq_experimental) {
+		shost->can_queue = HISI_SAS_MAX_COMMANDS;
+		shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS;
+	} else {
+		shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
+		shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
+	}
 
 	sha->sas_ha_name = DRV_NAME;
 	sha->dev = dev;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw as experimental
  2019-10-24 14:21 [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw as experimental John Garry
                   ` (5 preceding siblings ...)
  2019-10-24 14:21 ` [PATCH 6/6] scsi: hisi_sas: Expose multiple hw queues for v3 as experimental John Garry
@ 2019-10-25 16:04 ` John Garry
  6 siblings, 0 replies; 13+ messages in thread
From: John Garry @ 2019-10-25 16:04 UTC (permalink / raw)
  To: jejb, martin.petersen; +Cc: linux-scsi, linuxarm, linux-kernel, hare, ming.lei

On 24/10/2019 15:21, John Garry wrote:
> This series adds support to expose multiple hw queues for SCSI mid-layer
> as an experimental feature.
> 
> For now it is experimental due to known CPU hotplug issue for managed
> interrupts.
> 
> So now we have two module parameters to enable managed interrupts for v3
> hw driver:
> - auto_affine_msi_experimental:
> Use managed interrupts plus and manage reply map internally. Use
> request tag for IPTT (apart from reserved commands).
> - expose_mq_experimental
> Use managed interrupts plus and expose multipe hw queues. Manage IPTT
> internally with sbitmap.
> 
> Paramater auto_affine_msi_experimental shows better performance (than
> expose_mq_experimental), so we need to maintain it for now to stop
> complaints about performance regression (even though enabling this
> parameter is unsafe).
> 
> I want to remove these module parameters ASAP.
> 
> This series also includes a change to convert the driver to use sbitmap
> where possible for managing IPTT.

Hi Martin,

Can we hold off on this series until Ming has had a look?

Thanks,
John

> 
> This series is based on 5.4 + [0], even though being advertised for
> topic-sas-5.4 dev branch. Sorry for send before that is merged, but I just
> wanted to get these posted.
> 
> [0] https://lore.kernel.org/linux-scsi/1571674935-108326-1-git-send-email-john.garry@huawei.com/T/#t
> 
> 
> John Garry (6):
>    scsi: hisi_sas: Use sbitmap for IPTT management
>    scsi: hisi_sas: Pass scsi_cmnd pointer to hisi_sas_hw.slot_index_alloc
>    scsi: hisi_sas: Add bitmaps_alloc_v3_hw()
>    scsi: hisi_sas: Add slot_index_alloc_v3_hw() and
>      slot_index_free_v3_hw()
>    scsi: hisi_sas: Split interrupt_init_v3_hw()
>    scsi: hisi_sas: Expose multiple hw queues for v3 as experimental
> 
>   drivers/scsi/hisi_sas/hisi_sas.h       |  12 ++-
>   drivers/scsi/hisi_sas/hisi_sas_main.c  | 135 ++++++++++++-------------
>   drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 110 +++++++++++++-------
>   drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 100 ++++++++++++++++--
>   4 files changed, 242 insertions(+), 115 deletions(-)
> 


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/6] scsi: hisi_sas: Expose multiple hw queues for v3 as experimental
  2019-10-24 14:21 ` [PATCH 6/6] scsi: hisi_sas: Expose multiple hw queues for v3 as experimental John Garry
@ 2019-10-27  8:19   ` Ming Lei
  2019-11-11 14:02     ` John Garry
  0 siblings, 1 reply; 13+ messages in thread
From: Ming Lei @ 2019-10-27  8:19 UTC (permalink / raw)
  To: John Garry
  Cc: jejb, martin.petersen, linux-scsi, linuxarm, linux-kernel, hare

On Thu, Oct 24, 2019 at 10:21:21PM +0800, John Garry wrote:
> Since we're not ready to expose mutliple queues to the upper layer always
> due to CPU hotplug issue, add a new interim experimental command line
> option to support it.
> 
> We still need to keep supporting auto_affine_msi_experimental, since
> people are now replying the performance it provides, even though it is
> unsafe.
> 
> If auto_affine_msi_experimental and expose_mq_experimental are both set,
> then auto_affine_msi_experimental takes preference.
> 
> Signed-off-by: John Garry <john.garry@huawei.com>
> ---
>  drivers/scsi/hisi_sas/hisi_sas.h       |  2 +
>  drivers/scsi/hisi_sas/hisi_sas_main.c  | 55 ++++++++++++++++----------
>  drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 51 +++++++++++++++++++++---
>  3 files changed, 83 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
> index 4eb8f1c53f78..884f2426d753 100644
> --- a/drivers/scsi/hisi_sas/hisi_sas.h
> +++ b/drivers/scsi/hisi_sas/hisi_sas.h
> @@ -8,6 +8,8 @@
>  #define _HISI_SAS_H_
>  
>  #include <linux/acpi.h>
> +#include <linux/blk-mq.h>
> +#include <linux/blk-mq-pci.h>
>  #include <linux/clk.h>
>  #include <linux/debugfs.h>
>  #include <linux/dmapool.h>
> diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
> index 53802c1cc1d0..c8c96a46acfd 100644
> --- a/drivers/scsi/hisi_sas/hisi_sas_main.c
> +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
> @@ -389,9 +389,11 @@ static int hisi_sas_task_prep(struct sas_task *task,
>  	struct hisi_sas_slot *slot;
>  	struct hisi_sas_cmd_hdr	*cmd_hdr_base;
>  	struct asd_sas_port *sas_port = device->port;
> +	struct Scsi_Host *shost = hisi_hba->shost;
>  	struct device *dev = hisi_hba->dev;
>  	int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
>  	int n_elem = 0, n_elem_dif = 0, n_elem_req = 0;
> +	struct scsi_cmnd *scmd = NULL;
>  	struct hisi_sas_dq *dq;
>  	unsigned long flags;
>  	int wr_q_index;
> @@ -407,13 +409,38 @@ static int hisi_sas_task_prep(struct sas_task *task,
>  		return -ECOMM;
>  	}
>  
> -	if (hisi_hba->reply_map) {
> -		int cpu = raw_smp_processor_id();
> -		unsigned int dq_index = hisi_hba->reply_map[cpu];
> +	if (task->uldd_task) {
> +		struct ata_queued_cmd *qc;
>  
> -		*dq_pointer = dq = &hisi_hba->dq[dq_index];
> -	} else {
> +		if (dev_is_sata(device)) {
> +			qc = task->uldd_task;
> +			scmd = qc->scsicmd;
> +		} else {
> +			scmd = task->uldd_task;
> +		}
> +	}
> +
> +	/* We have to move to just a single mode: expose multiple queues */
> +	if (!hisi_hba->reply_map && !shost->nr_hw_queues) {
>  		*dq_pointer = dq = sas_dev->dq;
> +	} else {
> +		if (hisi_hba->reply_map) {
> +			int cpu = raw_smp_processor_id();
> +			unsigned int dq_index = hisi_hba->reply_map[cpu];
> +
> +			*dq_pointer = dq = &hisi_hba->dq[dq_index];
> +		} else {
> +			if (scmd) {
> +				unsigned int dq_index;
> +				u32 blk_tag;
> +
> +				blk_tag = blk_mq_unique_tag(scmd->request);
> +				dq_index = blk_mq_unique_tag_to_hwq(blk_tag);
> +				*dq_pointer = dq = &hisi_hba->dq[dq_index];
> +			} else {
> +				*dq_pointer = dq = sas_dev->dq;
> +			}
> +		}
>  	}
>  
>  	port = to_hisi_sas_port(sas_port);
> @@ -438,22 +465,10 @@ static int hisi_sas_task_prep(struct sas_task *task,
>  	}
>  
>  	if (hisi_hba->hw->slot_index_alloc)
> -		rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device, NULL);
> -	else {
> -		struct scsi_cmnd *scsi_cmnd = NULL;
> -
> -		if (task->uldd_task) {
> -			struct ata_queued_cmd *qc;
> +		rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device, scmd);
> +	else
> +		rc = hisi_sas_slot_index_alloc(hisi_hba, scmd);
>  
> -			if (dev_is_sata(device)) {
> -				qc = task->uldd_task;
> -				scsi_cmnd = qc->scsicmd;
> -			} else {
> -				scsi_cmnd = task->uldd_task;
> -			}
> -		}
> -		rc = hisi_sas_slot_index_alloc(hisi_hba, scsi_cmnd);
> -	}
>  	if (rc < 0)
>  		goto err_out_dif_dma_unmap;
>  
> diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
> index 29119d0b27a7..03ba0416f910 100644
> --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
> +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
> @@ -512,6 +512,11 @@ module_param(auto_affine_msi_experimental, bool, 0444);
>  MODULE_PARM_DESC(auto_affine_msi_experimental, "Enable auto-affinity of MSI IRQs as experimental:\n"
>  		 "default is off");
>  
> +static bool expose_mq_experimental;
> +module_param(expose_mq_experimental, bool, 0444);
> +MODULE_PARM_DESC(expose_mq_experimental, "Expose multiple hw queues to upper layer as experimental:\n"
> +		 "default is off");
> +
>  static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
>  {
>  	void __iomem *regs = hisi_hba->regs + off;
> @@ -558,6 +563,11 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
>  
>  static int bitmaps_alloc_v3_hw(struct hisi_hba *hisi_hba)
>  {
> +	if (expose_mq_experimental)
> +		return sbitmap_init_node(&hisi_hba->slot_index_tags,
> +					 HISI_SAS_MAX_COMMANDS, -1,
> +					 GFP_KERNEL,
> +					 dev_to_node(hisi_hba->dev));
>  	return sbitmap_init_node(&hisi_hba->slot_index_tags,
>  				 HISI_SAS_UNRESERVED_IPTT, -1,
>  				 GFP_KERNEL, dev_to_node(hisi_hba->dev));
> @@ -570,6 +580,10 @@ static int slot_index_alloc_v3_hw(struct hisi_hba *hisi_hba,
>  	struct sbitmap *slot_index_tags = &hisi_hba->slot_index_tags;
>  	int index;
>  
> +	if (expose_mq_experimental)
> +		return sbitmap_get(slot_index_tags,
> +				   hisi_hba->sbitmap_alloc_hint, false);
> +
>  	if (scmd)
>  		return scmd->request->tag;
>  
> @@ -583,7 +597,10 @@ static void slot_index_free_v3_hw(struct hisi_hba *hisi_hba, int slot_idx)
>  {
>  	struct sbitmap *slot_index_tags = &hisi_hba->slot_index_tags;
>  
> -	if (slot_idx >= HISI_SAS_UNRESERVED_IPTT)
> +	if (expose_mq_experimental) {
> +		sbitmap_clear_bit(slot_index_tags, slot_idx);
> +		hisi_hba->sbitmap_alloc_hint = slot_idx;
> +	} else if (slot_idx >= HISI_SAS_UNRESERVED_IPTT)
>  		sbitmap_clear_bit(slot_index_tags,
>  				  slot_idx - HISI_SAS_UNRESERVED_IPTT);
>  }
> @@ -2414,8 +2431,9 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
>  	struct device *dev = hisi_hba->dev;
>  	int vectors;
>  	int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi;
> +	struct Scsi_Host *shost = hisi_hba->shost;
>  
> -	if (auto_affine_msi_experimental) {
> +	if (auto_affine_msi_experimental || expose_mq_experimental) {
>  		struct irq_affinity desc = {
>  			.pre_vectors = BASE_VECTORS_V3_HW,
>  		};
> @@ -2434,7 +2452,9 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
>  							 &desc);
>  		if (vectors < 0)
>  			return -ENOENT;
> -		setup_reply_map_v3_hw(hisi_hba, vectors - BASE_VECTORS_V3_HW);
> +		if (auto_affine_msi_experimental)
> +			setup_reply_map_v3_hw(hisi_hba,
> +					      vectors - BASE_VECTORS_V3_HW);
>  	} else {
>  		min_msi = max_msi;
>  		vectors = pci_alloc_irq_vectors(hisi_hba->pci_dev, min_msi,
> @@ -2444,6 +2464,9 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
>  	}
>  
>  	hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW;
> +	if (expose_mq_experimental)
> +		shost->nr_hw_queues = hisi_hba->cq_nvecs;
> +
>  	return 0;
>  }
>  
> @@ -3096,6 +3119,17 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable)
>  	return 0;
>  }
>  
> +static int hisi_sas_map_queues(struct Scsi_Host *shost)
> +{
> +	struct hisi_hba *hisi_hba = shost_priv(shost);
> +	struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
> +
> +	if (expose_mq_experimental)
> +		return blk_mq_pci_map_queues(qmap, hisi_hba->pci_dev,
> +					     BASE_VECTORS_V3_HW);
> +	return blk_mq_map_queues(qmap);
> +}
> +
>  static struct scsi_host_template sht_v3_hw = {
>  	.name			= DRV_NAME,
>  	.module			= THIS_MODULE,
> @@ -3104,6 +3138,7 @@ static struct scsi_host_template sht_v3_hw = {
>  	.slave_configure	= hisi_sas_slave_configure,
>  	.scan_finished		= hisi_sas_scan_finished,
>  	.scan_start		= hisi_sas_scan_start,
> +	.map_queues		= hisi_sas_map_queues,
>  	.change_queue_depth	= sas_change_queue_depth,
>  	.bios_param		= sas_bios_param,
>  	.this_id		= -1,
> @@ -3265,8 +3300,14 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  	shost->max_lun = ~0;
>  	shost->max_channel = 1;
>  	shost->max_cmd_len = 16;
> -	shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
> -	shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
> +
> +	if (expose_mq_experimental) {
> +		shost->can_queue = HISI_SAS_MAX_COMMANDS;
> +		shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS;

The above is contradictory with current 'nr_hw_queues''s meaning,
see commit on Scsi_Host.nr_hw_queues.


        /*
         * In scsi-mq mode, the number of hardware queues supported by the LLD.
         *
         * Note: it is assumed that each hardware queue has a queue depth of
         * can_queue. In other words, the total queue depth per host
         * is nr_hw_queues * can_queue.
         */

Also this implementation wastes memory too much.


thanks,
Ming


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/6] scsi: hisi_sas: Expose multiple hw queues for v3 as experimental
  2019-10-27  8:19   ` Ming Lei
@ 2019-11-11 14:02     ` John Garry
  2019-11-12 11:10       ` Ming Lei
  0 siblings, 1 reply; 13+ messages in thread
From: John Garry @ 2019-11-11 14:02 UTC (permalink / raw)
  To: Ming Lei; +Cc: jejb, martin.petersen, linux-scsi, linuxarm, linux-kernel, hare

On 27/10/2019 08:19, Ming Lei wrote:
>>   	.this_id		= -1,
>> @@ -3265,8 +3300,14 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>>   	shost->max_lun = ~0;
>>   	shost->max_channel = 1;
>>   	shost->max_cmd_len = 16;
>> -	shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
>> -	shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
>> +

Hi Ming,

I mentioned in the thread "blk-mq: improvement on handling IO during CPU 
hotplug" that I was using this series to test that patchset.

So just with this patchset (and without yours), I get what looks like 
some IO errors in the LLDD. The error is an underflow error. I can't 
figure out what is the cause.

I'm wondering if the SCSI command is getting corrupted someway.

>> +	if (expose_mq_experimental) {
>> +		shost->can_queue = HISI_SAS_MAX_COMMANDS;
>> +		shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS;
> The above is contradictory with current 'nr_hw_queues''s meaning,
> see commit on Scsi_Host.nr_hw_queues.
> 

Right, so I am generating the hostwide tag in the LLDD. And the Scsi 
host-wide host_busy counter should ensure that we don't pump too much IO 
to the HBA.

What other problem will this cause?

Thanks,
John

> 
>          /*
>           * In scsi-mq mode, the number of hardware queues supported by the LLD.
>           *
>           * Note: it is assumed that each hardware queue has a queue depth of
>           * can_queue. In other words, the total queue depth per host
>           * is nr_hw_queues * can_queue.
>           */
> 
> Also this implementation wastes memory too much.
> 
> 
> thanks,
> Ming


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/6] scsi: hisi_sas: Expose multiple hw queues for v3 as experimental
  2019-11-11 14:02     ` John Garry
@ 2019-11-12 11:10       ` Ming Lei
  2019-11-12 13:54         ` John Garry
  0 siblings, 1 reply; 13+ messages in thread
From: Ming Lei @ 2019-11-12 11:10 UTC (permalink / raw)
  To: John Garry
  Cc: jejb, martin.petersen, linux-scsi, linuxarm, linux-kernel, hare

On Mon, Nov 11, 2019 at 02:02:27PM +0000, John Garry wrote:
> On 27/10/2019 08:19, Ming Lei wrote:
> > >   	.this_id		= -1,
> > > @@ -3265,8 +3300,14 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> > >   	shost->max_lun = ~0;
> > >   	shost->max_channel = 1;
> > >   	shost->max_cmd_len = 16;
> > > -	shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
> > > -	shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
> > > +
> 
> Hi Ming,
> 
> I mentioned in the thread "blk-mq: improvement on handling IO during CPU
> hotplug" that I was using this series to test that patchset.
> 
> So just with this patchset (and without yours), I get what looks like some
> IO errors in the LLDD. The error is an underflow error. I can't figure out
> what is the cause.

Can you post the error log? Or interpret the 'underflow error' from hisi
sas or scsi viewpoint?

> 
> I'm wondering if the SCSI command is getting corrupted someway.

Why do you think the command is corrupted?

> 
> > > +	if (expose_mq_experimental) {
> > > +		shost->can_queue = HISI_SAS_MAX_COMMANDS;
> > > +		shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS;
> > The above is contradictory with current 'nr_hw_queues''s meaning,
> > see commit on Scsi_Host.nr_hw_queues.
> > 
> 
> Right, so I am generating the hostwide tag in the LLDD. And the Scsi
> host-wide host_busy counter should ensure that we don't pump too much IO to
> the HBA.

Even without the host-wide host_busy, your approach should work if you
build the hisi sas tag correctly(uniquely), just not efficiently. I'd
suggest you to collect trace and observe if request with expected hisi sas
tag is sent to hardware.

BTW, the patch of 'scsi: core: avoid host-wide host_busy counter for scsi_mq'
will be merged to v5.5 if everything is fine.

https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git/commit/?h=5.5/scsi-queue&id=6eb045e092efefafc6687409a6fa6d1dabf0fb69

Thanks, 
Ming


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/6] scsi: hisi_sas: Expose multiple hw queues for v3 as experimental
  2019-11-12 11:10       ` Ming Lei
@ 2019-11-12 13:54         ` John Garry
  2019-11-12 14:35           ` John Garry
  0 siblings, 1 reply; 13+ messages in thread
From: John Garry @ 2019-11-12 13:54 UTC (permalink / raw)
  To: Ming Lei
  Cc: jejb, martin.petersen, linux-scsi, linuxarm, linux-kernel, hare,
	chenxiang

>>
>> I mentioned in the thread "blk-mq: improvement on handling IO during CPU
>> hotplug" that I was using this series to test that patchset.
>>
>> So just with this patchset (and without yours), I get what looks like some
>> IO errors in the LLDD. The error is an underflow error. I can't figure out
>> what is the cause.
> 

Hi Ming,

> Can you post the error log? Or interpret the 'underflow error' from hisi
> sas or scsi viewpoint?

The check here fails:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/scsi/libsas/sas_scsi_host.c?h=v5.4-rc7#n57

Indeed, no data is received.

> 
>>
>> I'm wondering if the SCSI command is getting corrupted someway.
> 
> Why do you think the command is corrupted?

I considered that the underflow may occur if we were to clobber a SCSI 
command/request from another hctx and zero some fields, which is 
detected as an underflow. But that's just guessing.

However do I find if I set shost->can_queue = HISI_SAS_MAX_COMMANDS / 
#queues, then no issue. But maybe that's a coincidence. For this, total 
queue depth = HISI_SAS_MAX_COMMANDS. I don't see the impact of that.

I need to test that more.

> 
>>
>>>> +	if (expose_mq_experimental) {
>>>> +		shost->can_queue = HISI_SAS_MAX_COMMANDS;
>>>> +		shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS;
>>> The above is contradictory with current 'nr_hw_queues''s meaning,
>>> see commit on Scsi_Host.nr_hw_queues.
>>>
>>
>> Right, so I am generating the hostwide tag in the LLDD. And the Scsi
>> host-wide host_busy counter should ensure that we don't pump too much IO to
>> the HBA.
> 
> Even without the host-wide host_busy, your approach should work if you
> build the hisi sas tag correctly(uniquely), just not efficiently.

Yes, I do that.

  I'd
> suggest you to collect trace and observe if request with expected hisi sas
> tag is sent to hardware.
> 

I can add some debug for that. What trace do you mean?

> BTW, the patch of 'scsi: core: avoid host-wide host_busy counter for scsi_mq'
> will be merged to v5.5 if everything is fine.
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git/commit/?h=5.5/scsi-queue&id=6eb045e092efefafc6687409a6fa6d1dabf0fb69

Yeah, it seems a good change.

Thanks,
John

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/6] scsi: hisi_sas: Expose multiple hw queues for v3 as experimental
  2019-11-12 13:54         ` John Garry
@ 2019-11-12 14:35           ` John Garry
  0 siblings, 0 replies; 13+ messages in thread
From: John Garry @ 2019-11-12 14:35 UTC (permalink / raw)
  To: Ming Lei
  Cc: jejb, martin.petersen, linux-scsi, linuxarm, linux-kernel, hare,
	chenxiang

On 12/11/2019 13:54, John Garry wrote:
>>>
>>> I mentioned in the thread "blk-mq: improvement on handling IO during CPU
>>> hotplug" that I was using this series to test that patchset.
>>>
>>> So just with this patchset (and without yours), I get what looks like 
>>> some
>>> IO errors in the LLDD. The error is an underflow error. I can't 
>>> figure out
>>> what is the cause.
>>
> 
> Hi Ming,
> 
>> Can you post the error log? Or interpret the 'underflow error' from hisi
>> sas or scsi viewpoint?
> 
> The check here fails:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/scsi/libsas/sas_scsi_host.c?h=v5.4-rc7#n57 
> 
> 
> Indeed, no data is received.
> 
>>
>>>
>>> I'm wondering if the SCSI command is getting corrupted someway.
>>
>> Why do you think the command is corrupted?
> 
> I considered that the underflow may occur if we were to clobber a SCSI 
> command/request from another hctx and zero some fields, which is 
> detected as an underflow. But that's just guessing.
> 
> However do I find if I set shost->can_queue = HISI_SAS_MAX_COMMANDS / 
> #queues, then no issue  But maybe that's a coincidence. For this, total
> queue depth = HISI_SAS_MAX_COMMANDS. I don't see the impact of that.
> 

Scratch that. I have seen the issue here also.

Thanks,
John

> I need to test that more.
> 
>>
>>>
>>>>> +    if (expose_mq_experimental) {
>>>>> +        shost->can_queue = HISI_SAS_MAX_COMMANDS;
>>>>> +        shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS;
>>>> The above is contradictory with current 'nr_hw_queues''s meaning,
>>>> see commit on Scsi_Host.nr_hw_queues.
>>>>
>>>
>>> Right, so I am generating the hostwide tag in the LLDD. And the Scsi
>>> host-wide host_busy counter should ensure that we don't pump too much 
>>> IO to
>>> the HBA.
>>
>> Even without the host-wide host_busy, your approach should work if you
>> build the hisi sas tag correctly(uniquely), just not efficiently.
> 
> Yes, I do that.
> 
>   I'd
>> suggest you to collect trace and observe if request with expected hisi 
>> sas
>> tag is sent to hardware.
>>
> 
> I can add some debug for that. What trace do you mean?
> 
>> BTW, the patch of 'scsi: core: avoid host-wide host_busy counter for 
>> scsi_mq'
>> will be merged to v5.5 if everything is fine.
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git/commit/?h=5.5/scsi-queue&id=6eb045e092efefafc6687409a6fa6d1dabf0fb69 
>>
> 
> Yeah, it seems a good change.
> 
> Thanks,
> John
> .


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2019-11-12 14:35 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-24 14:21 [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw as experimental John Garry
2019-10-24 14:21 ` [PATCH 1/6] scsi: hisi_sas: Use sbitmap for IPTT management John Garry
2019-10-24 14:21 ` [PATCH 2/6] scsi: hisi_sas: Pass scsi_cmnd pointer to hisi_sas_hw.slot_index_alloc John Garry
2019-10-24 14:21 ` [PATCH 3/6] scsi: hisi_sas: Add bitmaps_alloc_v3_hw() John Garry
2019-10-24 14:21 ` [PATCH 4/6] scsi: hisi_sas: Add slot_index_alloc_v3_hw() and slot_index_free_v3_hw() John Garry
2019-10-24 14:21 ` [PATCH 5/6] scsi: hisi_sas: Split interrupt_init_v3_hw() John Garry
2019-10-24 14:21 ` [PATCH 6/6] scsi: hisi_sas: Expose multiple hw queues for v3 as experimental John Garry
2019-10-27  8:19   ` Ming Lei
2019-11-11 14:02     ` John Garry
2019-11-12 11:10       ` Ming Lei
2019-11-12 13:54         ` John Garry
2019-11-12 14:35           ` John Garry
2019-10-25 16:04 ` [PATCH 0/6] hisi_sas: Expose multiple hw queues for v3 hw " John Garry

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).