Skip to content
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

Ring buffer code cleanups #84060

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Conversation

npitre
Copy link
Collaborator

@npitre npitre commented Jan 15, 2025

  • ring_buffer: delete redundant code
  • ring_buffer: optimize the partial buffer loop
  • ring_buffer: factorize almost identical code

andyross
andyross previously approved these changes Jan 16, 2025
Copy link
Contributor

@andyross andyross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks clean. Another advantage to new work being encouraged to reuse existing tools is that the existing tools get a round of review and audit too.

do {
partial_size = ring_buf_get_claim(buf, &src, size);
if (partial_size == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style, since the test is now at the top of the loop, you could refactor this into a while via e.g.:

while((partial_size = ring_buf_get_claim(buf, &src, size)) != 0) {
   ...
}

IIRC someone (MISRA?) doesn't want us using assignment in while expressions though, so it might need a wrapper that takes the size by reference and returns a boolean? Or not, I don't remember what the rules are supposed to be anymore.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure MISRA is against assignments within condition tests. And the loop has 2 exit conditions: one at the top and one at the bottom.

@npitre
Copy link
Collaborator Author

npitre commented Jan 16, 2025

The CI failure baffles me. Ideas anyone?

@peter-mitsis
Copy link
Collaborator

Regarding the CI failure ...

  1. It is reproducible.
  2. Locally, I see the failure arising after applying the 4th commit in the patch set.
  3. I added a printk statement to where tracing_api_not_found is set to true. It suggests that the string 'sys_trace_k_mutex_unlock_exit' is not being found in the data.
  4. More curiously, that same debug string is showing up even when the test passes--but after it reports a successful run. Something is definitely off.

@npitre
Copy link
Collaborator Author

npitre commented Jan 16, 2025

I reduced the CI failure to the following patch applied to the otherwise
unmodified main branch:

diff --git a/lib/utils/ring_buffer.c b/lib/utils/ring_buffer.c
index 39e6e257e92..f5121f817c2 100644
--- a/lib/utils/ring_buffer.c
+++ b/lib/utils/ring_buffer.c
@@ -16,14 +16,25 @@ uint32_t ring_buf_put_claim(struct ring_buf *buf, uint8_t **data, uint32_t size)
 
 	base = buf->put_base;
 	wrap_size = buf->put_head - base;
+
+	/*
+	 * Same as the line after the if, however here this causes
+	 * "west build -p -b qemu_x86/atom tests/subsys/tracing/tracing_api -T tracing.transport.uart.async.test"
+	 * to fail when uncommented.
+	 */
+	free_space = buf->size - (buf->put_head - buf->get_tail);
+
 	if (unlikely(wrap_size >= buf->size)) {
 		/* put_base is not yet adjusted */
 		wrap_size -= buf->size;
 		base += buf->size;
 	}
+
+	/* duplicate of the line above */
+	free_space = buf->size - (buf->put_head - buf->get_tail);
+
 	wrap_size = buf->size - wrap_size;
 
-	free_space = ring_buf_space_get(buf);
 	size = MIN(size, free_space);
 	size = MIN(size, wrap_size);
 

Makes no sense to me. Assembly output is different with and without the
offending line of course but my x86 assembly fu isn't up to the task.

@@ -235,30 +235,6 @@ static inline void z_swap_unlocked(void)
*
* The memory of the dummy thread can be completely uninitialized.
*/
static inline void z_dummy_thread_init(struct k_thread *dummy_thread)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to factor this change out to a separate PR?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WTF? This was supposed to be part of PR #83871 which shows as being merged. Yet the main branch does not have it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh-oh

Nicolas Pitre added 3 commits January 17, 2025 11:28
No need to clamp requested size as ring_buf_get_claim() does it already.

Signed-off-by: Nicolas Pitre <[email protected]>
It is more efficient to break early when size of claimed area becomes zero.

Signed-off-by: Nicolas Pitre <[email protected]>
Factorize almost identical code. May even improve performance due to
CPU cache locality.

Signed-off-by: Nicolas Pitre <[email protected]>
@peter-mitsis
Copy link
Collaborator

I am presently suspecting that the CI failure is due to a problem with the test itself. In a previous comment I noted that the same debug string still shows up when the test passes (without the proposed changes). This is making me suspect that there is something amiss not with the ring buffer code but with the test, and that the proposed changes have altered the timing just enough such that the test will detect a failure before it completes. FWIW, the tracing buffer has a default size of 2048 (CONFIG_TRACING_BUFFER_SIZE). Increase this value and the test will pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants