All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick DELAUNAY <patrick.delaunay@st.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 2/4] serial: protect access to serial rx buffer
Date: Tue, 4 Sep 2018 07:56:36 +0000	[thread overview]
Message-ID: <f7932e63538e4315aa77ca62c56e0786@SFHDAG6NODE3.st.com> (raw)
In-Reply-To: <5f210bf2-228e-86e5-26c2-563acbab2386@denx.de>

Hi Stefan

> From: Stefan <sr@denx.de>
> Sent: lundi 3 septembre 2018 16:03
> 
> Hi Patrick,
> 
> On 03.09.2018 15:35, Patrick DELAUNAY wrote:
> > Hi Simon and Stefan,
> >
> > Sorry for my late answer (I just come back from my summer holiday)
> >
> >> From: sjg at google.com <sjg@google.com> On Behalf Of Simon Glass
> >> Sent: mercredi 8 août 2018 11:56
> >>
> >> On 3 August 2018 at 05:38, Patrick Delaunay <patrick.delaunay@st.com>
> wrote:
> >>> Add test to avoid access to rx buffer when this buffer is empty.
> >>> In this case directly call getc() function to avoid issue when
> >>> tstc() is not called.
> >>>
> >>> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> >>> ---
> >>>
> >>>   drivers/serial/serial-uclass.c | 3 +++
> >>>   1 file changed, 3 insertions(+)
> >>>
> >>> diff --git a/drivers/serial/serial-uclass.c
> >>> b/drivers/serial/serial-uclass.c index 321d23e..4121a37 100644
> >>> --- a/drivers/serial/serial-uclass.c
> >>> +++ b/drivers/serial/serial-uclass.c
> >>> @@ -228,6 +228,9 @@ static int _serial_getc(struct udevice *dev)
> >>>          struct serial_dev_priv *upriv = dev_get_uclass_priv(dev);
> >>>          char val;
> >>>
> >>> +       if (upriv->rd_ptr == upriv->wr_ptr)
> >>> +               return __serial_getc(dev);
> >>> +
> >>>          val = upriv->buf[upriv->rd_ptr++];
> >>>          upriv->rd_ptr %= CONFIG_SERIAL_RX_BUFFER_SIZE;
> >>>
> >>> --
> >>> 2.7.4
> >>>
> >>
> >> Reviewed-by: Simon Glass <sjg@chromium.org>
> >>
> >> BTW I think the code in _serial_tstc() is wrong, or at least sub-optimal:
> >>
> >> /* Read all available chars into the RX buffer */ while (__serial_tstc(dev)) {
> >>     upriv->buf[upriv->wr_ptr++] = __serial_getc(dev);
> >>     upriv->wr_ptr %= CONFIG_SERIAL_RX_BUFFER_SIZE; }
> >>
> >> It should call serial_getc() until it returns -EAGAIN. There should
> >> be no need to call __serial_tstc() first,
> >
> > This part had be added by Stefan Roese in
> > SHA1 3ca7a06afb7cbc867b7861a8b9aada74e5bbb559
> >
> > But I check again the code, and I think the code is correct....
> 
> I really hope so. I did test this implementation quite heavily at that time.
> 
> > but I agree it is not optimal.
> >
> > we can directly ops->getc(dev) and no more __serial_getc() or
> > __serial_tstc() :
> > the behavior don't change but the access to serial driver is reduced.
> > When no char is available, ops->getc witll return -EAGAIN
> >
> > static int _serial_tstc(struct udevice *dev) {
> > 	struct dm_serial_ops *ops = serial_get_ops(dev);
> > 	struct serial_dev_priv *upriv = dev_get_uclass_priv(dev);
> > 	int err;
> >
> > 	/* Read all available chars into the RX buffer */
> > 	while(1) {
> > 		err = ops->getc(dev);
> > 		if (err < 0)
> > 			break;
> > 		upriv->buf[upriv->wr_ptr++] = err;
> > 		upriv->wr_ptr %= CONFIG_SERIAL_RX_BUFFER_SIZE;
> > 	}
> >
> > 	return upriv->rd_ptr != upriv->wr_ptr ? 1 : 0; }
> >
> > If you are OK I will push a other patchset for these otpimisation.
> 
> I'm not 100% sure, if this new implementation is "better". Lets compare the
> code:
> 
> Current version:
> static int _serial_tstc(struct udevice *dev) {
> 	struct serial_dev_priv *upriv = dev_get_uclass_priv(dev);
> 
> 	/* Read all available chars into the RX buffer */
> 	while (__serial_tstc(dev)) {
> 		upriv->buf[upriv->wr_ptr++] = __serial_getc(dev);
> 		upriv->wr_ptr %= CONFIG_SERIAL_RX_BUFFER_SIZE;
> 	}
> 
> 	return upriv->rd_ptr != upriv->wr_ptr ? 1 : 0; }
> 
> New version:
> static int _serial_tstc(struct udevice *dev) {
> 	struct dm_serial_ops *ops = serial_get_ops(dev);
> 	struct serial_dev_priv *upriv = dev_get_uclass_priv(dev);
> 	int err;
> 
> 	/* Read all available chars into the RX buffer */
> 	while(1) {
> 		err = ops->getc(dev);
> 		if (err < 0)
> 			break;
> 		upriv->buf[upriv->wr_ptr++] = err;
> 		upriv->wr_ptr %= CONFIG_SERIAL_RX_BUFFER_SIZE;
> 	}
> 
> 	return upriv->rd_ptr != upriv->wr_ptr ? 1 : 0; }
> 
> The new version has more code and will most likely produce a larger binary. You
> are removing the calls to the __foo() functions - making the call chain a bit
> smaller. But this will only affect the performance which is most likely negligible
> in this case.

Yes, perhaps a larger code but no more  "pending"  ops call of serial driver.
I only  directly use getc ops => that avoid one access to HW register I think.

Than can improve the execution time, but I agree that seems marginal in most the case.

> I any case, I don't object against any "optimizations" here.
> But please make sure to test any changes very thorough - please also on
> platforms with limited RX FIFO sizes.

Unfortunately I have no platform with limited FIFO size, So I don't known how test it deeply.

And the impact depends also how is implemented the serial driver (gets and pending ops can use several HW register access and is depending on the access time to the IP).

But if you and Simon think that "optimization" is not needed, you can forget this proposal because I think also the gain should be very low.
This proposal is only a reaction on the Simon comment (at least sub-optimal)

> Thanks,
> Stefan

Regards
Patrick 

  reply	other threads:[~2018-09-04  7:56 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-03 11:38 [U-Boot] [PATCH 0/4] Solve issue with serial rx buffer when MUX is deactivated Patrick Delaunay
2018-08-03 11:38 ` [U-Boot] [PATCH 1/4] stm32mp1: activate serial rx buffer Patrick Delaunay
2018-09-11 12:24   ` [U-Boot] [U-Boot,1/4] " Tom Rini
2018-08-03 11:38 ` [U-Boot] [PATCH 2/4] serial: protect access to " Patrick Delaunay
2018-08-08  9:56   ` Simon Glass
2018-09-03 13:35     ` Patrick DELAUNAY
2018-09-03 14:03       ` Stefan
2018-09-04  7:56         ` Patrick DELAUNAY [this message]
2018-09-04 12:07           ` Stefan
2018-09-06  8:09             ` Patrick DELAUNAY
2018-09-11 12:24   ` [U-Boot] [U-Boot, " Tom Rini
2018-08-03 11:38 ` [U-Boot] [PATCH 3/4] console: unify fgetc function when console MUX is deactivated Patrick Delaunay
2018-08-08  9:55   ` Simon Glass
2018-09-03 14:56     ` Patrick DELAUNAY
2018-09-11 12:24   ` [U-Boot] [U-Boot, " Tom Rini
2018-08-03 11:38 ` [U-Boot] [PATCH 4/4] cli: handle getch error Patrick Delaunay
2018-09-11 12:24   ` [U-Boot] [U-Boot,4/4] " Tom Rini

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=f7932e63538e4315aa77ca62c56e0786@SFHDAG6NODE3.st.com \
    --to=patrick.delaunay@st.com \
    --cc=u-boot@lists.denx.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.