-
Notifications
You must be signed in to change notification settings - Fork 30
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
PicoServer - get_sender_client_id() returning wrong value #30
Comments
Do you mean that sometimes it correctly loads and runs and sometimes it fails to startup, or that when it runs it sometimes fails on individual packets?
Which version of the project are you using? Are you able to add a GitHub url to where pico_send_get_sender_id() is called? When I look it seems that only pico_control_get_sender_id() is being called? int pico_send_send(int socket_fd, int len, int buffer_offset)
{
seL4_Word client_id = client_check(); And client_check():
This does look like a bug in the picoserver component, where for the pico_send* interface calls, the client check function should be calling The camkes runtime should probably also be setting |
Alright this will be a long one, but with the info you gave I took a second look this week, and was able to identify and fix the problem. I'll try to be as detailed as possible. Answering Questions
I was unsure at first, but after fixing the bug, I can confirm the driver I ported is working as intended, and this was definitely a problem with the PicoServer component.
I am using the default.xml manifest from the camkes-manifest github at tag 3.10.0.
I am not sadly, because these functions are actually generated when calling the init-build.sh script. However, you are correct, even in the generated component code, these functions are never called, which did turn out to be part of the problem. Intended BehaviourThe original problem I described was that the wrong CAmkES Components Waiting
As you can see in in picoserver example application, both the Socket callback function
You can see when this callback is invoked by the low level device loop, it is passed an event, and socket_fd. If there is an event, then the Putting Client Event
Later, after the event has already been put, the CAmkES component actually needs to be notified that it's socket received an event so it can handle it. This is where the Notify Client
This function is called in the low level device loop, and essentially just checks the flag, and emits a signal, then resets the flag. The The BugThe problem I was running into when running the example app is that only one of my components was actually being woken up and handling its events. I eventually tried removing the After seeing your post I took a closer look at the
Essentially, depending on whatever ID is passed in, Well looking back at the The FixThe fix I implemented was very straight forward, and from testing seems to be working flawlessly. Although I have not tried testing with >2 components yet. In the server_cb function: +1 because CAmkES component IDs start at 0, while The next change was in notify_client function: Now instead of a hardcoded emit, One More BugWith that fixed I ran into one other bug, and to come full circle, your comment about The fix here was also very straight forward, in the Send
Receive
With this change, everything seems to be working perfectly for how I'm using it. ConclusionObviously there are larger problems, as something like this should probably be changed in every function instead of the two I'm using. I don't have a commit ready to fix all of this yet, and would be interested to hear feedback on it before getting one ready. However, from what I can tell, when the I am going to do more testing with >2 components, as well as work with UDP and see if I can confirm these fixes will work. If so, I do plan on making a commit which should address the issues I have shown. I will also clean it up a bit, and maybe induce a second |
Tested with 3 components, and more changes will be necessary. Since socket_cb, and notify_client are called by two different threads, some components are not getting signaled before others have their socket_cb function called. This overwrites what client needed emitting, and it will get stuck waiting. I have it mostly working by adding an array with length == number of clients
In socket_cb
In notify_client
This was my first thought of a solution, although it seems wasteful to traverse the entire array every time, Maybe using a linked list would be more efficient. |
Apologies if this is the wrong place for this question, but I am having a problem with the PicoServer App.
Essentially, I have ported an ethernet driver from the Zynq7000 to the Zync Ultrascale+, and am trying to use the PicoServer App to test it. It works about 90% of the time I load and run it, but sometimes it flakes out. I have done a lot of investigation but am a bit stuck as this is the first project I have worked on in either seL4 or camkes.
Right now, I have the Listener component start up and get its socket into the listening state, then I signal the echo client to start up and attempt to make a connection. From my understanding of the app, these components should enter the while loop at the bottom and call seL4_Wait(() and then be woken up by the PicoServer when their socket receives an event. However, I am running into one of two scenarios.
I leave the seL4_Wait() call alone, and the Listener socket is never woken up, even though, when I trace down the TCP/IP stack, I see the syn from the Echo going out and trying to make the connection.
I change seL4_Wait() to and seL4_Poll() call, and the connection is made between the two components, however at times it doesn't work as mentioned above. Specifically when I attempt to send data, either data is not sent, or it says data is sent but the listener doesn't actually receive anything.
I am a little stuck on where to start debugging situation 1, but in situation 2, I have traced the problem to when the component checks its client_id, which then corresponds to what socket gets returned from the PicoServer. A call is made to pico_send_get_sender_id(), which switches on the pico_send_badge to return the ID of the Echo component. At times pico_send_badge is not correctly set to the Echo component's badge, which is causing the wrong badge to get returned, which then causes the wrong client_id to get returned, which then causes the wrong socket to get returned. The stack then attempts to send from the Listener socket instead of the echo socket, which obviously causes an error. At times the error happens on the receiving end, where the Echo component's socket is returned and it tries to receive the data it just sent to the Listener socket, which again causes an error.
My best guess is that since there is a single handle message function being called by potentially two different component threads, that the pico_send_badge is not getting read/written correctly at times. I've tried adding the volatile keyword, but it didn't fix this issue.
I am a bit at a loss on how to progress in debugging this issue. If anyone has any suggestions, or needs more info please let me know. This is my first issue on creation on Github so if this is the wrong place for this or I'm leaving something out please let me know.
The text was updated successfully, but these errors were encountered: