Message ID | 20210226083300.30934-1-avri.altman@wdc.com (mailing list archive) |
---|---|
Headers | show |
Series | Add Host control mode to HPB | expand |
> > Hi Avri, > > > +static void ufshpb_read_to_handler(struct work_struct *work) > > +{ > > + struct delayed_work *dwork = to_delayed_work(work); > > + struct ufshpb_lu *hpb; > > + struct victim_select_info *lru_info; > > + struct ufshpb_region *rgn; > > + unsigned long flags; > > + LIST_HEAD(expired_list); > > + > > + hpb = container_of(dwork, struct ufshpb_lu, ufshpb_read_to_work); > > + > > + if (test_and_set_bit(TIMEOUT_WORK_PENDING, &hpb- > >work_data_bits)) > > + return; > > + > > + spin_lock_irqsave(&hpb->rgn_state_lock, flags); > > + > > + lru_info = &hpb->lru_info; > > + > > + list_for_each_entry(rgn, &lru_info->lh_lru_rgn, list_lru_rgn) { > > + bool timedout = ktime_after(ktime_get(), rgn->read_timeout); > > + > > + if (timedout) { > > It is important not just to check the timeout, but how much time has passed. > If the time exceeded is twice the threshold, the read_timeout_expiries > value should be reduced by 2 instead of 1. Theoretically this shouldn't happened. Please note that POLLING_INTERVAL_MS << READ_TO_MS. Better add appropriate check when making those configurable. Thanks, Avri > > > + rgn->read_timeout_expiries--; > > Thanks, > Daejun
> Hi Avri, > > > diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c > > index cf704b82e72a..f33aa28e0a0a 100644 > > --- a/drivers/scsi/ufs/ufshpb.c > > +++ b/drivers/scsi/ufs/ufshpb.c > > @@ -642,7 +642,8 @@ int ufshpb_prep(struct ufs_hba *hba, struct > ufshcd_lrb *lrbp) > > if (rgn->reads == ACTIVATION_THRESHOLD) > > activate = true; > > spin_unlock_irqrestore(&rgn->rgn_lock, flags); > > - if (activate) { > > + if (activate || > > + test_and_clear_bit(RGN_FLAG_UPDATE, &rgn->rgn_flags)) { > > How about merge rgn->rgn_flags to rgn_state? Done. Thanks, Avri > > Thanks, > Daejun
Hi Avri, > > > > Hi Avri, > > > > > +static void ufshpb_read_to_handler(struct work_struct *work) > > > +{ > > > + struct delayed_work *dwork = to_delayed_work(work); > > > + struct ufshpb_lu *hpb; > > > + struct victim_select_info *lru_info; > > > + struct ufshpb_region *rgn; > > > + unsigned long flags; > > > + LIST_HEAD(expired_list); > > > + > > > + hpb = container_of(dwork, struct ufshpb_lu, ufshpb_read_to_work); > > > + > > > + if (test_and_set_bit(TIMEOUT_WORK_PENDING, &hpb- > > >work_data_bits)) > > > + return; > > > + > > > + spin_lock_irqsave(&hpb->rgn_state_lock, flags); > > > + > > > + lru_info = &hpb->lru_info; > > > + > > > + list_for_each_entry(rgn, &lru_info->lh_lru_rgn, list_lru_rgn) { > > > + bool timedout = ktime_after(ktime_get(), rgn->read_timeout); > > > + > > > + if (timedout) { > > > > It is important not just to check the timeout, but how much time has passed. > > If the time exceeded is twice the threshold, the read_timeout_expiries > > value should be reduced by 2 instead of 1. > Theoretically this shouldn't happened. > Please note that POLLING_INTERVAL_MS << READ_TO_MS. > Better add appropriate check when making those configurable. OK, I agree. Thanks, Daejun > > Thanks, > Avri > > > > > + rgn->read_timeout_expiries--; > > > > Thanks, > > Daejun > > > >