-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
drivers/serial/serial.c: adapt to the iovec-based api #14898
base: master
Are you sure you want to change the base?
Conversation
[Experimental Bot, please feedback here] Fill In The Commit Message: This PR contains a Commit with an Empty Commit Message. Please fill in the Commit Message with the PR Summary. No, this PR does not fully meet the NuttX requirements. While it provides a summary and mentions testing, it lacks crucial details. Here's a breakdown of missing information:
Specifically, the author needs to:
|
b94fb12
to
2937e17
Compare
@@ -102,6 +101,11 @@ static ssize_t file_readv_compat(FAR struct file *filep, | |||
remaining -= nread; | |||
} | |||
|
|||
if (ntotal >= 0) | |||
{ | |||
uio_advance(uio, ntotal); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's benefit to update the offset in one of uio entry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it eases logic like:
while (uio_resid(uio) > 0) {
n = process_some(uio, ...);
uio_advance(uio, n);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and maybe can help things like restart on EINTR in future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we advance in the loop to avoid iterate the vector twice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, we can. i feel it's one of the last things to optimize though.
* Or -EOVERFLOW. | ||
* | ||
****************************************************************************/ | ||
|
||
ssize_t uio_total_len(FAR const struct uio *uio) | ||
ssize_t uio_resid(FAR const struct uio *uio) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uio_remain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"resid" is the term used by BSDs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, can we follow https://man.freebsd.org/cgi/man.cgi?uio(9) as much as possible, which define uio_offset and uio_resid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. let me think i bit.
This can simplify partial result handling.
"total" is a bit confusing after the introduction of uio_advance().
although i'm not quite happy with the "offset" functionality, it's necessary to simplify the adaptation of some drivers like drivers/serial/serial.c, which (ab)uses the user-supplied buffer as a line-buffer.
This would fix readv/writev issues mentioned in apache#12674. (only for this specific driver though. with this approach, we basically have to fix every single drivers and filesystems.) Lightly tested on the serial console, using micropython REPL on toywasm with esp32s3-devkit:toywasm, which used to be suffered by the readv issue.
* Or -EOVERFLOW. | ||
* | ||
****************************************************************************/ | ||
|
||
ssize_t uio_total_len(FAR const struct uio *uio) | ||
ssize_t uio_resid(FAR const struct uio *uio) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, can we follow https://man.freebsd.org/cgi/man.cgi?uio(9) as much as possible, which define uio_offset and uio_resid?
total = uio_total_len(uio); | ||
if (total >= 0) | ||
{ | ||
uio_advance(uio, total); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we advance one by one to avoid iterate the vector twice
@@ -94,19 +91,27 @@ static ssize_t devzero_readv(FAR struct file *filep, | |||
memset(iov[i].iov_base, 0, iov[i].iov_len); | |||
} | |||
|
|||
uio_advance(uio, total); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we advance one by one to avoid iterate the vector three times
ssize_t ret = uio_total_len(uio); | ||
if (ret >= 0) | ||
{ | ||
uio_advance(uio, ret); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we advance one by one to avoid iterate the vector twice
ssize_t ret = uio_total_len(uio); /* Say that everything was written */ | ||
if (ret >= 0) | ||
{ | ||
uio_advance(uio, ret); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we advance one by one to avoid iterate the vector twice
memcpy((FAR uint8_t *)iov->iov_base + offset, buf, blen); | ||
|
||
len -= blen; | ||
if (len == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
DEBUGASSERT(uio_resid(uio) >= 0); | ||
DEBUGASSERT(len <= uio_resid(uio)); | ||
DEBUGASSERT(offset <= uio_resid(uio) - len); | ||
DEBUGASSERT(SSIZE_MAX - offset >= uio->uio_offset_in_iov); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
memcpy(buf, (FAR const uint8_t *)iov->iov_base + offset, blen); | ||
|
||
len -= blen; | ||
if (len == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
@@ -1408,9 +1469,9 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, | |||
*/ | |||
|
|||
uart_disabletxint(dev); | |||
for (; buflen; buflen--) | |||
for (; buflen; uio_advance(uio, 1), buflen--) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
merge line 1474
leave_critical_section(flags); | ||
|
||
return ret; | ||
} | ||
|
||
buflen = nwritten = uio_resid(uio); | ||
if (nwritten < 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why add the additional check
Summary
drivers/serial/serial.c: adapt to the iovec-based api
This would fix readv/writev issues mentioned in
#12674.
(only for this specific driver though. with this approach,
we basically have to fix every single drivers and
filesystems.)
Impact
Testing
Lightly tested on the serial console, using micropython REPL
on toywasm with esp32s3-devkit:toywasm, which used to be
suffered by the readv issue.