-
Notifications
You must be signed in to change notification settings - Fork 22
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
Add extern function recirculate() #114
base: main
Are you sure you want to change the base?
Conversation
// recirculate() - Cause the packet to be recirculated when it | ||
// finishes completing the main control. | ||
// | ||
// Invoking recirculate() is supported only within the main control. |
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 this would be better comment:
Invoking recirculate() is supported directly or indirectly called from the main control.
I know this is how it is written in other locations but being more explict of what it means be invoked from the main control is always better.
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 would like to explore following types of recirculations -
- parser -> control -> deparser -- recirc1 --> parser ..... (as shown in pna arch diagram) - User metadata is NOT preserved. Any data needed is added as recirc-header, which will be extracted by parser.
- parser -> control -> -- recirc2 --> control .... -> deparser - User metadata is preserved.
recirc1 and recirc2 (to be named appropriately) are both invoked in action routines and take effect at the end of the pipeline.
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.
With the 2nd form of doing recirc, maybe I suggest, the name redocontrol or something similar to that.
With that being said my hardware can support the 2nd form though I am not so sure the 2nd form is useful; can you think of an usecase for each form?
I can think of removing the xvlan and doing some ACLs and then recirculating it and redoing the parsing to get a new set of headers. That would be the first form.
But I can't think of use case for the 2nd form though unless we have the original parser also get the inner headers. I am not 100% sure if that will always work.
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.
Use cases of 2nd form I can think of -
- implementing longer (stages) pipeline on a target that has smaller number of stages. Each pass launches different set of tables to complete the processing.
- perform hash-chaining on hash collision
- Performance benefit in avoiding parser/deparser processing times if packet is not changed between passes.
Explicitly document what is preserved with packets when they are recirculated. One thought is that all user-defined metadata is preserved, but this is not universally implementable by all vendors wanting to support PNA. One mechanism that seems universally implementable is to explicitly add one or more headers to the packet that must be preserved during recirculation. Another potential mechanism would be that there are one or more arguments to the recirculate operation that are specified by the P4 developer, and this causes those fields to be preserved by the device. For one example of this approach, see the v1model and PSA architectures (they are not the same as each other in the P4 source code mechanisms, but both require the P4 developer to be explicit in what they want to save vs. not). Another idea would be to have different operations for preserving vs. not preserving user-defined metadata, or some way to specify exactly which subset of user-defined metadata is saved, e.g. copying it into a header or struct explicitly in the user's P4 code. (perhaps calling one resubmit vs. recirculate). AI Andy: Present v1model and PSA mechanisms (maybe also TNA?) for preserving metadata at next PNA meeting (probably 2nd week Feb 2023). |
It would be good to also specify precisely what intrinsic metadata changes, and if that is agreed upon behavior between all architectures |
If PNA supports mutable table entries that is also a mechanism for storing state in-between passes. Various implementations will have different cost functions for preserving context in: metadata vs packet headers vs tables. |
There was a discussion about how to control which subset of metadata should be preserved with the packet after a recirculate operation, with notes here: https://docs.google.com/document/d/1vX5GStrE01Pbj6d-liuuHF-4sYXjc601n5zJ4FHQXpM/edit#bookmark=id.uqs2nsxo6mx0 Below is another variation that is somewhat of a combination of some other ideas discussed before, plus one new thing not mentioned during the 2023-Feb-13 meeting. Proposal:
Thoughts? |
Mario: If you want a significant amount of user metadata that is assigned in the main parser, and read and/or written in the main control or main deparser, but NOT recirculated, the approach described in the comment above would not handle that well. Andy: We could consider applying a small tweak to the previous comment where there are two user_metadata parameters: one that is explicitly preserved across recirculation, the other defined NEVER to be preserved across recirculation. Thomas: The approach of adding headers for preserving recirculated metadata could interact badly with hardware accelerators, e.g. IPsec encrypt/decrypt on the recircucation path, unless they were configured somehow to ignore the user-defined custom headers. |
Some notes from 2023-Mar-20 discussion of this topic: Thomas: What about recirculate(single_bit_W_value); extern call, where single_bit_W_value is the ONLY value promised to be preserved with the recirculated packet, and that value is copied into some intrinsic metadata input field that we define, e.g. |
2023-Apr-03 discussion: Sounds reasonable to update this PR to add one bit type to recirculate() extern function as its only parameter, and that value becomes the value of a new recirculate_data field in the parser input and main control input on the next pass. Should we do this, too? Also have a 0-argument variant of recirculate in case a user has no such data they care to include with the packet, in case a target can optimize in this case. |
@jfingerh Reminder from Andy to himself to make progress on this issue. |
With commit 4 of this PR, I believe I have addressed all of the earlier comments above, except for this proposed idea:
I would recommend that such a different operation be part of a separate PR from this one, if someone wants to champion that proposal. |
// `recirc_data` has the same value as the field with the same | ||
// name in struct `pna_main_parser_input_metadata_t` did when this | ||
// packet was parsed. | ||
bit<32> recirc_data; |
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.
Propose changing bit<32> to type parameter T, like so:
struct pna_main_input_metdata_t<T> {
// other fields here
T recirc_data;
}
also hopefully the package definitions below can be used to force T to be the same between parser and main control.
`recirculate` is the same as calling `recirculate` then `drop_packet`, | ||
or different. Alternately, we can explicitly say "every PNA target | ||
should define and document their behavior on arbitrary combinations of | ||
these operations, if they wish". P4 developers would not find that as |
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.
AI Andy: Add a note about one possibility: last-one-wins among drop_packet send_to_port recirculate, but mirror_packet always takes effect on top of the last of those 3 ops.
No description provided.