@@ -357,6 +357,43 @@ static int wait_resp(struct afu *afu, struct afu_cmd *cmd)
357
357
return rc ;
358
358
}
359
359
360
+ /**
361
+ * cmd_to_target_hwq() - selects a target hardware queue for a SCSI command
362
+ * @host: SCSI host associated with device.
363
+ * @scp: SCSI command to send.
364
+ * @afu: SCSI command to send.
365
+ *
366
+ * Hashes a command based upon the hardware queue mode.
367
+ *
368
+ * Return: Trusted index of target hardware queue
369
+ */
370
+ static u32 cmd_to_target_hwq (struct Scsi_Host * host , struct scsi_cmnd * scp ,
371
+ struct afu * afu )
372
+ {
373
+ u32 tag ;
374
+ u32 hwq = 0 ;
375
+
376
+ if (afu -> num_hwqs == 1 )
377
+ return 0 ;
378
+
379
+ switch (afu -> hwq_mode ) {
380
+ case HWQ_MODE_RR :
381
+ hwq = afu -> hwq_rr_count ++ % afu -> num_hwqs ;
382
+ break ;
383
+ case HWQ_MODE_TAG :
384
+ tag = blk_mq_unique_tag (scp -> request );
385
+ hwq = blk_mq_unique_tag_to_hwq (tag );
386
+ break ;
387
+ case HWQ_MODE_CPU :
388
+ hwq = smp_processor_id () % afu -> num_hwqs ;
389
+ break ;
390
+ default :
391
+ WARN_ON_ONCE (1 );
392
+ }
393
+
394
+ return hwq ;
395
+ }
396
+
360
397
/**
361
398
* send_tmf() - sends a Task Management Function (TMF)
362
399
* @afu: AFU to checkout from.
@@ -368,10 +405,12 @@ static int wait_resp(struct afu *afu, struct afu_cmd *cmd)
368
405
*/
369
406
static int send_tmf (struct afu * afu , struct scsi_cmnd * scp , u64 tmfcmd )
370
407
{
371
- struct cxlflash_cfg * cfg = shost_priv (scp -> device -> host );
408
+ struct Scsi_Host * host = scp -> device -> host ;
409
+ struct cxlflash_cfg * cfg = shost_priv (host );
372
410
struct afu_cmd * cmd = sc_to_afucz (scp );
373
411
struct device * dev = & cfg -> dev -> dev ;
374
- struct hwq * hwq = get_hwq (afu , PRIMARY_HWQ );
412
+ int hwq_index = cmd_to_target_hwq (host , scp , afu );
413
+ struct hwq * hwq = get_hwq (afu , hwq_index );
375
414
ulong lock_flags ;
376
415
int rc = 0 ;
377
416
ulong to ;
@@ -388,7 +427,7 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
388
427
cmd -> scp = scp ;
389
428
cmd -> parent = afu ;
390
429
cmd -> cmd_tmf = true;
391
- cmd -> hwq_index = hwq -> index ;
430
+ cmd -> hwq_index = hwq_index ;
392
431
393
432
cmd -> rcb .ctx_id = hwq -> ctx_hndl ;
394
433
cmd -> rcb .msi = SISL_MSI_RRQ_UPDATED ;
@@ -448,7 +487,8 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
448
487
struct device * dev = & cfg -> dev -> dev ;
449
488
struct afu_cmd * cmd = sc_to_afucz (scp );
450
489
struct scatterlist * sg = scsi_sglist (scp );
451
- struct hwq * hwq = get_hwq (afu , PRIMARY_HWQ );
490
+ int hwq_index = cmd_to_target_hwq (host , scp , afu );
491
+ struct hwq * hwq = get_hwq (afu , hwq_index );
452
492
u16 req_flags = SISL_REQ_FLAGS_SUP_UNDERRUN ;
453
493
ulong lock_flags ;
454
494
int rc = 0 ;
@@ -498,7 +538,7 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
498
538
499
539
cmd -> scp = scp ;
500
540
cmd -> parent = afu ;
501
- cmd -> hwq_index = hwq -> index ;
541
+ cmd -> hwq_index = hwq_index ;
502
542
503
543
cmd -> rcb .ctx_id = hwq -> ctx_hndl ;
504
544
cmd -> rcb .msi = SISL_MSI_RRQ_UPDATED ;
@@ -2654,6 +2694,74 @@ static ssize_t num_hwqs_store(struct device *dev,
2654
2694
return count ;
2655
2695
}
2656
2696
2697
+ static const char * hwq_mode_name [MAX_HWQ_MODE ] = { "rr" , "tag" , "cpu" };
2698
+
2699
+ /**
2700
+ * hwq_mode_show() - presents the HWQ steering mode for the host
2701
+ * @dev: Generic device associated with the host.
2702
+ * @attr: Device attribute representing the HWQ steering mode.
2703
+ * @buf: Buffer of length PAGE_SIZE to report back the HWQ steering mode
2704
+ * as a character string.
2705
+ *
2706
+ * Return: The size of the ASCII string returned in @buf.
2707
+ */
2708
+ static ssize_t hwq_mode_show (struct device * dev ,
2709
+ struct device_attribute * attr , char * buf )
2710
+ {
2711
+ struct cxlflash_cfg * cfg = shost_priv (class_to_shost (dev ));
2712
+ struct afu * afu = cfg -> afu ;
2713
+
2714
+ return scnprintf (buf , PAGE_SIZE , "%s\n" , hwq_mode_name [afu -> hwq_mode ]);
2715
+ }
2716
+
2717
+ /**
2718
+ * hwq_mode_store() - sets the HWQ steering mode for the host
2719
+ * @dev: Generic device associated with the host.
2720
+ * @attr: Device attribute representing the HWQ steering mode.
2721
+ * @buf: Buffer of length PAGE_SIZE containing the HWQ steering mode
2722
+ * as a character string.
2723
+ * @count: Length of data resizing in @buf.
2724
+ *
2725
+ * rr = Round-Robin
2726
+ * tag = Block MQ Tagging
2727
+ * cpu = CPU Affinity
2728
+ *
2729
+ * Return: The size of the ASCII string returned in @buf.
2730
+ */
2731
+ static ssize_t hwq_mode_store (struct device * dev ,
2732
+ struct device_attribute * attr ,
2733
+ const char * buf , size_t count )
2734
+ {
2735
+ struct Scsi_Host * shost = class_to_shost (dev );
2736
+ struct cxlflash_cfg * cfg = shost_priv (shost );
2737
+ struct device * cfgdev = & cfg -> dev -> dev ;
2738
+ struct afu * afu = cfg -> afu ;
2739
+ int i ;
2740
+ u32 mode = MAX_HWQ_MODE ;
2741
+
2742
+ for (i = 0 ; i < MAX_HWQ_MODE ; i ++ ) {
2743
+ if (!strncmp (hwq_mode_name [i ], buf , strlen (hwq_mode_name [i ]))) {
2744
+ mode = i ;
2745
+ break ;
2746
+ }
2747
+ }
2748
+
2749
+ if (mode >= MAX_HWQ_MODE ) {
2750
+ dev_info (cfgdev , "Invalid HWQ steering mode.\n" );
2751
+ return - EINVAL ;
2752
+ }
2753
+
2754
+ if ((mode == HWQ_MODE_TAG ) && !shost_use_blk_mq (shost )) {
2755
+ dev_info (cfgdev , "SCSI-MQ is not enabled, use a different "
2756
+ "HWQ steering mode.\n" );
2757
+ return - EINVAL ;
2758
+ }
2759
+
2760
+ afu -> hwq_mode = mode ;
2761
+
2762
+ return count ;
2763
+ }
2764
+
2657
2765
/**
2658
2766
* mode_show() - presents the current mode of the device
2659
2767
* @dev: Generic device associated with the device.
@@ -2686,6 +2794,7 @@ static DEVICE_ATTR_RO(port2_lun_table);
2686
2794
static DEVICE_ATTR_RO (port3_lun_table );
2687
2795
static DEVICE_ATTR_RW (irqpoll_weight );
2688
2796
static DEVICE_ATTR_RW (num_hwqs );
2797
+ static DEVICE_ATTR_RW (hwq_mode );
2689
2798
2690
2799
static struct device_attribute * cxlflash_host_attrs [] = {
2691
2800
& dev_attr_port0 ,
@@ -2700,6 +2809,7 @@ static struct device_attribute *cxlflash_host_attrs[] = {
2700
2809
& dev_attr_port3_lun_table ,
2701
2810
& dev_attr_irqpoll_weight ,
2702
2811
& dev_attr_num_hwqs ,
2812
+ & dev_attr_hwq_mode ,
2703
2813
NULL
2704
2814
};
2705
2815
0 commit comments