Hi Bean, > > + > > +static inline int ufshpb_get_read_id(struct ufshpb_lu *hpb) > > +{ > > + if (++hpb->cur_read_id >= MAX_HPB_READ_ID) > > + hpb->cur_read_id = 0; > > + return hpb->cur_read_id; > > +} > > + > > +static int ufshpb_execute_pre_req(struct ufshpb_lu *hpb, struct > > scsi_cmnd *cmd, > > + struct ufshpb_req *pre_req, int > > read_id) > > +{ > > + struct scsi_device *sdev = cmd->device; > > + struct request_queue *q = sdev->request_queue; > > + struct request *req; > > + struct scsi_request *rq; > > + struct bio *bio = pre_req->bio; > > + > > + pre_req->hpb = hpb; > > + pre_req->wb.lpn = sectors_to_logical(cmd->device, > > + blk_rq_pos(cmd- > > >request)); > > + pre_req->wb.len = sectors_to_logical(cmd->device, > > + blk_rq_sectors(cmd- > > >request)); > > + if (ufshpb_pre_req_add_bio_page(hpb, q, pre_req)) > > + return -ENOMEM; > > + > > + req = pre_req->req; > > + > > + /* 1. request setup */ > > + blk_rq_append_bio(req, &bio); > > + req->rq_disk = NULL; > > + req->end_io_data = (void *)pre_req; > > + req->end_io = ufshpb_pre_req_compl_fn; > > + > > + /* 2. scsi_request setup */ > > + rq = scsi_req(req); > > + rq->retries = 1; > > + > > + ufshpb_set_write_buf_cmd(rq->cmd, pre_req->wb.lpn, pre_req- > > >wb.len, > > + read_id); > > + rq->cmd_len = scsi_command_size(rq->cmd); > > + > > + if (blk_insert_cloned_request(q, req) != BLK_STS_OK) > > + return -EAGAIN; > > + > > + hpb->stats.pre_req_cnt++; > > + > > + return 0; > > +} > > + > > +static int ufshpb_issue_pre_req(struct ufshpb_lu *hpb, struct > > scsi_cmnd *cmd, > > + int *read_id) > > +{ > > + struct ufshpb_req *pre_req; > > + struct request *req = NULL; > > + struct bio *bio = NULL; > > + unsigned long flags; > > + int _read_id; > > + int ret = 0; > > + > > + req = blk_get_request(cmd->device->request_queue, > > + REQ_OP_SCSI_OUT | REQ_SYNC, > > BLK_MQ_REQ_NOWAIT); > > + if (IS_ERR(req)) > > + return -EAGAIN; > > + > > + bio = bio_alloc(GFP_ATOMIC, 1); > > + if (!bio) { > > + blk_put_request(req); > > + return -EAGAIN; > > + } > > + > > + spin_lock_irqsave(&hpb->rgn_state_lock, flags); > > + pre_req = ufshpb_get_pre_req(hpb); > > + if (!pre_req) { > > + ret = -EAGAIN; > > + goto unlock_out; > > + } > > + _read_id = ufshpb_get_read_id(hpb); > > + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); > > + > > + pre_req->req = req; > > + pre_req->bio = bio; > > + > > + ret = ufshpb_execute_pre_req(hpb, cmd, pre_req, _read_id); > > + if (ret) > > + goto free_pre_req; > > + > > + *read_id = _read_id; > > + > > + return ret; > > +free_pre_req: > > + spin_lock_irqsave(&hpb->rgn_state_lock, flags); > > + ufshpb_put_pre_req(hpb, pre_req); > > +unlock_out: > > + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); > > + bio_put(bio); > > + blk_put_request(req); > > + return ret; > > +} > > + > > /* > > * This function will set up HPB read command using host-side L2P > > map data. > > - * In HPB v1.0, maximum size of HPB read command is 4KB. > > */ > > -void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) > > +int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) > > { > > struct ufshpb_lu *hpb; > > struct ufshpb_region *rgn; > > @@ -291,26 +560,27 @@ void ufshpb_prep(struct ufs_hba *hba, struct > > ufshcd_lrb *lrbp) > > u64 ppn; > > unsigned long flags; > > int transfer_len, rgn_idx, srgn_idx, srgn_offset; > > + int read_id = 0; > > int err = 0; > > > > hpb = ufshpb_get_hpb_data(cmd->device); > > if (!hpb) > > - return; > > + return -ENODEV; > > > > if (ufshpb_get_state(hpb) != HPB_PRESENT) { > > dev_notice(&hpb->sdev_ufs_lu->sdev_dev, > > "%s: ufshpb state is not PRESENT", > > __func__); > > - return; > > + return -ENODEV; > > } > > > > if (!ufshpb_is_write_or_discard_cmd(cmd) && > > !ufshpb_is_read_cmd(cmd)) > > - return; > > + return 0; > > > > transfer_len = sectors_to_logical(cmd->device, > > blk_rq_sectors(cmd- > > >request)); > > if (unlikely(!transfer_len)) > > - return; > > + return 0; > > > > lpn = sectors_to_logical(cmd->device, blk_rq_pos(cmd- > > >request)); > > ufshpb_get_pos_from_lpn(hpb, lpn, &rgn_idx, &srgn_idx, > > &srgn_offset); > > @@ -323,18 +593,19 @@ void ufshpb_prep(struct ufs_hba *hba, struct > > ufshcd_lrb *lrbp) > > ufshpb_set_ppn_dirty(hpb, rgn_idx, srgn_idx, > > srgn_offset, > > transfer_len); > > spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); > > - return; > > + return 0; > > } > > > > - if (!ufshpb_is_support_chunk(transfer_len)) > > - return; > > + if (!ufshpb_is_support_chunk(hpb, transfer_len) && > > + (ufshpb_is_legacy(hba) && (transfer_len != > > HPB_LEGACY_CHUNK_HIGH))) > > + return 0; > > > > spin_lock_irqsave(&hpb->rgn_state_lock, flags); > > if (ufshpb_test_ppn_dirty(hpb, rgn_idx, srgn_idx, > > srgn_offset, > > transfer_len)) { > > hpb->stats.miss_cnt++; > > spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); > > - return; > > + return 0; > > } > > > > err = ufshpb_fill_ppn_from_page(hpb, srgn->mctx, srgn_offset, > > 1, &ppn); > > @@ -347,28 +618,46 @@ void ufshpb_prep(struct ufs_hba *hba, struct > > ufshcd_lrb *lrbp) > > * active state. > > */ > > dev_err(hba->dev, "get ppn failed. err %d\n", err); > > - return; > > + return err; > > + } > > + > > + if (!ufshpb_is_legacy(hba) && > > + ufshpb_is_required_wb(hpb, transfer_len)) { > > + err = ufshpb_issue_pre_req(hpb, cmd, &read_id); > > + if (err) { > > + unsigned long timeout; > > + > > + timeout = cmd->jiffies_at_alloc + > > msecs_to_jiffies( > > + hpb->params.requeue_timeout_ms); > > + > > + if (time_before(jiffies, timeout)) > > + return -EAGAIN; > > + > > + hpb->stats.miss_cnt++; > > + return 0; > > + } > > } > > > > - ufshpb_set_hpb_read_to_upiu(hpb, lrbp, lpn, ppn, > > transfer_len); > > + ufshpb_set_hpb_read_to_upiu(hpb, lrbp, lpn, ppn, > > transfer_len, read_id); > > > > hpb->stats.hit_cnt++; > > + return 0; > > } > > > > BUG!!! > > > Please read HPB 2.0 Spec carefully, and check how to correctly use HPB > READ ID. you are assigning 0 for HPB write buffer. how can you expect > the HPB READ be paired??? > I fixed as follows, static inline int ufshpb_get_read_id(struct ufshpb_lu *hpb) { if (hpb->cur_read_id >= MAX_HPB_READ_ID) hpb->cur_read_id = 0; return ++hpb->cur_read_id; } Thanks for comments, I will check carefully. Thanks, Daejun