Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: aacraid: Reply queue mapping to CPUs based on IRQ affinity

Fix the I/O hang that arises because of the MSIx vector not having a mapped
online CPU upon receiving completion.

SCSI cmds take the blk_mq route, which is setup during init. Reserved cmds
fetch the vector_no from mq_map after init is complete. Before init, they
have to use 0 - as per the norm.

Reviewed-by: Gilbert Wu <gilbert.wu@microchip.com>
Signed-off-by: Sagar Biradar <Sagar.Biradar@microchip.com>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Link: https://lore.kernel.org/r/20230519230834.27436-1-sagar.biradar@microchip.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Sagar Biradar and committed by
Martin K. Petersen
9dc704dc 6d074ce2

+43 -3
+1
drivers/scsi/aacraid/aacraid.h
··· 1678 1678 u32 handle_pci_error; 1679 1679 bool init_reset; 1680 1680 u8 soft_reset_support; 1681 + u8 use_map_queue; 1681 1682 }; 1682 1683 1683 1684 #define aac_adapter_interrupt(dev) \
+5 -1
drivers/scsi/aacraid/commsup.c
··· 223 223 struct fib *aac_fib_alloc_tag(struct aac_dev *dev, struct scsi_cmnd *scmd) 224 224 { 225 225 struct fib *fibptr; 226 + u32 blk_tag; 227 + int i; 226 228 227 - fibptr = &dev->fibs[scsi_cmd_to_rq(scmd)->tag]; 229 + blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); 230 + i = blk_mq_unique_tag_to_tag(blk_tag); 231 + fibptr = &dev->fibs[i]; 228 232 /* 229 233 * Null out fields that depend on being zero at the start of 230 234 * each I/O
+14
drivers/scsi/aacraid/linit.c
··· 19 19 20 20 #include <linux/compat.h> 21 21 #include <linux/blkdev.h> 22 + #include <linux/blk-mq-pci.h> 22 23 #include <linux/completion.h> 23 24 #include <linux/init.h> 24 25 #include <linux/interrupt.h> ··· 503 502 sdev->tagged_supported = 1; 504 503 505 504 return 0; 505 + } 506 + 507 + static void aac_map_queues(struct Scsi_Host *shost) 508 + { 509 + struct aac_dev *aac = (struct aac_dev *)shost->hostdata; 510 + 511 + blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], 512 + aac->pdev, 0); 513 + aac->use_map_queue = true; 506 514 } 507 515 508 516 /** ··· 1498 1488 .bios_param = aac_biosparm, 1499 1489 .shost_groups = aac_host_groups, 1500 1490 .slave_configure = aac_slave_configure, 1491 + .map_queues = aac_map_queues, 1501 1492 .change_queue_depth = aac_change_queue_depth, 1502 1493 .sdev_groups = aac_dev_groups, 1503 1494 .eh_abort_handler = aac_eh_abort, ··· 1786 1775 shost->max_lun = AAC_MAX_LUN; 1787 1776 1788 1777 pci_set_drvdata(pdev, shost); 1778 + shost->nr_hw_queues = aac->max_msix; 1779 + shost->host_tagset = 1; 1789 1780 1790 1781 error = scsi_add_host(shost, &pdev->dev); 1791 1782 if (error) ··· 1919 1906 struct aac_dev *aac = (struct aac_dev *)shost->hostdata; 1920 1907 1921 1908 aac_cancel_rescan_worker(aac); 1909 + aac->use_map_queue = false; 1922 1910 scsi_remove_host(shost); 1923 1911 1924 1912 __aac_shutdown(aac);
+23 -2
drivers/scsi/aacraid/src.c
··· 493 493 #endif 494 494 495 495 u16 vector_no; 496 + struct scsi_cmnd *scmd; 497 + u32 blk_tag; 498 + struct Scsi_Host *shost = dev->scsi_host_ptr; 499 + struct blk_mq_queue_map *qmap; 496 500 497 501 atomic_inc(&q->numpending); 498 502 ··· 509 505 if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) 510 506 && dev->sa_firmware) 511 507 vector_no = aac_get_vector(dev); 512 - else 513 - vector_no = fib->vector_no; 508 + else { 509 + if (!fib->vector_no || !fib->callback_data) { 510 + if (shost && dev->use_map_queue) { 511 + qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; 512 + vector_no = qmap->mq_map[raw_smp_processor_id()]; 513 + } 514 + /* 515 + * We hardcode the vector_no for 516 + * reserved commands as a valid shost is 517 + * absent during the init 518 + */ 519 + else 520 + vector_no = 0; 521 + } else { 522 + scmd = (struct scsi_cmnd *)fib->callback_data; 523 + blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); 524 + vector_no = blk_mq_unique_tag_to_hwq(blk_tag); 525 + } 526 + } 514 527 515 528 if (native_hba) { 516 529 if (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF) {