Skip to content

Commit 52f6e19

Browse files
Karan Tilak Kumarmartinkpetersen
authored andcommitted
scsi: fnic: Add support for multiqueue (MQ) in fnic_main.c
Set map_queues in the fnic_host_template to fnic_mq_map_queues_cpus. Define fnic_mq_map_queues_cpus to set cpu assignment to fnic queues. Refactor code in fnic_probe to enable vnic queues before scsi_add_host. Modify notify set to the correct index. Reviewed-by: Sesidhar Baddela <[email protected]> Reviewed-by: Arulprabhu Ponnusamy <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: John Garry <[email protected]> Signed-off-by: Karan Tilak Kumar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 848d010 commit 52f6e19

File tree

2 files changed

+77
-34
lines changed

2 files changed

+77
-34
lines changed

drivers/scsi/fnic/fnic.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ static inline u64 fnic_flags_and_state(struct scsi_cmnd *cmd)
109109
#define FNIC_ABT_TERM_DELAY_TIMEOUT 500 /* mSec */
110110

111111
#define FNIC_MAX_FCP_TARGET 256
112-
112+
#define FNIC_PCI_OFFSET 2
113113
/**
114114
* state_flags to identify host state along along with fnic's state
115115
**/
@@ -386,7 +386,7 @@ void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq,
386386
int fnic_fw_reset_handler(struct fnic *fnic);
387387
void fnic_terminate_rport_io(struct fc_rport *);
388388
const char *fnic_state_to_str(unsigned int state);
389-
389+
void fnic_mq_map_queues_cpus(struct Scsi_Host *host);
390390
void fnic_log_q_error(struct fnic *fnic);
391391
void fnic_handle_link_event(struct fnic *fnic);
392392

drivers/scsi/fnic/fnic_main.c

Lines changed: 75 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
#include <linux/pci.h>
1313
#include <linux/skbuff.h>
1414
#include <linux/interrupt.h>
15+
#include <linux/irq.h>
1516
#include <linux/spinlock.h>
1617
#include <linux/workqueue.h>
1718
#include <linux/if_ether.h>
19+
#include <linux/blk-mq-pci.h>
1820
#include <scsi/fc/fc_fip.h>
1921
#include <scsi/scsi_host.h>
2022
#include <scsi/scsi_transport.h>
@@ -114,6 +116,7 @@ static const struct scsi_host_template fnic_host_template = {
114116
.shost_groups = fnic_host_groups,
115117
.track_queue_depth = 1,
116118
.cmd_size = sizeof(struct fnic_cmd_priv),
119+
.map_queues = fnic_mq_map_queues_cpus,
117120
};
118121

119122
static void
@@ -390,7 +393,7 @@ static int fnic_notify_set(struct fnic *fnic)
390393
err = vnic_dev_notify_set(fnic->vdev, -1);
391394
break;
392395
case VNIC_DEV_INTR_MODE_MSIX:
393-
err = vnic_dev_notify_set(fnic->vdev, FNIC_MSIX_ERR_NOTIFY);
396+
err = vnic_dev_notify_set(fnic->vdev, fnic->wq_copy_count + fnic->copy_wq_base);
394397
break;
395398
default:
396399
shost_printk(KERN_ERR, fnic->lport->host,
@@ -563,11 +566,6 @@ static int fnic_scsi_drv_init(struct fnic *fnic)
563566
host->max_cmd_len = FCOE_MAX_CMD_LEN;
564567

565568
host->nr_hw_queues = fnic->wq_copy_count;
566-
if (host->nr_hw_queues > 1)
567-
shost_printk(KERN_ERR, host,
568-
"fnic: blk-mq is not supported");
569-
570-
host->nr_hw_queues = fnic->wq_copy_count = 1;
571569

572570
shost_printk(KERN_INFO, host,
573571
"fnic: can_queue: %d max_lun: %llu",
@@ -580,6 +578,32 @@ static int fnic_scsi_drv_init(struct fnic *fnic)
580578
return 0;
581579
}
582580

581+
void fnic_mq_map_queues_cpus(struct Scsi_Host *host)
582+
{
583+
struct fc_lport *lp = shost_priv(host);
584+
struct fnic *fnic = lport_priv(lp);
585+
struct pci_dev *l_pdev = fnic->pdev;
586+
int intr_mode = fnic->config.intr_mode;
587+
struct blk_mq_queue_map *qmap = &host->tag_set.map[HCTX_TYPE_DEFAULT];
588+
589+
if (intr_mode == VNIC_DEV_INTR_MODE_MSI || intr_mode == VNIC_DEV_INTR_MODE_INTX) {
590+
FNIC_MAIN_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
591+
"intr_mode is not msix\n");
592+
return;
593+
}
594+
595+
FNIC_MAIN_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
596+
"qmap->nr_queues: %d\n", qmap->nr_queues);
597+
598+
if (l_pdev == NULL) {
599+
FNIC_MAIN_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
600+
"l_pdev is null\n");
601+
return;
602+
}
603+
604+
blk_mq_pci_map_queues(qmap, l_pdev, FNIC_PCI_OFFSET);
605+
}
606+
583607
static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
584608
{
585609
struct Scsi_Host *host;
@@ -590,6 +614,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
590614
int fnic_id = 0;
591615
int i;
592616
unsigned long flags;
617+
int hwq;
593618

594619
/*
595620
* Allocate SCSI Host and set up association between host,
@@ -613,8 +638,8 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
613638
}
614639
fnic->lport = lp;
615640
fnic->ctlr.lp = lp;
616-
617641
fnic->link_events = 0;
642+
fnic->pdev = pdev;
618643

619644
snprintf(fnic->name, sizeof(fnic->name) - 1, "%s%d", DRV_NAME,
620645
host->host_no);
@@ -623,11 +648,6 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
623648
fnic->fnic_num = fnic_id;
624649
fnic_stats_debugfs_init(fnic);
625650

626-
/* Setup PCI resources */
627-
pci_set_drvdata(pdev, fnic);
628-
629-
fnic->pdev = pdev;
630-
631651
err = pci_enable_device(pdev);
632652
if (err) {
633653
shost_printk(KERN_ERR, fnic->lport->host,
@@ -729,7 +749,8 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
729749
goto err_out_dev_close;
730750
}
731751

732-
fnic_scsi_drv_init(fnic);
752+
/* Setup PCI resources */
753+
pci_set_drvdata(pdev, fnic);
733754

734755
fnic_get_res_counts(fnic);
735756

@@ -749,6 +770,16 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
749770
goto err_out_clear_intr;
750771
}
751772

773+
fnic_scsi_drv_init(fnic);
774+
775+
for (hwq = 0; hwq < fnic->wq_copy_count; hwq++) {
776+
fnic->sw_copy_wq[hwq].ioreq_table_size = fnic->fnic_max_tag_id;
777+
fnic->sw_copy_wq[hwq].io_req_table =
778+
kzalloc((fnic->sw_copy_wq[hwq].ioreq_table_size + 1) *
779+
sizeof(struct fnic_io_req *), GFP_KERNEL);
780+
}
781+
shost_printk(KERN_INFO, fnic->lport->host, "fnic copy wqs: %d, Q0 ioreq table size: %d\n",
782+
fnic->wq_copy_count, fnic->sw_copy_wq[0].ioreq_table_size);
752783

753784
/* initialize all fnic locks */
754785
spin_lock_init(&fnic->fnic_lock);
@@ -835,16 +866,32 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
835866

836867
/* allocate RQ buffers and post them to RQ*/
837868
for (i = 0; i < fnic->rq_count; i++) {
838-
vnic_rq_enable(&fnic->rq[i]);
839869
err = vnic_rq_fill(&fnic->rq[i], fnic_alloc_rq_frame);
840870
if (err) {
841871
shost_printk(KERN_ERR, fnic->lport->host,
842872
"fnic_alloc_rq_frame can't alloc "
843873
"frame\n");
844-
goto err_out_free_rq_buf;
874+
goto err_out_rq_buf;
845875
}
846876
}
847877

878+
/* Enable all queues */
879+
for (i = 0; i < fnic->raw_wq_count; i++)
880+
vnic_wq_enable(&fnic->wq[i]);
881+
for (i = 0; i < fnic->rq_count; i++) {
882+
if (!ioread32(&fnic->rq[i].ctrl->enable))
883+
vnic_rq_enable(&fnic->rq[i]);
884+
}
885+
for (i = 0; i < fnic->wq_copy_count; i++)
886+
vnic_wq_copy_enable(&fnic->hw_copy_wq[i]);
887+
888+
err = fnic_request_intr(fnic);
889+
if (err) {
890+
shost_printk(KERN_ERR, fnic->lport->host,
891+
"Unable to request irq.\n");
892+
goto err_out_request_intr;
893+
}
894+
848895
/*
849896
* Initialization done with PCI system, hardware, firmware.
850897
* Add host to SCSI
@@ -853,9 +900,10 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
853900
if (err) {
854901
shost_printk(KERN_ERR, fnic->lport->host,
855902
"fnic: scsi_add_host failed...exiting\n");
856-
goto err_out_free_rq_buf;
903+
goto err_out_scsi_add_host;
857904
}
858905

906+
859907
/* Start local port initiatialization */
860908

861909
lp->link_up = 0;
@@ -879,7 +927,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
879927
if (!fc_exch_mgr_alloc(lp, FC_CLASS_3, FCPIO_HOST_EXCH_RANGE_START,
880928
FCPIO_HOST_EXCH_RANGE_END, NULL)) {
881929
err = -ENOMEM;
882-
goto err_out_remove_scsi_host;
930+
goto err_out_fc_exch_mgr_alloc;
883931
}
884932

885933
fc_lport_init_stats(lp);
@@ -907,21 +955,8 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
907955
skb_queue_head_init(&fnic->frame_queue);
908956
skb_queue_head_init(&fnic->tx_queue);
909957

910-
/* Enable all queues */
911-
for (i = 0; i < fnic->raw_wq_count; i++)
912-
vnic_wq_enable(&fnic->wq[i]);
913-
for (i = 0; i < fnic->wq_copy_count; i++)
914-
vnic_wq_copy_enable(&fnic->hw_copy_wq[i]);
915-
916958
fc_fabric_login(lp);
917959

918-
err = fnic_request_intr(fnic);
919-
if (err) {
920-
shost_printk(KERN_ERR, fnic->lport->host,
921-
"Unable to request irq.\n");
922-
goto err_out_free_exch_mgr;
923-
}
924-
925960
vnic_dev_enable(fnic->vdev);
926961

927962
for (i = 0; i < fnic->intr_count; i++)
@@ -933,12 +968,15 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
933968

934969
err_out_free_exch_mgr:
935970
fc_exch_mgr_free(lp);
936-
err_out_remove_scsi_host:
971+
err_out_fc_exch_mgr_alloc:
937972
fc_remove_host(lp->host);
938973
scsi_remove_host(lp->host);
939-
err_out_free_rq_buf:
974+
err_out_scsi_add_host:
975+
fnic_free_intr(fnic);
976+
err_out_request_intr:
940977
for (i = 0; i < fnic->rq_count; i++)
941978
vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf);
979+
err_out_rq_buf:
942980
vnic_dev_notify_unset(fnic->vdev);
943981
err_out_free_max_pool:
944982
mempool_destroy(fnic->io_sgl_pool[FNIC_SGL_CACHE_MAX]);
@@ -947,6 +985,8 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
947985
err_out_free_ioreq_pool:
948986
mempool_destroy(fnic->io_req_pool);
949987
err_out_free_resources:
988+
for (hwq = 0; hwq < fnic->wq_copy_count; hwq++)
989+
kfree(fnic->sw_copy_wq[hwq].io_req_table);
950990
fnic_free_vnic_resources(fnic);
951991
err_out_clear_intr:
952992
fnic_clear_intr_mode(fnic);
@@ -975,6 +1015,7 @@ static void fnic_remove(struct pci_dev *pdev)
9751015
struct fnic *fnic = pci_get_drvdata(pdev);
9761016
struct fc_lport *lp = fnic->lport;
9771017
unsigned long flags;
1018+
int hwq;
9781019

9791020
/*
9801021
* Mark state so that the workqueue thread stops forwarding
@@ -1035,6 +1076,8 @@ static void fnic_remove(struct pci_dev *pdev)
10351076

10361077
fc_remove_host(fnic->lport->host);
10371078
scsi_remove_host(fnic->lport->host);
1079+
for (hwq = 0; hwq < fnic->wq_copy_count; hwq++)
1080+
kfree(fnic->sw_copy_wq[hwq].io_req_table);
10381081
fc_exch_mgr_free(fnic->lport);
10391082
vnic_dev_notify_unset(fnic->vdev);
10401083
fnic_free_intr(fnic);

0 commit comments

Comments
 (0)