-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Improvements in TCP connections allocation. #7525
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
Conversation
|
Previously, when I believe this has no meaning now, as we cannot really run out of connections (as easily before at least), and since there is no free connections lists, the connection is nowhere to be returned. Also, as there will never be any free connections, this will trigger this code every time, causing old connections to be dropped constantly, instead of only when actually needed. |
On some platforms this behavior can cause the memory fragmentation, and also if you think the memory fragmentation is acceptable, please configure the numb er of connections to 1, which will consistent with your expectations.
as mentioned in #6960, please release the connections instance if the number of connections is configured to 1, otherwise keep the current behavior, in some cases memory fragmentation is unacceptable. |
As I mentioned, my intention is to add a pool of preallocated connections, to avoid heap fragmentation. So new connections will be allocated only when the pool is exhausted. I will include this change in this PR. |
dbd4d5d to
6e8b289
Compare
|
This is my second take on improving dynamically allocated connections. Now a pool of preallocated connections is created during start. If nevertheless the connections are exhausted, a new one will be allocated, allowing normal operation of the system even during temporal high load. When these "extra" connections are no longer needed, they are properly deallocated. This is not fully tested yet, I am working on this and I will comment back. In the meantime please review the proposed solution. I am planning on also adding a maximum connections limit. This way a misbehaving system, or possibly a network attack, will not exhaust the heap (which will possibly have disastrous consequences). |
|
Also added the maximum connections limit. |
aaec433 to
46cb9c4
Compare
|
Everything seems fine now. Tested on a custom server with a few dozens of connections. It seems stable, and no memory leaks were observed. |
|
I removed the extra Kconfig and all connections are allocated in a single batch. Also I changed init a bit, so it is simpler now, and there is no code duplication. |
0be2fb8 to
7398953
Compare
|
Here is another take on this issue.
Done. For the moment BSS is used, I am not sure whether I will change this to use the heap.
Done. This way it satisfies everyone.
I left this in TCP level. I believe it is much better to be able to tune each protocol independently. Especially because each protocol has a different connection structure size, and different usage. For example the heap may have enough space for 50 UDP connections, but not for 50 TCP connections.
Yes will do, in a future PR though. |
|
I just had the time to complete my tests, and this seems to behave as expected. @xiaoxiang781216 What do you think, can we merge this? Does anyone understand what is the issue with the CI? |
I will take a look in tomorrow
I am trying fix ci break here: #7842 |
|
@fjpanag please rebase to the last master, ci break has been fixed. |
|
@fjpanag it's better to apply the similar change to all socket conn, not only tcp. |
|
not all comments get addressed? |
Working on it... I will ping you. |
|
@fjpanag CONFIG_NET_ALLOC_SOCKETS need be removed from sim/dynconns/defconfig: |
|
Users defconfigs are needed to be updated after this PR. |
|
Marked. |
| else | ||
| #endif | ||
| { | ||
| dq_addlast(&conn->sconn.node, &g_free_ieee802154_connections); |
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.
Maybe we need to move memset(conn, 0, sizeof(*conn)); here and do not spend extra cycles to memset memory that is going to be free-ed?
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 this is a good idea, I will provide a new PR for this.
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.
@pkarashchenko see #8669.
|
|
||
| /* Reset structure */ | ||
|
|
||
| memset(conn, 0, sizeof(*conn)); |
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
|
|
||
| /* Make sure that the connection is marked as uninitialized */ | ||
|
|
||
| memset(conn, 0, sizeof(*conn)); |
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
| else | ||
| #endif | ||
| { | ||
| dq_addlast(&conn->sconn.node, &g_free_tcp_connections); |
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.
Do we need memset(conn, 0, sizeof(*conn)); before adding to the queue
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.
I think not. It seems that tcp_free() sets the contents of conn to specific values, for example see this.
If someone knows for sure how this works, I can add a memset() and then set the flags, or whatever else is needed.
|
|
||
| /* Clear the connection structure */ | ||
|
|
||
| memset(conn, 0, sizeof(*conn)); |
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
| /* Reset structure */ | ||
|
|
||
| nxsem_destroy(&conn->resp.sem); | ||
| memset(conn, 0, sizeof(*conn)); |
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
Summary
This is an attempt to fix the issues reported in #6960:
tcp_free()the connection is actually deallocated, instead of leaving it existing forever in the list.This is only the first step, possibly with more to come (list of pre-allocated connections, maximum connections limit etc).
For the moment, this PR handles only TCP, till we determine all the details.
Then the fix will be copied to all other connections that use similar logic.
Impact
Improved memory utilization in TCP.
Testing
Only minimal testing for the moment.
More testing is expected on actual hardware soon, I will report back.