Skip to content

Commit 688daed

Browse files
committed
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "This is two driver fixes (megaraid_sas and hisi_sas). The megaraid one is a revert of a previous revert of a cpu hotplug fix which exposed a bug in the block layer which has been fixed in this merge window. The hisi_sas performance enhancement comes from switching to interrupt managed completion queues, which depended on the addition of devm_platform_get_irqs_affinity() which is now upstream via the irq tree in the last merge window" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: hisi_sas: Expose HW queues for v2 hw Revert "Revert "scsi: megaraid_sas: Added support for shared host tagset for cpuhotplug""
2 parents ed41fd0 + a8f8088 commit 688daed

File tree

5 files changed

+123
-26
lines changed

5 files changed

+123
-26
lines changed

drivers/scsi/hisi_sas/hisi_sas.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/debugfs.h>
1515
#include <linux/dmapool.h>
1616
#include <linux/iopoll.h>
17+
#include <linux/irq.h>
1718
#include <linux/lcm.h>
1819
#include <linux/libata.h>
1920
#include <linux/mfd/syscon.h>
@@ -294,6 +295,7 @@ enum {
294295

295296
struct hisi_sas_hw {
296297
int (*hw_init)(struct hisi_hba *hisi_hba);
298+
int (*interrupt_preinit)(struct hisi_hba *hisi_hba);
297299
void (*setup_itct)(struct hisi_hba *hisi_hba,
298300
struct hisi_sas_device *device);
299301
int (*slot_index_alloc)(struct hisi_hba *hisi_hba,
@@ -393,6 +395,8 @@ struct hisi_hba {
393395
u32 refclk_frequency_mhz;
394396
u8 sas_addr[SAS_ADDR_SIZE];
395397

398+
int *irq_map; /* v2 hw */
399+
396400
int n_phy;
397401
spinlock_t lock;
398402
struct semaphore sem;

drivers/scsi/hisi_sas/hisi_sas_main.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2614,6 +2614,13 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
26142614
return NULL;
26152615
}
26162616

2617+
static int hisi_sas_interrupt_preinit(struct hisi_hba *hisi_hba)
2618+
{
2619+
if (hisi_hba->hw->interrupt_preinit)
2620+
return hisi_hba->hw->interrupt_preinit(hisi_hba);
2621+
return 0;
2622+
}
2623+
26172624
int hisi_sas_probe(struct platform_device *pdev,
26182625
const struct hisi_sas_hw *hw)
26192626
{
@@ -2671,6 +2678,10 @@ int hisi_sas_probe(struct platform_device *pdev,
26712678
sha->sas_port[i] = &hisi_hba->port[i].sas_port;
26722679
}
26732680

2681+
rc = hisi_sas_interrupt_preinit(hisi_hba);
2682+
if (rc)
2683+
goto err_out_ha;
2684+
26742685
rc = scsi_add_host(shost, &pdev->dev);
26752686
if (rc)
26762687
goto err_out_ha;

drivers/scsi/hisi_sas/hisi_sas_v2_hw.c

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3302,6 +3302,28 @@ static irq_handler_t fatal_interrupts[HISI_SAS_FATAL_INT_NR] = {
33023302
fatal_axi_int_v2_hw
33033303
};
33043304

3305+
#define CQ0_IRQ_INDEX (96)
3306+
3307+
static int hisi_sas_v2_interrupt_preinit(struct hisi_hba *hisi_hba)
3308+
{
3309+
struct platform_device *pdev = hisi_hba->platform_dev;
3310+
struct Scsi_Host *shost = hisi_hba->shost;
3311+
struct irq_affinity desc = {
3312+
.pre_vectors = CQ0_IRQ_INDEX,
3313+
.post_vectors = 16,
3314+
};
3315+
int resv = desc.pre_vectors + desc.post_vectors, minvec = resv + 1, nvec;
3316+
3317+
nvec = devm_platform_get_irqs_affinity(pdev, &desc, minvec, 128,
3318+
&hisi_hba->irq_map);
3319+
if (nvec < 0)
3320+
return nvec;
3321+
3322+
shost->nr_hw_queues = hisi_hba->cq_nvecs = nvec - resv;
3323+
3324+
return 0;
3325+
}
3326+
33053327
/*
33063328
* There is a limitation in the hip06 chipset that we need
33073329
* to map in all mbigen interrupts, even if they are not used.
@@ -3310,14 +3332,11 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
33103332
{
33113333
struct platform_device *pdev = hisi_hba->platform_dev;
33123334
struct device *dev = &pdev->dev;
3313-
int irq, rc = 0, irq_map[128];
3335+
int irq, rc = 0;
33143336
int i, phy_no, fatal_no, queue_no;
33153337

3316-
for (i = 0; i < 128; i++)
3317-
irq_map[i] = platform_get_irq(pdev, i);
3318-
33193338
for (i = 0; i < HISI_SAS_PHY_INT_NR; i++) {
3320-
irq = irq_map[i + 1]; /* Phy up/down is irq1 */
3339+
irq = hisi_hba->irq_map[i + 1]; /* Phy up/down is irq1 */
33213340
rc = devm_request_irq(dev, irq, phy_interrupts[i], 0,
33223341
DRV_NAME " phy", hisi_hba);
33233342
if (rc) {
@@ -3331,7 +3350,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
33313350
for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
33323351
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
33333352

3334-
irq = irq_map[phy_no + 72];
3353+
irq = hisi_hba->irq_map[phy_no + 72];
33353354
rc = devm_request_irq(dev, irq, sata_int_v2_hw, 0,
33363355
DRV_NAME " sata", phy);
33373356
if (rc) {
@@ -3343,7 +3362,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
33433362
}
33443363

33453364
for (fatal_no = 0; fatal_no < HISI_SAS_FATAL_INT_NR; fatal_no++) {
3346-
irq = irq_map[fatal_no + 81];
3365+
irq = hisi_hba->irq_map[fatal_no + 81];
33473366
rc = devm_request_irq(dev, irq, fatal_interrupts[fatal_no], 0,
33483367
DRV_NAME " fatal", hisi_hba);
33493368
if (rc) {
@@ -3354,24 +3373,22 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
33543373
}
33553374
}
33563375

3357-
for (queue_no = 0; queue_no < hisi_hba->queue_count; queue_no++) {
3376+
for (queue_no = 0; queue_no < hisi_hba->cq_nvecs; queue_no++) {
33583377
struct hisi_sas_cq *cq = &hisi_hba->cq[queue_no];
33593378

3360-
cq->irq_no = irq_map[queue_no + 96];
3379+
cq->irq_no = hisi_hba->irq_map[queue_no + 96];
33613380
rc = devm_request_threaded_irq(dev, cq->irq_no,
33623381
cq_interrupt_v2_hw,
33633382
cq_thread_v2_hw, IRQF_ONESHOT,
33643383
DRV_NAME " cq", cq);
33653384
if (rc) {
33663385
dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n",
3367-
irq, rc);
3386+
cq->irq_no, rc);
33683387
rc = -ENOENT;
33693388
goto err_out;
33703389
}
3390+
cq->irq_mask = irq_get_affinity_mask(cq->irq_no);
33713391
}
3372-
3373-
hisi_hba->cq_nvecs = hisi_hba->queue_count;
3374-
33753392
err_out:
33763393
return rc;
33773394
}
@@ -3529,6 +3546,26 @@ static struct device_attribute *host_attrs_v2_hw[] = {
35293546
NULL
35303547
};
35313548

3549+
static int map_queues_v2_hw(struct Scsi_Host *shost)
3550+
{
3551+
struct hisi_hba *hisi_hba = shost_priv(shost);
3552+
struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
3553+
const struct cpumask *mask;
3554+
unsigned int queue, cpu;
3555+
3556+
for (queue = 0; queue < qmap->nr_queues; queue++) {
3557+
mask = irq_get_affinity_mask(hisi_hba->irq_map[96 + queue]);
3558+
if (!mask)
3559+
continue;
3560+
3561+
for_each_cpu(cpu, mask)
3562+
qmap->mq_map[cpu] = qmap->queue_offset + queue;
3563+
}
3564+
3565+
return 0;
3566+
3567+
}
3568+
35323569
static struct scsi_host_template sht_v2_hw = {
35333570
.name = DRV_NAME,
35343571
.proc_name = DRV_NAME,
@@ -3553,10 +3590,13 @@ static struct scsi_host_template sht_v2_hw = {
35533590
#endif
35543591
.shost_attrs = host_attrs_v2_hw,
35553592
.host_reset = hisi_sas_host_reset,
3593+
.map_queues = map_queues_v2_hw,
3594+
.host_tagset = 1,
35563595
};
35573596

35583597
static const struct hisi_sas_hw hisi_sas_v2_hw = {
35593598
.hw_init = hisi_sas_v2_init,
3599+
.interrupt_preinit = hisi_sas_v2_interrupt_preinit,
35603600
.setup_itct = setup_itct_v2_hw,
35613601
.slot_index_alloc = slot_index_alloc_quirk_v2_hw,
35623602
.alloc_dev = alloc_dev_quirk_v2_hw,

drivers/scsi/megaraid/megaraid_sas_base.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <linux/poll.h>
3838
#include <linux/vmalloc.h>
3939
#include <linux/irq_poll.h>
40+
#include <linux/blk-mq-pci.h>
4041

4142
#include <scsi/scsi.h>
4243
#include <scsi/scsi_cmnd.h>
@@ -113,6 +114,10 @@ unsigned int enable_sdev_max_qd;
113114
module_param(enable_sdev_max_qd, int, 0444);
114115
MODULE_PARM_DESC(enable_sdev_max_qd, "Enable sdev max qd as can_queue. Default: 0");
115116

117+
int host_tagset_enable = 1;
118+
module_param(host_tagset_enable, int, 0444);
119+
MODULE_PARM_DESC(host_tagset_enable, "Shared host tagset enable/disable Default: enable(1)");
120+
116121
MODULE_LICENSE("GPL");
117122
MODULE_VERSION(MEGASAS_VERSION);
118123
MODULE_AUTHOR("megaraidlinux.pdl@broadcom.com");
@@ -3119,6 +3124,19 @@ megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
31193124
return 0;
31203125
}
31213126

3127+
static int megasas_map_queues(struct Scsi_Host *shost)
3128+
{
3129+
struct megasas_instance *instance;
3130+
3131+
instance = (struct megasas_instance *)shost->hostdata;
3132+
3133+
if (shost->nr_hw_queues == 1)
3134+
return 0;
3135+
3136+
return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT],
3137+
instance->pdev, instance->low_latency_index_start);
3138+
}
3139+
31223140
static void megasas_aen_polling(struct work_struct *work);
31233141

31243142
/**
@@ -3427,6 +3445,7 @@ static struct scsi_host_template megasas_template = {
34273445
.eh_timed_out = megasas_reset_timer,
34283446
.shost_attrs = megaraid_host_attrs,
34293447
.bios_param = megasas_bios_param,
3448+
.map_queues = megasas_map_queues,
34303449
.change_queue_depth = scsi_change_queue_depth,
34313450
.max_segment_size = 0xffffffff,
34323451
};
@@ -6808,6 +6827,26 @@ static int megasas_io_attach(struct megasas_instance *instance)
68086827
host->max_lun = MEGASAS_MAX_LUN;
68096828
host->max_cmd_len = 16;
68106829

6830+
/* Use shared host tagset only for fusion adaptors
6831+
* if there are managed interrupts (smp affinity enabled case).
6832+
* Single msix_vectors in kdump, so shared host tag is also disabled.
6833+
*/
6834+
6835+
host->host_tagset = 0;
6836+
host->nr_hw_queues = 1;
6837+
6838+
if ((instance->adapter_type != MFI_SERIES) &&
6839+
(instance->msix_vectors > instance->low_latency_index_start) &&
6840+
host_tagset_enable &&
6841+
instance->smp_affinity_enable) {
6842+
host->host_tagset = 1;
6843+
host->nr_hw_queues = instance->msix_vectors -
6844+
instance->low_latency_index_start;
6845+
}
6846+
6847+
dev_info(&instance->pdev->dev,
6848+
"Max firmware commands: %d shared with nr_hw_queues = %d\n",
6849+
instance->max_fw_cmds, host->nr_hw_queues);
68116850
/*
68126851
* Notify the mid-layer about the new controller
68136852
*/

drivers/scsi/megaraid/megaraid_sas_fusion.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -359,24 +359,29 @@ megasas_get_msix_index(struct megasas_instance *instance,
359359
{
360360
int sdev_busy;
361361

362-
/* nr_hw_queue = 1 for MegaRAID */
363-
struct blk_mq_hw_ctx *hctx =
364-
scmd->device->request_queue->queue_hw_ctx[0];
365-
366-
sdev_busy = atomic_read(&hctx->nr_active);
362+
/* TBD - if sml remove device_busy in future, driver
363+
* should track counter in internal structure.
364+
*/
365+
sdev_busy = atomic_read(&scmd->device->device_busy);
367366

368367
if (instance->perf_mode == MR_BALANCED_PERF_MODE &&
369-
sdev_busy > (data_arms * MR_DEVICE_HIGH_IOPS_DEPTH))
368+
sdev_busy > (data_arms * MR_DEVICE_HIGH_IOPS_DEPTH)) {
370369
cmd->request_desc->SCSIIO.MSIxIndex =
371370
mega_mod64((atomic64_add_return(1, &instance->high_iops_outstanding) /
372371
MR_HIGH_IOPS_BATCH_COUNT), instance->low_latency_index_start);
373-
else if (instance->msix_load_balance)
372+
} else if (instance->msix_load_balance) {
374373
cmd->request_desc->SCSIIO.MSIxIndex =
375374
(mega_mod64(atomic64_add_return(1, &instance->total_io_count),
376375
instance->msix_vectors));
377-
else
376+
} else if (instance->host->nr_hw_queues > 1) {
377+
u32 tag = blk_mq_unique_tag(scmd->request);
378+
379+
cmd->request_desc->SCSIIO.MSIxIndex = blk_mq_unique_tag_to_hwq(tag) +
380+
instance->low_latency_index_start;
381+
} else {
378382
cmd->request_desc->SCSIIO.MSIxIndex =
379383
instance->reply_map[raw_smp_processor_id()];
384+
}
380385
}
381386

382387
/**
@@ -956,9 +961,6 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
956961
if (megasas_alloc_cmdlist_fusion(instance))
957962
goto fail_exit;
958963

959-
dev_info(&instance->pdev->dev, "Configured max firmware commands: %d\n",
960-
instance->max_fw_cmds);
961-
962964
/* The first 256 bytes (SMID 0) is not used. Don't add to the cmd list */
963965
io_req_base = fusion->io_request_frames + MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
964966
io_req_base_phys = fusion->io_request_frames_phys + MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
@@ -1102,8 +1104,9 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
11021104
MR_HIGH_IOPS_QUEUE_COUNT) && cur_intr_coalescing)
11031105
instance->perf_mode = MR_BALANCED_PERF_MODE;
11041106

1105-
dev_info(&instance->pdev->dev, "Performance mode :%s\n",
1106-
MEGASAS_PERF_MODE_2STR(instance->perf_mode));
1107+
dev_info(&instance->pdev->dev, "Performance mode :%s (latency index = %d)\n",
1108+
MEGASAS_PERF_MODE_2STR(instance->perf_mode),
1109+
instance->low_latency_index_start);
11071110

11081111
instance->fw_sync_cache_support = (scratch_pad_1 &
11091112
MR_CAN_HANDLE_SYNC_CACHE_OFFSET) ? 1 : 0;

0 commit comments

Comments
 (0)