Skip to content

Commit 8d98416

Browse files
John Garryaxboe
authored andcommitted
scsi: hisi_sas: Switch v3 hw to MQ
Now that the block layer provides a shared tag, we can switch the driver to expose all HW queues. Signed-off-by: John Garry <john.garry@huawei.com> Tested-by: Douglas Gilbert <dgilbert@interlog.com> Acked-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 64f1501 commit 8d98416

3 files changed

Lines changed: 56 additions & 70 deletions

File tree

drivers/scsi/hisi_sas/hisi_sas.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#define _HISI_SAS_H_
99

1010
#include <linux/acpi.h>
11+
#include <linux/blk-mq.h>
12+
#include <linux/blk-mq-pci.h>
1113
#include <linux/clk.h>
1214
#include <linux/debugfs.h>
1315
#include <linux/dmapool.h>
@@ -431,7 +433,6 @@ struct hisi_hba {
431433
u32 intr_coal_count; /* Interrupt count to coalesce */
432434

433435
int cq_nvecs;
434-
unsigned int *reply_map;
435436

436437
/* bist */
437438
enum sas_linkrate debugfs_bist_linkrate;

drivers/scsi/hisi_sas/hisi_sas_main.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ static int hisi_sas_task_prep(struct sas_task *task,
417417
struct device *dev = hisi_hba->dev;
418418
int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
419419
int n_elem = 0, n_elem_dif = 0, n_elem_req = 0;
420+
struct scsi_cmnd *scmd = NULL;
420421
struct hisi_sas_dq *dq;
421422
unsigned long flags;
422423
int wr_q_index;
@@ -432,10 +433,23 @@ static int hisi_sas_task_prep(struct sas_task *task,
432433
return -ECOMM;
433434
}
434435

435-
if (hisi_hba->reply_map) {
436-
int cpu = raw_smp_processor_id();
437-
unsigned int dq_index = hisi_hba->reply_map[cpu];
436+
if (task->uldd_task) {
437+
struct ata_queued_cmd *qc;
438438

439+
if (dev_is_sata(device)) {
440+
qc = task->uldd_task;
441+
scmd = qc->scsicmd;
442+
} else {
443+
scmd = task->uldd_task;
444+
}
445+
}
446+
447+
if (scmd) {
448+
unsigned int dq_index;
449+
u32 blk_tag;
450+
451+
blk_tag = blk_mq_unique_tag(scmd->request);
452+
dq_index = blk_mq_unique_tag_to_hwq(blk_tag);
439453
*dq_pointer = dq = &hisi_hba->dq[dq_index];
440454
} else {
441455
*dq_pointer = dq = sas_dev->dq;
@@ -464,21 +478,9 @@ static int hisi_sas_task_prep(struct sas_task *task,
464478

465479
if (hisi_hba->hw->slot_index_alloc)
466480
rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device);
467-
else {
468-
struct scsi_cmnd *scsi_cmnd = NULL;
469-
470-
if (task->uldd_task) {
471-
struct ata_queued_cmd *qc;
481+
else
482+
rc = hisi_sas_slot_index_alloc(hisi_hba, scmd);
472483

473-
if (dev_is_sata(device)) {
474-
qc = task->uldd_task;
475-
scsi_cmnd = qc->scsicmd;
476-
} else {
477-
scsi_cmnd = task->uldd_task;
478-
}
479-
}
480-
rc = hisi_sas_slot_index_alloc(hisi_hba, scsi_cmnd);
481-
}
482484
if (rc < 0)
483485
goto err_out_dif_dma_unmap;
484486

drivers/scsi/hisi_sas/hisi_sas_v3_hw.c

Lines changed: 35 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,68 +2362,36 @@ static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p)
23622362
return IRQ_WAKE_THREAD;
23632363
}
23642364

2365-
static void setup_reply_map_v3_hw(struct hisi_hba *hisi_hba, int nvecs)
2365+
static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
23662366
{
2367-
const struct cpumask *mask;
2368-
int queue, cpu;
2367+
int vectors;
2368+
int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi;
2369+
struct Scsi_Host *shost = hisi_hba->shost;
2370+
struct irq_affinity desc = {
2371+
.pre_vectors = BASE_VECTORS_V3_HW,
2372+
};
23692373

2370-
for (queue = 0; queue < nvecs; queue++) {
2371-
struct hisi_sas_cq *cq = &hisi_hba->cq[queue];
2374+
min_msi = MIN_AFFINE_VECTORS_V3_HW;
2375+
vectors = pci_alloc_irq_vectors_affinity(hisi_hba->pci_dev,
2376+
min_msi, max_msi,
2377+
PCI_IRQ_MSI |
2378+
PCI_IRQ_AFFINITY,
2379+
&desc);
2380+
if (vectors < 0)
2381+
return -ENOENT;
23722382

2373-
mask = pci_irq_get_affinity(hisi_hba->pci_dev, queue +
2374-
BASE_VECTORS_V3_HW);
2375-
if (!mask)
2376-
goto fallback;
2377-
cq->irq_mask = mask;
2378-
for_each_cpu(cpu, mask)
2379-
hisi_hba->reply_map[cpu] = queue;
2380-
}
2381-
return;
23822383

2383-
fallback:
2384-
for_each_possible_cpu(cpu)
2385-
hisi_hba->reply_map[cpu] = cpu % hisi_hba->queue_count;
2386-
/* Don't clean all CQ masks */
2384+
hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW;
2385+
shost->nr_hw_queues = hisi_hba->cq_nvecs;
2386+
2387+
return 0;
23872388
}
23882389

23892390
static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
23902391
{
23912392
struct device *dev = hisi_hba->dev;
23922393
struct pci_dev *pdev = hisi_hba->pci_dev;
2393-
int vectors, rc, i;
2394-
int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi;
2395-
2396-
if (auto_affine_msi_experimental) {
2397-
struct irq_affinity desc = {
2398-
.pre_vectors = BASE_VECTORS_V3_HW,
2399-
};
2400-
2401-
dev_info(dev, "Enable MSI auto-affinity\n");
2402-
2403-
min_msi = MIN_AFFINE_VECTORS_V3_HW;
2404-
2405-
hisi_hba->reply_map = devm_kcalloc(dev, nr_cpu_ids,
2406-
sizeof(unsigned int),
2407-
GFP_KERNEL);
2408-
if (!hisi_hba->reply_map)
2409-
return -ENOMEM;
2410-
vectors = pci_alloc_irq_vectors_affinity(hisi_hba->pci_dev,
2411-
min_msi, max_msi,
2412-
PCI_IRQ_MSI |
2413-
PCI_IRQ_AFFINITY,
2414-
&desc);
2415-
if (vectors < 0)
2416-
return -ENOENT;
2417-
setup_reply_map_v3_hw(hisi_hba, vectors - BASE_VECTORS_V3_HW);
2418-
} else {
2419-
min_msi = max_msi;
2420-
vectors = pci_alloc_irq_vectors(hisi_hba->pci_dev, min_msi,
2421-
max_msi, PCI_IRQ_MSI);
2422-
if (vectors < 0)
2423-
return vectors;
2424-
}
2425-
2426-
hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW;
2394+
int rc, i;
24272395

24282396
rc = devm_request_irq(dev, pci_irq_vector(pdev, 1),
24292397
int_phy_up_down_bcast_v3_hw, 0,
@@ -3072,6 +3040,15 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable)
30723040
return 0;
30733041
}
30743042

3043+
static int hisi_sas_map_queues(struct Scsi_Host *shost)
3044+
{
3045+
struct hisi_hba *hisi_hba = shost_priv(shost);
3046+
struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
3047+
3048+
return blk_mq_pci_map_queues(qmap, hisi_hba->pci_dev,
3049+
BASE_VECTORS_V3_HW);
3050+
}
3051+
30753052
static struct scsi_host_template sht_v3_hw = {
30763053
.name = DRV_NAME,
30773054
.proc_name = DRV_NAME,
@@ -3082,6 +3059,7 @@ static struct scsi_host_template sht_v3_hw = {
30823059
.slave_configure = hisi_sas_slave_configure,
30833060
.scan_finished = hisi_sas_scan_finished,
30843061
.scan_start = hisi_sas_scan_start,
3062+
.map_queues = hisi_sas_map_queues,
30853063
.change_queue_depth = sas_change_queue_depth,
30863064
.bios_param = sas_bios_param,
30873065
.this_id = -1,
@@ -3098,6 +3076,7 @@ static struct scsi_host_template sht_v3_hw = {
30983076
.shost_attrs = host_attrs_v3_hw,
30993077
.tag_alloc_policy = BLK_TAG_ALLOC_RR,
31003078
.host_reset = hisi_sas_host_reset,
3079+
.host_tagset = 1,
31013080
};
31023081

31033082
static const struct hisi_sas_hw hisi_sas_v3_hw = {
@@ -3269,6 +3248,10 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
32693248
if (hisi_sas_debugfs_enable)
32703249
hisi_sas_debugfs_init(hisi_hba);
32713250

3251+
rc = interrupt_preinit_v3_hw(hisi_hba);
3252+
if (rc)
3253+
goto err_out_ha;
3254+
dev_err(dev, "%d hw queues\n", shost->nr_hw_queues);
32723255
rc = scsi_add_host(shost, dev);
32733256
if (rc)
32743257
goto err_out_ha;

0 commit comments

Comments
 (0)