Skip to content

Commit 22089c2

Browse files
bvanasschemartinkpetersen
authored andcommitted
scsi: ufs: core: Optimize the hot path
Set .cmd_size in the SCSI host template such that the SCSI core makes struct scsi_cmnd and struct ufshcd_lrb adjacent. Convert the cmd->lrbp and lrbp->cmd memory loads into pointer offset calculations. Remove the data structure members that became superfluous, namely ufshcd_lrb.cmd and ufs_hba.lrb. Since ufshcd_lrb.cmd is removed, this pointer cannot be used anymore to test whether or not a command is a SCSI command. Introduce a new function for this purpose, namely ufshcd_is_scsi_cmd(). Signed-off-by: Bart Van Assche <bvanassche@acm.org> Link: https://patch.msgid.link/20251031204029.2883185-24-bvanassche@acm.org Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent e5f9cc2 commit 22089c2

5 files changed

Lines changed: 179 additions & 129 deletions

File tree

drivers/ufs/core/ufs-mcq.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,8 @@ static int ufshcd_mcq_sq_start(struct ufs_hba *hba, struct ufs_hw_queue *hwq)
534534
*/
535535
int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag)
536536
{
537-
struct ufshcd_lrb *lrbp = &hba->lrb[task_tag];
538-
struct scsi_cmnd *cmd = lrbp->cmd;
537+
struct scsi_cmnd *cmd = ufshcd_tag_to_cmd(hba, task_tag);
538+
struct ufshcd_lrb *lrbp = scsi_cmd_priv(cmd);
539539
struct ufs_hw_queue *hwq;
540540
void __iomem *reg, *opr_sqd_base;
541541
u32 nexus, id, val;
@@ -618,7 +618,8 @@ static void ufshcd_mcq_nullify_sqe(struct utp_transfer_req_desc *utrd)
618618
static bool ufshcd_mcq_sqe_search(struct ufs_hba *hba,
619619
struct ufs_hw_queue *hwq, int task_tag)
620620
{
621-
struct ufshcd_lrb *lrbp = &hba->lrb[task_tag];
621+
struct scsi_cmnd *cmd = ufshcd_tag_to_cmd(hba, task_tag);
622+
struct ufshcd_lrb *lrbp = scsi_cmd_priv(cmd);
622623
struct utp_transfer_req_desc *utrd;
623624
__le64 cmd_desc_base_addr;
624625
bool ret = false;
@@ -669,7 +670,7 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
669670
struct Scsi_Host *host = cmd->device->host;
670671
struct ufs_hba *hba = shost_priv(host);
671672
int tag = scsi_cmd_to_rq(cmd)->tag;
672-
struct ufshcd_lrb *lrbp = &hba->lrb[tag];
673+
struct ufshcd_lrb *lrbp = scsi_cmd_priv(cmd);
673674
struct ufs_hw_queue *hwq;
674675
int err;
675676

drivers/ufs/core/ufshcd-crypto.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp,
3838
}
3939

4040
static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba,
41-
struct ufshcd_lrb *lrbp)
41+
struct scsi_cmnd *cmd)
4242
{
43-
struct scsi_cmnd *cmd = lrbp->cmd;
4443
const struct bio_crypt_ctx *crypt_ctx = scsi_cmd_to_rq(cmd)->crypt_ctx;
44+
struct ufshcd_lrb *lrbp = scsi_cmd_priv(cmd);
4545

4646
if (crypt_ctx && hba->vops && hba->vops->fill_crypto_prdt)
4747
return hba->vops->fill_crypto_prdt(hba, crypt_ctx,
@@ -51,17 +51,19 @@ static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba,
5151
}
5252

5353
static inline void ufshcd_crypto_clear_prdt(struct ufs_hba *hba,
54-
struct ufshcd_lrb *lrbp)
54+
struct scsi_cmnd *cmd)
5555
{
56+
struct ufshcd_lrb *lrbp = scsi_cmd_priv(cmd);
57+
5658
if (!(hba->quirks & UFSHCD_QUIRK_KEYS_IN_PRDT))
5759
return;
5860

59-
if (!(scsi_cmd_to_rq(lrbp->cmd)->crypt_ctx))
61+
if (!(scsi_cmd_to_rq(cmd)->crypt_ctx))
6062
return;
6163

6264
/* Zeroize the PRDT because it can contain cryptographic keys. */
6365
memzero_explicit(lrbp->ucd_prdt_ptr,
64-
ufshcd_sg_entry_size(hba) * scsi_sg_count(lrbp->cmd));
66+
ufshcd_sg_entry_size(hba) * scsi_sg_count(cmd));
6567
}
6668

6769
bool ufshcd_crypto_enable(struct ufs_hba *hba);
@@ -82,13 +84,15 @@ ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp,
8284
struct request_desc_header *h) { }
8385

8486
static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba,
85-
struct ufshcd_lrb *lrbp)
87+
struct scsi_cmnd *cmd)
8688
{
8789
return 0;
8890
}
8991

9092
static inline void ufshcd_crypto_clear_prdt(struct ufs_hba *hba,
91-
struct ufshcd_lrb *lrbp) { }
93+
struct scsi_cmnd *cmd)
94+
{
95+
}
9296

9397
static inline bool ufshcd_crypto_enable(struct ufs_hba *hba)
9498
{

drivers/ufs/core/ufshcd-priv.h

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ bool ufshcd_cmd_inflight(struct scsi_cmnd *cmd);
7777
int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag);
7878
int ufshcd_mcq_abort(struct scsi_cmnd *cmd);
7979
int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag);
80-
void ufshcd_release_scsi_cmd(struct ufs_hba *hba,
81-
struct ufshcd_lrb *lrbp);
80+
void ufshcd_release_scsi_cmd(struct ufs_hba *hba, struct scsi_cmnd *cmd);
8281

8382
#define SD_ASCII_STD true
8483
#define SD_RAW false
@@ -363,6 +362,44 @@ static inline bool ufs_is_valid_unit_desc_lun(struct ufs_dev_info *dev_info, u8
363362
return lun == UFS_UPIU_RPMB_WLUN || (lun < dev_info->max_lu_supported);
364363
}
365364

365+
/*
366+
* Convert a block layer tag into a SCSI command pointer. This function is
367+
* called once per I/O completion path and is also called from error paths.
368+
*/
369+
static inline struct scsi_cmnd *ufshcd_tag_to_cmd(struct ufs_hba *hba, u32 tag)
370+
{
371+
struct blk_mq_tags *tags = hba->host->tag_set.shared_tags;
372+
struct request *rq;
373+
374+
/*
375+
* Handle reserved tags differently because the UFS driver does not
376+
* call blk_mq_alloc_request() for allocating reserved requests.
377+
* Allocating reserved tags with blk_mq_alloc_request() would require
378+
* the following:
379+
* - Allocate an additional request queue from &hba->host->tag_set for
380+
* allocating reserved requests from.
381+
* - For that request queue, allocate a SCSI device.
382+
* - Calling blk_mq_alloc_request(hba->dev_mgmt_queue, REQ_OP_DRV_OUT,
383+
* BLK_MQ_REQ_RESERVED) for allocating a reserved request and
384+
* blk_mq_free_request() for freeing reserved requests.
385+
* - Set the .device pointer for these reserved requests.
386+
* - Submit reserved requests with blk_execute_rq().
387+
* - Modify ufshcd_queuecommand() such that it handles reserved requests
388+
* in another way than SCSI requests.
389+
* - Modify ufshcd_compl_one_cqe() such that it calls scsi_done() for
390+
* device management commands.
391+
* - Modify all callback functions called by blk_mq_tagset_busy_iter()
392+
* calls in the UFS driver and skip device management commands.
393+
*/
394+
rq = tag < UFSHCD_NUM_RESERVED ? tags->static_rqs[tag] :
395+
blk_mq_tag_to_rq(tags, tag);
396+
397+
if (WARN_ON_ONCE(!rq))
398+
return NULL;
399+
400+
return blk_mq_rq_to_pdu(rq);
401+
}
402+
366403
static inline void ufshcd_inc_sq_tail(struct ufs_hw_queue *q)
367404
__must_hold(&q->sq_lock)
368405
{

0 commit comments

Comments
 (0)