11.06.2019 21:22, Bitan Biswas ÐÐÑÐÑ:OK.
On 6/11/19 4:34 AM, Dmitry Osipenko wrote:
11.06.2019 10:38, Bitan Biswas ÐÐÑÐÑ:I shall try to add some comments near the BUG_ON check.
On 6/10/19 2:00 PM, Dmitry Osipenko wrote:
10.06.2019 22:41, Bitan Biswas ÐÐÑÐÑ:I see that I am wrong and buf_remaining > 3 needs to be prevented at
On 6/10/19 11:12 AM, Dmitry Osipenko wrote:
10.06.2019 20:08, Bitan Biswas ÐÐÑÐÑ:buf_remaining will be less than equal to 3 because of the expression
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@xxxxxxxxxx>
---
ÂÂÂ 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;
earlier
https://elixir.bootlin.com/linux/v5.2-rc4/source/drivers/i2c/busses/i2c-tegra.c#L520
Ah yes, indeed!
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]Is the Overflow case pointed above corresponding to when
In the case "if (status & I2C_INT_PACKET_XFER_COMPLETE) {" , we do notThen here:Can you please elaborate why the condition needs to be as follows
ÂÂÂÂÂÂ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;
ÂÂÂÂÂÂ}
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;
ÂÂÂÂÂ}
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.
msg_buf_remaining is zero?
Yes!
If no, what indicates that message is fullyI would update the patch for the Overflow case around the line 862 pointed.
sent? I see that if msg_buf_remaining is already zero, the call
tegra_i2c_empty_rx_fifo will not do any copy of the bytes from FIFO to buf.
One more point that is not clear to me is are the above suggestions you
made is corresponding to replacing below line in linux-next ?
https://elixir.bootlin.com/linux/v5.2-rc4/source/drivers/i2c/busses/i2c-tegra.c#L888
That addresses the "underflow" case. I'm not suggesting to replace it at
all. I was talking about replacing this and nothing else:
https://elixir.bootlin.com/linux/v5.2-rc4/source/drivers/i2c/busses/i2c-tegra.c#L862
Thanks. Based on your review plan to abandon the patch "V5 6/7".
Can you please also review the newly added patch "V5 6/7 "that was newly
posted? I think it is needed.
Sure.