-
Notifications
You must be signed in to change notification settings - Fork 1
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
Port table improvements #425
Conversation
001d3bb
to
344393c
Compare
@PlagueCZ Second question is |
The use of On of such calls is for example You are right about the |
it is true that the port status needs to be checked before packet processing continues when doing routing. however, if it is just about port checking for this particular case, would it be better and simpler if we use a bitmap or a simple array containing status instead of making this link status as a field in the port structure? |
Tao's suggestion (using a table for statuses) would work perfectly well (and would actually be nicely localized), the only drawback I see is the requirement for array-bounds checking, which is one of the things this changes is trying to get rid of by verifying the |
55e45a1
to
00ab9b8
Compare
@PlagueCZ Thanks for the clarification. I think this is not smt introduced by this PR but I can not seem to find the place where the |
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.
Thanks. Looks good to me. I will merge it and the open question regarding the port attached state will be handled by @byteocean in a different PR, if needed.
Motivation
struct dp_port *dp_port_get(port_id)
(called inside many functions) from list traversal O(n) to direct array access O(1), which happened for every packetrte_eth_dev_socket_id()
on the sameport_id
RTE_VERIFY(port_id < RTE_DIM(some_port_indexed_table))
that can crashsome_global_table[DP_MAX_PORTS]
into one placeChanges
This caused replacing most of
uint16_t port_id
function arguments tostruct dp_port *port
, which is the largest part of the changes across the codebase.I created a table of ports and moved all
vm_entry
andinternal_stats
intostruct dp_port
since all these were also accessed by a port_id. This also enabled doing aDP_FOREACH_PORT
to iterate VMs (that were previously traversing all possible 128 ports even when not in use).In the end I inlined hot-functions (like
dp_port_get(m->port_id)
since it gets called multiple times for each packet traversal). This does require havingextern _dp_variables
in the header though.To further optimize, there are now
dp_get_port(m)
anddp_get_dst_port(df)
that do not check the table index, thus will never fail, based on the fact thatm->port
anddf->nxt_hop
are already checked once. If this is something unwanted, I can change it, though it really complicates the code with all theif (!port) return DROP_
etc.I also dropped some of the wrappers (like
dp_get_fwall_head(port_id)
) and directly useport->vm.fwall_head
because:port
is already valid pointer (no need to checkport_id
index as before)memcpy()
can be checked bysizeof()
nowSince I touched many
dp_lpm_
functions anyway I noticed that there are many VM-related ones that are not LPM/routing related, so I separated those intodp_vm.c
.Also small changes like adding a
pci_name
tostruct dp_port
to prevent system calls in every listing of interfaces again and again; changing the logging macro to directly usedp_port
, etc.One thing that I changed and am not 100% sure about is the fact that previously some VNI functions, like
dp_lpm_reset_route_tables(vni, socket_id)
ordp_get_vni_route4_table(vni, socket_id)
used the argumentsocket_id
that was retrieved fromport_id
. But there already is a storedsocket_id
instruct vni_value
, so I used that instead as that seems to be the desired use.