[PATCH v2 1/1] scsi: ufs: core: Make UFS_MCQ_NUM_DEV_CMD_QUEUES a module parameter
AngeloGioacchino Del Regno
angelogioacchino.delregno at collabora.com
Tue May 30 00:24:11 PDT 2023
Il 30/05/23 04:35, Po-Wen Kao ha scritto:
> A dedicated queue for dev commands is not mandatory, hence let
> UFS_MCQ_NUM_DEV_CMD_QUEUES become module parameter `dev_cmd_queues`
> to allow sharing first hw queue for dev commands.
>
> When `dev_cmd_queues` is set to 0, the hwq 0 will be shared for I/O
> requests and dev commands. In the same hwq, commands are processed based
> on submission order hence might take longer to dispatch dev command
> under heavy traffic. For the host with dedicated hwq for dev commands
> can benefit in such scenario.
>
> Signed-off-by: Po-Wen Kao <powen.kao at mediatek.com>
I imagine that MediaTek's UFS IP does not support dev_cmd_queues=1, does it?
In that case, this should not be a UFS module parameter, but a setting that
you provide from ufs-mediatek instead.
Regards,
Angelo
> ---
> drivers/ufs/core/ufs-mcq.c | 35 +++++++++++++++++++++++++++-------
> drivers/ufs/core/ufshcd-priv.h | 2 +-
> drivers/ufs/core/ufshcd.c | 2 +-
> 3 files changed, 30 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c
> index 51b3c6ae781d..4ef48c84e62f 100644
> --- a/drivers/ufs/core/ufs-mcq.c
> +++ b/drivers/ufs/core/ufs-mcq.c
> @@ -16,7 +16,8 @@
> #define MAX_QUEUE_SUP GENMASK(7, 0)
> #define UFS_MCQ_MIN_RW_QUEUES 2
> #define UFS_MCQ_MIN_READ_QUEUES 0
> -#define UFS_MCQ_NUM_DEV_CMD_QUEUES 1
> +#define UFS_MCQ_MAX_DEV_CMD_QUEUES 1
> +#define UFS_MCQ_MIN_DEV_CMD_QUEUES 0
> #define UFS_MCQ_MIN_POLL_QUEUES 0
> #define QUEUE_EN_OFFSET 31
> #define QUEUE_ID_OFFSET 16
> @@ -75,6 +76,23 @@ module_param_cb(poll_queues, &poll_queue_count_ops, &poll_queues, 0644);
> MODULE_PARM_DESC(poll_queues,
> "Number of poll queues used for r/w. Default value is 1");
>
> +static int dev_cmd_queue_count_set(const char *val, const struct kernel_param *kp)
> +{
> + return param_set_uint_minmax(val, kp,
> + UFS_MCQ_MIN_DEV_CMD_QUEUES,
> + UFS_MCQ_MAX_DEV_CMD_QUEUES);
> +}
> +
> +static const struct kernel_param_ops dev_cmd_queue_count_ops = {
> + .set = dev_cmd_queue_count_set,
> + .get = param_get_uint,
> +};
> +
> +unsigned int dev_cmd_queues = 1;
> +module_param_cb(dev_cmd_queues, &dev_cmd_queue_count_ops, &dev_cmd_queues, 0644);
> +MODULE_PARM_DESC(dev_cmd_queues,
> + "Number of queues used for dev command. Default value is 1");
> +
> /**
> * ufshcd_mcq_config_mac - Set the #Max Activ Cmds.
> * @hba: per adapter instance
> @@ -109,7 +127,7 @@ struct ufs_hw_queue *ufshcd_mcq_req_to_hwq(struct ufs_hba *hba,
> u32 hwq = blk_mq_unique_tag_to_hwq(utag);
>
> /* uhq[0] is used to serve device commands */
> - return &hba->uhq[hwq + UFSHCD_MCQ_IO_QUEUE_OFFSET];
> + return &hba->uhq[hwq + dev_cmd_queues];
> }
>
> /**
> @@ -153,7 +171,7 @@ static int ufshcd_mcq_config_nr_queues(struct ufs_hba *hba)
> /* maxq is 0 based value */
> hba_maxq = FIELD_GET(MAX_QUEUE_SUP, hba->mcq_capabilities) + 1;
>
> - tot_queues = UFS_MCQ_NUM_DEV_CMD_QUEUES + read_queues + poll_queues +
> + tot_queues = dev_cmd_queues + read_queues + poll_queues +
> rw_queues;
>
> if (hba_maxq < tot_queues) {
> @@ -162,7 +180,7 @@ static int ufshcd_mcq_config_nr_queues(struct ufs_hba *hba)
> return -EOPNOTSUPP;
> }
>
> - rem = hba_maxq - UFS_MCQ_NUM_DEV_CMD_QUEUES;
> + rem = hba_maxq - dev_cmd_queues;
>
> if (rw_queues) {
> hba->nr_queues[HCTX_TYPE_DEFAULT] = rw_queues;
> @@ -188,7 +206,7 @@ static int ufshcd_mcq_config_nr_queues(struct ufs_hba *hba)
> for (i = 0; i < HCTX_MAX_TYPES; i++)
> host->nr_hw_queues += hba->nr_queues[i];
>
> - hba->nr_hw_queues = host->nr_hw_queues + UFS_MCQ_NUM_DEV_CMD_QUEUES;
> + hba->nr_hw_queues = host->nr_hw_queues + dev_cmd_queues;
> return 0;
> }
>
> @@ -424,8 +442,11 @@ int ufshcd_mcq_init(struct ufs_hba *hba)
>
> /* The very first HW queue serves device commands */
> hba->dev_cmd_queue = &hba->uhq[0];
> - /* Give dev_cmd_queue the minimal number of entries */
> - hba->dev_cmd_queue->max_entries = MAX_DEV_CMD_ENTRIES;
> + if (dev_cmd_queues) {
> + /* Give dedicated dev_cmd_queue the minimal number of entries */
> + hba->dev_cmd_queue->max_entries = MAX_DEV_CMD_ENTRIES;
> + }
> +
>
> host->host_tagset = 1;
> return 0;
> diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h
> index d53b93c21a0c..b490d645f12c 100644
> --- a/drivers/ufs/core/ufshcd-priv.h
> +++ b/drivers/ufs/core/ufshcd-priv.h
> @@ -78,7 +78,6 @@ struct ufs_hw_queue *ufshcd_mcq_req_to_hwq(struct ufs_hba *hba,
> unsigned long ufshcd_mcq_poll_cqe_lock(struct ufs_hba *hba,
> struct ufs_hw_queue *hwq);
>
> -#define UFSHCD_MCQ_IO_QUEUE_OFFSET 1
> #define SD_ASCII_STD true
> #define SD_RAW false
> int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index,
> @@ -287,6 +286,7 @@ static inline int ufshcd_mcq_vops_config_esi(struct ufs_hba *hba)
> return -EOPNOTSUPP;
> }
>
> +extern unsigned int dev_cmd_queues;
> extern const struct ufs_pm_lvl_states ufs_pm_lvl_states[];
>
> /**
> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> index 4ec8dacb447c..6361e21ca1c5 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -5493,7 +5493,7 @@ static int ufshcd_poll(struct Scsi_Host *shost, unsigned int queue_num)
> struct ufs_hw_queue *hwq;
>
> if (is_mcq_enabled(hba)) {
> - hwq = &hba->uhq[queue_num + UFSHCD_MCQ_IO_QUEUE_OFFSET];
> + hwq = &hba->uhq[queue_num + dev_cmd_queues];
>
> return ufshcd_mcq_poll_cqe_lock(hba, hwq);
> }
More information about the Linux-mediatek
mailing list