@@ -552,6 +552,11 @@ static int prot_mask;
552552module_param (prot_mask , int , 0444 );
553553MODULE_PARM_DESC (prot_mask , " host protection capabilities mask, def=0x0 " );
554554
555+ /* the index of iopoll queues are bigger than interrupt queues' */
556+ static int experimental_iopoll_q_cnt ;
557+ module_param (experimental_iopoll_q_cnt , int , 0444 );
558+ MODULE_PARM_DESC (experimental_iopoll_q_cnt , "number of queues to be used as poll mode, def=0" );
559+
555560static void debugfs_work_handler_v3_hw (struct work_struct * work );
556561static void debugfs_snapshot_regs_v3_hw (struct hisi_hba * hisi_hba );
557562
@@ -2391,18 +2396,20 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
23912396 task -> task_done (task );
23922397}
23932398
2394- static void complete_v3_hw (struct hisi_sas_cq * cq )
2399+ static int complete_v3_hw (struct hisi_sas_cq * cq )
23952400{
23962401 struct hisi_sas_complete_v3_hdr * complete_queue ;
23972402 struct hisi_hba * hisi_hba = cq -> hisi_hba ;
23982403 u32 rd_point , wr_point ;
23992404 int queue = cq -> id ;
2405+ int completed ;
24002406
24012407 rd_point = cq -> rd_point ;
24022408 complete_queue = hisi_hba -> complete_hdr [queue ];
24032409
24042410 wr_point = hisi_sas_read32 (hisi_hba , COMPL_Q_0_WR_PTR +
24052411 (0x14 * queue ));
2412+ completed = (wr_point + HISI_SAS_QUEUE_SLOTS - rd_point ) % HISI_SAS_QUEUE_SLOTS ;
24062413
24072414 while (rd_point != wr_point ) {
24082415 struct hisi_sas_complete_v3_hdr * complete_hdr ;
@@ -2450,6 +2457,21 @@ static void complete_v3_hw(struct hisi_sas_cq *cq)
24502457 /* update rd_point */
24512458 cq -> rd_point = rd_point ;
24522459 hisi_sas_write32 (hisi_hba , COMPL_Q_0_RD_PTR + (0x14 * queue ), rd_point );
2460+
2461+ return completed ;
2462+ }
2463+
2464+ static int queue_complete_v3_hw (struct Scsi_Host * shost , unsigned int queue )
2465+ {
2466+ struct hisi_hba * hisi_hba = shost_priv (shost );
2467+ struct hisi_sas_cq * cq = & hisi_hba -> cq [queue ];
2468+ int completed ;
2469+
2470+ spin_lock (& cq -> poll_lock );
2471+ completed = complete_v3_hw (cq );
2472+ spin_unlock (& cq -> poll_lock );
2473+
2474+ return completed ;
24532475}
24542476
24552477static irqreturn_t cq_thread_v3_hw (int irq_no , void * p )
@@ -2481,8 +2503,9 @@ static void hisi_sas_v3_free_vectors(void *data)
24812503
24822504static int interrupt_preinit_v3_hw (struct hisi_hba * hisi_hba )
24832505{
2484- int vectors ;
2485- int max_msi = HISI_SAS_MSI_COUNT_V3_HW , min_msi ;
2506+ /* Allocate all MSI vectors to avoid re-insertion issue */
2507+ int max_msi = HISI_SAS_MSI_COUNT_V3_HW ;
2508+ int vectors , min_msi ;
24862509 struct Scsi_Host * shost = hisi_hba -> shost ;
24872510 struct pci_dev * pdev = hisi_hba -> pci_dev ;
24882511 struct irq_affinity desc = {
@@ -2499,8 +2522,8 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba)
24992522 return - ENOENT ;
25002523
25012524
2502- hisi_hba -> cq_nvecs = vectors - BASE_VECTORS_V3_HW ;
2503- shost -> nr_hw_queues = hisi_hba -> cq_nvecs ;
2525+ hisi_hba -> cq_nvecs = vectors - BASE_VECTORS_V3_HW - hisi_hba -> iopoll_q_cnt ;
2526+ shost -> nr_hw_queues = hisi_hba -> cq_nvecs + hisi_hba -> iopoll_q_cnt ;
25042527
25052528 devm_add_action (& pdev -> dev , hisi_sas_v3_free_vectors , pdev );
25062529 return 0 ;
@@ -3218,9 +3241,31 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable)
32183241static void hisi_sas_map_queues (struct Scsi_Host * shost )
32193242{
32203243 struct hisi_hba * hisi_hba = shost_priv (shost );
3221- struct blk_mq_queue_map * qmap = & shost -> tag_set .map [HCTX_TYPE_DEFAULT ];
3244+ struct blk_mq_queue_map * qmap ;
3245+ int i , qoff ;
3246+
3247+ for (i = 0 , qoff = 0 ; i < shost -> nr_maps ; i ++ ) {
3248+ qmap = & shost -> tag_set .map [i ];
3249+ if (i == HCTX_TYPE_DEFAULT ) {
3250+ qmap -> nr_queues = hisi_hba -> cq_nvecs ;
3251+ } else if (i == HCTX_TYPE_POLL ) {
3252+ qmap -> nr_queues = hisi_hba -> iopoll_q_cnt ;
3253+ } else {
3254+ qmap -> nr_queues = 0 ;
3255+ continue ;
3256+ }
32223257
3223- blk_mq_pci_map_queues (qmap , hisi_hba -> pci_dev , BASE_VECTORS_V3_HW );
3258+ /* At least one interrupt hardware queue */
3259+ if (!qmap -> nr_queues )
3260+ WARN_ON (i == HCTX_TYPE_DEFAULT );
3261+ qmap -> queue_offset = qoff ;
3262+ if (i == HCTX_TYPE_POLL )
3263+ blk_mq_map_queues (qmap );
3264+ else
3265+ blk_mq_pci_map_queues (qmap , hisi_hba -> pci_dev ,
3266+ BASE_VECTORS_V3_HW );
3267+ qoff += qmap -> nr_queues ;
3268+ }
32243269}
32253270
32263271static struct scsi_host_template sht_v3_hw = {
@@ -3252,6 +3297,7 @@ static struct scsi_host_template sht_v3_hw = {
32523297 .tag_alloc_policy = BLK_TAG_ALLOC_RR ,
32533298 .host_reset = hisi_sas_host_reset ,
32543299 .host_tagset = 1 ,
3300+ .mq_poll = queue_complete_v3_hw ,
32553301};
32563302
32573303static const struct hisi_sas_hw hisi_sas_v3_hw = {
@@ -3311,6 +3357,13 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
33113357 if (hisi_sas_get_fw_info (hisi_hba ) < 0 )
33123358 goto err_out ;
33133359
3360+ if (experimental_iopoll_q_cnt < 0 ||
3361+ experimental_iopoll_q_cnt >= hisi_hba -> queue_count )
3362+ dev_err (dev , "iopoll queue count %d cannot exceed or equal 16, using default 0\n" ,
3363+ experimental_iopoll_q_cnt );
3364+ else
3365+ hisi_hba -> iopoll_q_cnt = experimental_iopoll_q_cnt ;
3366+
33143367 if (hisi_sas_alloc (hisi_hba )) {
33153368 hisi_sas_free (hisi_hba );
33163369 goto err_out ;
@@ -4866,6 +4919,10 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
48664919 shost -> max_cmd_len = 16 ;
48674920 shost -> can_queue = HISI_SAS_UNRESERVED_IPTT ;
48684921 shost -> cmd_per_lun = HISI_SAS_UNRESERVED_IPTT ;
4922+ if (hisi_hba -> iopoll_q_cnt )
4923+ shost -> nr_maps = 3 ;
4924+ else
4925+ shost -> nr_maps = 1 ;
48694926
48704927 sha -> sas_ha_name = DRV_NAME ;
48714928 sha -> dev = dev ;
0 commit comments