All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Osipenko <digetx@gmail.com>
To: Bitan Biswas <bbiswas@nvidia.com>,
	Laxman Dewangan <ldewangan@nvidia.com>,
	Thierry Reding <treding@nvidia.com>,
	Jonathan Hunter <jonathanh@nvidia.com>,
	linux-i2c@vger.kernel.org, linux-tegra@vger.kernel.org,
	linux-kernel@vger.kernel.org, Peter Rosin <peda@axentia.se>,
	Wolfram Sang <wsa@the-dreams.de>
Cc: Shardar Mohammed <smohammed@nvidia.com>,
	Sowjanya Komatineni <skomatineni@nvidia.com>,
	Mantravadi Karthik <mkarthik@nvidia.com>
Subject: Re: [PATCH V4 6/6] i2c: tegra: remove BUG, BUG_ON
Date: Tue, 11 Jun 2019 14:34:23 +0300	[thread overview]
Message-ID: <d29804b9-d3be-9eb2-ba06-f4de2aad3764@gmail.com> (raw)
In-Reply-To: <fe0a0cb2-73e3-8f5c-8115-f99c150bd5df@nvidia.com>

11.06.2019 10:38, Bitan Biswas пишет:
> 
> 
> On 6/10/19 2:00 PM, Dmitry Osipenko wrote:
>> 10.06.2019 22:41, Bitan Biswas пишет:
>>>
>>>
>>> On 6/10/19 11:12 AM, Dmitry Osipenko wrote:
>>>> 10.06.2019 20:08, Bitan Biswas пишет:
>>>>> Remove redundant BUG_ON calls or replace with WARN_ON_ONCE
>>>>> as needed. Remove BUG() and make Rx and Tx case handling
>>>>> similar.
>>>>>
>>>>> Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
>>>>> ---
>>>>>    drivers/i2c/busses/i2c-tegra.c | 11 ++++++-----
>>>>>    1 file changed, 6 insertions(+), 5 deletions(-)
>>>>
>>>> Looks that this is still not correct. What if it transfer-complete flag
>>>> is set and buffer is full on RX? In this case the transfer will succeed
>>>> while it was a failure.
>>>>
>>>>> diff --git a/drivers/i2c/busses/i2c-tegra.c
>>>>> b/drivers/i2c/busses/i2c-tegra.c
>>>>> index 4dfb4c1..30619d6 100644
>>>>> --- a/drivers/i2c/busses/i2c-tegra.c
>>>>> +++ b/drivers/i2c/busses/i2c-tegra.c
>>>>> @@ -515,7 +515,6 @@ static int tegra_i2c_empty_rx_fifo(struct
>>>>> tegra_i2c_dev *i2c_dev)
>>>>>         * prevent overwriting past the end of buf
>>>>>         */
>>>>>        if (rx_fifo_avail > 0 && buf_remaining > 0) {
>>>>> -        BUG_ON(buf_remaining > 3);
>>>>
>>>> Actually error should be returned here since out-of-bounds memory
>>>> accesses must be avoided, hence:
>>>>
>>>>      if (WARN_ON_ONCE(buf_remaining > 3))
>>>>          return -EINVAL;
>>> buf_remaining will be less than equal to 3 because of the expression
>>> earlier
>>> https://elixir.bootlin.com/linux/v5.2-rc4/source/drivers/i2c/busses/i2c-tegra.c#L520
>>>
>>>
>>
>> Ah yes, indeed!
>>
> I see that I am wrong and buf_remaining > 3 needs to be prevented at
> 
> https://elixir.bootlin.com/linux/v5.2-rc4/source/drivers/i2c/busses/i2c-tegra.c#L528
> 
> 
> because of word_to_transfer is limited to rx_fifo_avail:
> 
> https://elixir.bootlin.com/linux/v5.2-rc4/source/drivers/i2c/busses/i2c-tegra.c#L515
> 
> 
> I shall add the check for less than 3 in both RX and TX cases in a
> separate patch in this series.

When word_to_transfer is more than rx_fifo_avail, then the rx_fifo_avail
becomes zero and hence the nibbles won't be copied. Please take a closer
look, the current code is correct, but the buf_remaining > 3 is unneeded
because it can't ever happen.

The code is structured the way that it's difficult to follow, apparently
the person who added the BUG_ON check in the first place couldn't follow
it either. Maybe it's worth to invest some more effort into refactoring
at least that part of the code. At minimum a clarifying comments would
be helpful.

[snip]

>>>> Then here:
>>>>
>>>>      if (WARN_ON_ONCE(!i2c_dev->msg_buf_remaining) ||
>>>>          tegra_i2c_empty_rx_fifo(i2c_dev)) {
>>>>          i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT;
>>>>          goto err;
>>>>      }
>>>>
>>> Can you please elaborate why the condition needs to be as follows
>>> instead of " if (WARN_ON_ONCE(i2c_dev->msg_buf_remaining)) " ?
>>>
>>>>       if (WARN_ON_ONCE(!i2c_dev->msg_buf_remaining) ||
>>>>           tegra_i2c_empty_rx_fifo(i2c_dev)) {
>>
>> Because this is a "receive" transfer and hence it is a error condition
>> if the data-message was already fully received and then there is another
>> request from hardware to receive more data. So
>> "!i2c_dev->msg_buf_remaining" is the error condition here because there
>> is no more space in the buffer.
>>
>> Looking at this again, seems checking for "if
>> (WARN_ON_ONCE(rx_fifo_avail))" in the above hunk [1] will be already
>> enough since a not fully drained RX FIFO means that there is no enough
>> space in the buffer. Then it could be:
>>
>>          if (tegra_i2c_empty_rx_fifo(i2c_dev)) {
>>                  i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT;
>>                  goto err;
>>     }
>>
> In the case "if (status & I2C_INT_PACKET_XFER_COMPLETE) {" , we do not
> have any tegra_i2c_empty_rx_fifo call today. In this current driver I do
> not see any code that checks for the buffer space and prevents RX FIFO
> from being drained. The transfer complete when seen must have already
> consumed all bytes of msg_buf_remaining in the call at the line
> 
> https://elixir.bootlin.com/linux/v5.2-rc4/source/drivers/i2c/busses/i2c-tegra.c#L860
> 
> 
> So we can put the "WARN_ON_ONCE(i2c_dev->msg_buf_remaining) with msg_err
> assignment and goto err" to confirm if some corner case is not handled.
> 
> Planning to share updated patch.

There are two possible error conditions:

1) Underflow: the XFER_COMPLETE happens before message is fully sent.

2) Overflow: message is fully sent, but there is no XFER_COMPLETE and
then hardware asks to transfer more.

We are addressing the second case here, while you seems are confusing it
with the first case.

  reply	other threads:[~2019-06-11 11:34 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-10 17:08 [PATCH V4 1/6] i2c: tegra: clean up macros Bitan Biswas
2019-06-10 17:08 ` Bitan Biswas
2019-06-10 17:08 ` [PATCH V4 2/6] i2c: tegra: remove unnecessary variable init Bitan Biswas
2019-06-10 17:08   ` Bitan Biswas
2019-06-10 17:08 ` [PATCH V4 3/6] i2c: tegra: fix alignment and spacing violations Bitan Biswas
2019-06-10 17:08   ` Bitan Biswas
2019-06-10 17:08 ` [PATCH V4 4/6] i2c: tegra: add spinlock definition comment Bitan Biswas
2019-06-10 17:08   ` Bitan Biswas
2019-06-10 17:08 ` [PATCH V4 5/6] i2c: tegra: fix msleep warning Bitan Biswas
2019-06-10 17:08   ` Bitan Biswas
2019-06-10 17:08 ` [PATCH V4 6/6] i2c: tegra: remove BUG, BUG_ON Bitan Biswas
2019-06-10 17:08   ` Bitan Biswas
2019-06-10 18:12   ` Dmitry Osipenko
2019-06-10 18:18     ` Dmitry Osipenko
2019-06-10 19:41     ` Bitan Biswas
2019-06-10 19:41       ` Bitan Biswas
2019-06-10 21:00       ` Dmitry Osipenko
2019-06-11  7:38         ` Bitan Biswas
2019-06-11  7:38           ` Bitan Biswas
2019-06-11 11:34           ` Dmitry Osipenko [this message]
2019-06-11 18:22             ` Bitan Biswas
2019-06-11 18:22               ` Bitan Biswas
2019-06-12 13:33               ` Dmitry Osipenko
2019-06-13 11:33                 ` Bitan Biswas
2019-06-13 11:33                   ` Bitan Biswas

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=d29804b9-d3be-9eb2-ba06-f4de2aad3764@gmail.com \
    --to=digetx@gmail.com \
    --cc=bbiswas@nvidia.com \
    --cc=jonathanh@nvidia.com \
    --cc=ldewangan@nvidia.com \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=mkarthik@nvidia.com \
    --cc=peda@axentia.se \
    --cc=skomatineni@nvidia.com \
    --cc=smohammed@nvidia.com \
    --cc=treding@nvidia.com \
    --cc=wsa@the-dreams.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.