-
Notifications
You must be signed in to change notification settings - Fork 445
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
Part 1 for PSA support #601
Conversation
Yeah, we should get this reviewed and landed quickly, since it touches a huge number of files. It looks like you need to rebase already. |
backends/bmv2/JsonObjects.cpp
Outdated
|
||
/// create a new field to an existing header type, returns a pointer to the field | ||
void | ||
JsonObjects::add_header_field(const cstring& name, Util::JsonArray** field) { |
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.
This function doesn't return anything, despite the comment. It also just uses *field
, it doesn't try to modify it, so does it need the double pointer?
backends/bmv2/JsonObjects.h
Outdated
#ifndef _BACKENDS_BMV2_JSONOBJECTS_H_ | ||
#define _BACKENDS_BMV2_JSONOBJECTS_H_ | ||
|
||
namespace bm { |
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.
We generally use namespace BMV2
for bmv2 -- in any case we always use Capitalized names for namespaces.
auto km = k->to<IR::Mask>(); | ||
key->emplace("key", stringRepr(km->left->to<IR::Constant>()->value, k8)); | ||
auto trailing_zeros = [](unsigned long n) { return n ? __builtin_ctzl(n) : 0; }; | ||
auto count_ones = [](unsigned long n) { return n ? __builtin_popcountl(n) : 0;}; |
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.
These functions should probably be added to lib/bitops.h rather than being defined inline here.
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.
or rather lib/gmputil.h
backends/bmv2/deparser.h
Outdated
public: | ||
explicit ConvertDeparser(Backend* backend) { | ||
passes.push_back(new DoDeparserBlockConversion(backend)); | ||
setName("ConvertDeparser"); |
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 you expect to want to add more passes here? If not, using a pass manager for a single pass is unnecessarily obscure.
backends/bmv2/lower.cpp
Outdated
@@ -401,7 +401,8 @@ class ComplexExpression : public Inspector { | |||
const IR::PathExpression* | |||
RemoveComplexExpressions::createTemporary(const IR::Expression* expression) { | |||
auto type = typeMap->getType(expression, true); | |||
auto name = refMap->newName("tmp"); | |||
LOG1("expression " << expression << " " << type); |
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.
LOG1 should only be used for messages that are self-contained and not too frequent, such as starting or ending a pass. This should probably be LOG3 or LOG4?
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.
There are a few things that I think you should remove from this PR, there are not ready for mainstream, and they are unlikely to conflict with future changes (e.g. the p4d2 tests, the remap for field aliases).
backends/bmv2/JsonObjects.cpp
Outdated
} | ||
|
||
/// append a json object r to a parent json array | ||
/// insert a field 'op' with 'name' to r |
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.
s/r/parent
|
||
class ConvertActions : public Inspector { | ||
Backend* backend; | ||
P4::ReferenceMap* refMap; |
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.
Is there a particular reason to have these as data members? You are initializing them from the backend data members.
backends/bmv2/backend.cpp
Outdated
|
||
namespace BMV2 { | ||
|
||
void Backend::createFieldAliases(const char *remapFile) { |
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.
This is not needed anymore, is it? We're not using remap files.
backends/bmv2/metadata.cpp
Outdated
*/ | ||
|
||
/* | ||
Copyright 2013-present Barefoot Networks, Inc. |
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.
two copyright headers is one too many :)
backends/bmv2/metadata.cpp
Outdated
|
||
namespace BMV2 { | ||
|
||
} // end namespace BMV2 |
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.
this is not needed anymore.
backends/bmv2/metermap.cpp
Outdated
/** | ||
Set the size of the table that a meter is attached to. | ||
|
||
@param meter |
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.
unless you comment the parameters themselves, it's not needed to just add them as a @param
.
|
||
namespace BMV2 { | ||
|
||
class DirectMeterMap final { |
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.
class comment?
p4include/p4d2model_bmss_meta.map
Outdated
@@ -0,0 +1,29 @@ | |||
# This file maps p4d2 metadata to the bmv2 simple switch standard and intrinsic metadata |
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.
remove this file too.
@@ -0,0 +1,159 @@ | |||
/* -*- P4_16 -*- */ | |||
#include <core.p4> | |||
#include <p4d2model.p4> |
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.
is this test still failing? should we convert it back to v1model?
@@ -0,0 +1,8 @@ | |||
set_default ipv4_lpm drop |
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.
before checking these in, we should make sure they are correct. I'm not convinced that the packet data is going to work for this test.
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.
It will be impossible to review this patch in detail, given its size, and the fact that the diff tools do not work well across many files. I think that we will have to rely on the tests to a very large degree.
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.
good work, hard to review thoroughly though
backends/bmv2/JsonObjects.h
Outdated
#define _BACKENDS_BMV2_JSONOBJECTS_H_ | ||
|
||
namespace bm { | ||
|
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.
this header should probably include its dependencies, like <map>
, etc and forward declare Util::JsonArray
, etc.
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.
by the way this is important to people not using a unified build
backends/bmv2/v1model.cpp
Outdated
BUG_CHECK(hash->is<IR::Declaration_ID>(), "%1%: expected a member", hash); | ||
auto algo = convertHashAlgorithm(hash->to<IR::Declaration_ID>()->name); | ||
selector->emplace("algo", algo); | ||
// FIXME selector_check pass |
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.
why was this commented-out?
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.
good catch, I put it back.
backends/bmv2/action.cpp
Outdated
if (type->is<IR::Type_StructLike>()) | ||
operation = "copy_header"; | ||
else | ||
operation = "modify_field"; |
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.
you should try to use the new bmv2 core primitives when possible given that they will be available on all archs: assign
, assign_header
... (see https://github.com/p4lang/behavioral-model/blob/master/include/bm/bm_sim/core/primitives.h). For example assign
is strictly equivalent to the "old" modify_field
.
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.
can you point me to the mapping for copy_header
, add_header
, remove_header
and exit
?
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.
there is no mapping (also some new core primitives have no old equivalent), you'll have to go by the names
for exit
, you should keep using exit
, the name is staying the same
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.
Looks good.
- Comments on how to handle the semantics of multiple PRE invocations - and design option of splitting the PRE into PRE and BQE (Buffering and Queueing Engine) - added PRE as argument to Ingress and Egress - added missing 'in' qualifiers and random distribution - add size types instead of indefinite int - update with @mbudiu-vmw comments to pass through compiler - ActionProfile and ActionSelector externs
This commit refactors bmv2 backend to support multiple pipelien architectures. JsonConverter is refactored into a pass manager which is more conformed to the rest of the compiler design. Added files: backend.cpp - the new backend pass manager convert*.cpp - compiler passes for control, parser, deparser, externs and headers inferArchitecture - a new frontend pass to parse the architecture p4 into a data object which is then used by json generator model.cpp - a v2model that oriented for p4-16 IR TODO: tov1model - a pass to convert v2model to v1model to execute on simple-switch
Also fixes issues with decl handling and match types.
…y simple switch Allows access to bmv2 simple switch intrinsic and queueing metadata for programs that use the v1model. While these metadata would be available by defining separate metadata with the correct names, it is desirable that the functionality is exposed in the architecture definition. This patch will work with any metadata that has fields renamed.
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.
Although the code has been merged, I think that some things need to be fixed. This review is not comprehensive, because it is very difficult to read code that has been split across files. It would have been much better if this was provided as a set of separate patches. This should also live in an experimental branch, and not in master, since it has not been reviewed properly.
@@ -102,7 +102,8 @@ BUILT_SOURCES += \ | |||
# FIXME -- and check-install-headers: below need to be consistent | |||
p4includedir = $(pkgdatadir)/p4include | |||
p4_14includedir = $(pkgdatadir)/p4_14include | |||
p4include_HEADERS += $(srcdir)/p4include/core.p4 $(srcdir)/p4include/v1model.p4 | |||
p4include_HEADERS += $(wildcard $(srcdir)/p4include/*.p4) \ | |||
$(wildcard $(srcdir)/p4include/*.map) |
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.
map files are something new; they deserve an explanation. They are also installed, so they seem quite important.
field_aliases = insert_array_field(toplevel, "field_aliases"); | ||
} | ||
|
||
/// insert a json array to a parent object under key 'name' |
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 that we want phrase capitalization for such comments: start with an uppercase and end with a period.
void | ||
JsonObjects::add_meta_info() { | ||
auto info = new Util::JsonObject(); | ||
static constexpr int version_major = 2; |
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.
This is actually the dialect version of the JSON language supported. I think that these constants should be in a more prominent place, not in code.
backends/bmv2/JsonObjects.cpp
Outdated
} | ||
|
||
/** | ||
* create a header type in json |
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.
This function and the next ones should also have a @returns tag.
return id; | ||
} | ||
|
||
/// create a heder type with empty field list. |
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.
typo in comment
|
||
/* P4-16 declaration of the P4-D2 (P4 Developer's Day) switch model */ | ||
|
||
#include "core.p4" |
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.
This should be #include <core.p4>
@@ -38,6 +38,18 @@ struct standard_metadata_t { | |||
bit<1> drop; | |||
bit<16> recirculate_port; | |||
bit<32> packet_length; | |||
// flattening fields that exist in bmv2-ss | |||
// queueing metadata | |||
@alias("queueing_metadata.enq_timestamp") bit<32> enq_timestamp; |
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.
The @alias
annotation is not documented. What does it mean?
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.
@alias is used to generate the field_alias
section of the BMV2 JSON. Field alias creates a mapping from the metadata name in P4 program to the behavioral model's internal metadata name. Here we use it to expose all metadata supported by behavior model to user through standard metadata, as requested by @vgurevich
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.
You have to add this description to the v1model.p4 file itself.
@@ -133,14 +145,17 @@ parser Parser<H, M>(packet_in b, | |||
inout standard_metadata_t standard_metadata); | |||
control VerifyChecksum<H, M>(in H hdr, | |||
inout M meta); | |||
@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.
The @pipeline annotation is not documented anywhere. I think it should be removed.
You are essentially duplicating functionality provided by the package operation - the fact that something is a pipeline is given by the fact that it is used as an argument to the V1Switch package in the right position.
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.
The @pipeline annotation is needed because BMv2 JSON mandates only ingress and egress can be in the pipeline
section. The original BMv2 backend hard-coded the name of ingress and egress in v1model when generating the pipeline
section in JSON. When I wrote the visitor, I did not figure out a way to traverse only ingress
and egress
, and not verifychecksum
and updatechecksum
without hard-coding the names. They are all Controlblock
from the visitor's point of view.
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.
The annotation is on the type, not on the instance, so this way of doing it won't work.
For example, you could very well have multiple blocks with the same type required in the package, e.g., the same signature for checksum updates and for the main pipeline.
The way you distinguish them is by the argument of package they bind to. That's why there is a pass which takes a policy about which controls to skip. What you have to do is something similar for the P2D2 architecture: a list of controls to skip.
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.
Previously, the skipControls policy receives the list of control blocks to skip from the hard-coded names in v1model.
Line 126 in b25ba2d
auto ingress = main->getParameterValue(P4V1::V1Model::instance.sw.ingress.name); |
updateChecksum
in PSA, or other architecture that people come up with. I am not sure how to identify updateChecksum without using annotation?
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 understand what you are trying to do.
The problem comes from the fact that you are trying to support multiple architectures with a single back-end. That will be harder and harder as these architecture diverge in behaviors. For example, changes you make for PSA may break v1model programs. Also, the BMv2 back-end generates a program called p4c-bm2-ss, so you see that it targets a specific simulator on top of BMv2 (bmv2 can be used to implements lots of different simulators), and it it assumes a specific model for the input architecture, v1model. These things are tightly coupled in the code; the C++ code hardwires a lot of knowledge about v1model and BMv2 SS in particular. You are trying to de-entangle them, but that won't be easy.
However, v1model should be thought as a description of a fixed architecture, which cannot be changed. In general, you cannot assume you can edit it anymore after you have distributed it to customers.
Moreover, regarding the @pipeline annotations, all the information you need IS in the package. It is just annoying to extract. Maybe you can write some helper functions to make this easier. For v1model we know that the pipelines are arguments 3 and 4 of the main package, and the deparser is argument 6 (the code in fact uses the parameter names in v1model to retrieve them). This is a contract between the architecture and the compiler, and it can never change once you published the architecture, so you can rely on it. Similarly, for PSA you will identify the pipelines from the arguments to the main package. So what you have to do is write a generic class that can identify the blocks from the main package, provide two implementations for PSA and v1model and output the same data-structure that you can use from both. I would suggest not using annotations, but just set, the same way it was done in the BMv2 back-end.
* These types need to be defined before including the architecture file | ||
* and the macro protecting them should be defined. | ||
*/ | ||
#ifndef PSA_CORE_TYPES |
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.
Is this file the most recent version?
It looks like this file cannot compile.
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.
We haven't fully tested psa.p4 yet. I will do it in the next PR.
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 you can then remove it from the PR?
/** | ||
* PSA supported metadata types | ||
*/ | ||
struct psa_parser_input_metadata_t { |
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.
indentation is wrong.
Thanks very much for the review, Mihai. I will address your comments today. |
This is a rather large commit to refactor bmv2 backend to enable easier support for PSA.
A few major changes in this commit:
jsonconverter.cpp
had two jobs: traversing the IR and generating the corresponding JSON template. We introduced a newJsonObjects
class that handles the JSON template generation and refactoredjsonconverter.cpp
into individualheader.cpp
,control.cpp
,extern.cpp
,action.cpp
,parser.cpp
,deparser.cpp
files to limit each file to one aspect of the IR.primitive
s are handled differently by v1model and PSA. We separated out the v1model-specific primitive generation intov1model.cpp
to be backward-compatible with bm2-ss.As the code stands right now, it still generates valid JSON for bm2-ss. Our next step is to enable JSON generation for bm2-psa, and test with PSA behavior model.
In the interest of not keep a branch for too long, I hope we can fold this change in, to allow others to modify the refactored code, instead of adding changes to
jsonconverter.cpp
.