From: Niklas Cassel <Niklas.Cassel@wdc.com>
To: Christoph Hellwig <hch@lst.de>
Cc: Keith Busch <kbusch@kernel.org>,
"sagi@grimberg.me" <sagi@grimberg.me>,
"linux-nvme@lists.infradead.org" <linux-nvme@lists.infradead.org>
Subject: Re: [PATCH] nvme: add support for TP4084 - Time-to-Ready Enhancements
Date: Fri, 20 May 2022 11:51:49 +0000 [thread overview]
Message-ID: <YoeA1Lh9oxwyao2S@x1-carbon> (raw)
In-Reply-To: <20220518150044.GA1359@lst.de>
On Wed, May 18, 2022 at 05:00:44PM +0200, Christoph Hellwig wrote:
> On Wed, May 18, 2022 at 08:36:47AM -0600, Keith Busch wrote:
> > On Wed, May 18, 2022 at 08:40:40AM +0200, Christoph Hellwig wrote:
> > > +static int nvme_identify_ns_cs_indep(struct nvme_ctrl *ctrl, unsigned nsid,
> > > + struct nvme_id_ns_cs_indep **id)
> > > +{
> > > + struct nvme_command c = {
> > > + .identify.opcode = nvme_admin_identify,
> > > + .identify.nsid = cpu_to_le32(nsid),
> > > + .identify.cns = NVME_ID_CNS_NS_CS_INDEP,
> > > + };
> > > + int error;
> >
> > Every other place in this driver calls this value 'ret'.
>
> Except for nvme_identify_ns, where I copied it from :)
>
> But I can change it to ret.
>
> >
> > > -static int nvme_wait_ready(struct nvme_ctrl *ctrl, u64 cap, bool enabled)
> > > +static int nvme_wait_ready(struct nvme_ctrl *ctrl, bool enabled)
> > > {
> > > - unsigned long timeout =
> > > - ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;
> > > + unsigned long timeout = ((ctrl->enable_timeout + 1) * HZ / 2) + jiffies;
> >
> > I think we need to continue using the NVME_CAP_TIMEOUT() value when 'enabled'
> > is false. The enable_timeout is only applicable for the 0->1 transition and may
> > be too short if CRIME is set or too long when it's not.
From the CC.CRIME description:
Changing the value of this field may cause a change in the time reported in the
CAP.TO field. Refer to the definition of CAP.TO for more details.
The definition for CAP.TO:
If the Controller Ready Independent of Media Enable (CC.CRIME) bit is set to ‘1’
and the worst-case time for CSTS.RDY to change state is due to enabling the
controller after CC.EN transitions from ‘0’ to ‘1’, then this field shall be set
to:
a) the value in Controller Ready Independent of Media Timeout (CRTO.CRIMT); or
b) FFh if CRTO.CRIMT is greater than FFh.
This phrasing is quite confusing IMO.
I interpret this as:
If CC.CRIME is set, and CC.EN changes value from 0 to 1,
then the the controller shall write the value of CRTO.CRIMT to CAP.TO.
(If we want to make use of CAP.TO, then we would need to read the value
after setting CC.EN.)
When does the controller change CAP.TO to contain the "disable" timeout?
After CSTS.RDY has transitioned to 1...?
Since CAP.TO register contains either the enable or disable timeout,
it is quite important to know at what point in time it will contain
one or the other, so we can know if we should read CAP.TO before or
after setting a new CC.EN value.
In nvme_enable_ctrl(), we read CAP register first, then set the bits.
Since this patch never uses CAP.TO when CRIMS is supported, it should
not matter that we read the register before setting CC.EN.
nvme_disable_ctrl() doesn't re-read the register after setting CC.EN = 0.
It relies on the cached register value that was read by nvme_enable_ctrl().
Since nvme_enable_ctrl() reads the value before setting CC.CRIME
(and because the reset value of CC.CRIME is 0), the cached value should
always be the long timeout.
So nvme_enable_ctrl() and nvme_disable_ctrl() should both use the correct
timeout value with this patch, even though it seems a bit fragile.
If we ever read and update ctrl->caps, depending on the state of the
controller, NVME_CAP_TIMEOUT(ctrl->cap) can potentially contain the
CRTO.CRIMT value, and then using this value in nvme_disable_ctrl()
could potentially cause us to use the (short) enable timeout instead
of the (long) disable timeout.
It would have been way easier if it was just separate registers for
enable and disable timeouts...
If we want things to be more robust, I guess we could read the CAP.TO
register after a reset, and save that value in a ctrl->disable_timeout
which nvme_disable_ctrl() then reuses. Enable timeout can be as it is
in V2, it does not need to be saved.
Kind regards,
Niklas
next prev parent reply other threads:[~2022-05-20 11:52 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-18 6:40 [PATCH] nvme: add support for TP4084 - Time-to-Ready Enhancements Christoph Hellwig
2022-05-18 9:26 ` Hannes Reinecke
2022-05-18 14:36 ` Keith Busch
2022-05-18 15:00 ` Christoph Hellwig
2022-05-18 15:09 ` Keith Busch
2022-05-18 16:14 ` Chaitanya Kulkarni
2022-05-20 11:51 ` Niklas Cassel [this message]
2022-05-20 14:13 ` Keith Busch
2022-05-25 16:19 ` Niklas Cassel
2022-05-25 16:23 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YoeA1Lh9oxwyao2S@x1-carbon \
--to=niklas.cassel@wdc.com \
--cc=hch@lst.de \
--cc=kbusch@kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=sagi@grimberg.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox