Skip to content
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

DPDK backend: Add support for meter and counter extern #2813

Merged
merged 34 commits into from
Jun 29, 2021

Conversation

usha1830
Copy link
Contributor

This PR adds support for meter and counter PSA extern in DPDK backend and a minor change to fix jump statements in action body.

DPDK target's requirements

  • Current PSA Meter extern API does not allow the user the specify a packet length, but DPDK target expects the packet length to come from the user. To handle this, Meter execute method API is customized to take an additional optional parameter for packet length.

PSA_MeterColor_t execute(in S index, in PSA_MeterColor_t color, @optional in bit<32> pkt_len);

  • Similarly, for PSA counter extern, packet length is required for PACKET counter. The Counter count method API is customized to take additional optional parameter for packet length.

void count(in S index, @optional in bit<32> increment);

  • DPDK target implements counter using register. Register declaration "regarray" instruction is used for counter declaration and atomic addition of registers "regadd" is used for counter incrementing. The packet counters are incremented by length specified by the user as argument to count method and byte counters are incremented by 1.

usha1830 added 28 commits April 22, 2021 00:28
1) Add missing regarray declarations
2) Fix read() method implementation
…n objects and methods in/from control blocks only
- Disabled Midend predication pass to allow conditional operator to be splitted into if-else statement
- Added a new test and reference output for conditional operator
: met_map(met_map) , typeMap(typeMap) {}

bool preorder(const IR::Declaration_Instance *d) override {
if (d->type->is<IR::Type_Specialized>()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these can be combined into a single line

if (d->type->is<IR::Type_Specialized>()) {
auto type = d->type->to<IR::Type_Specialized>();
auto externTypeName = type->baseType->path->name.name;
if (externTypeName == "Meter"){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no space after (

if (d->arguments->size() != 2) {
::error("%1%: expected number of meters and type of meter as arguments", d);
} else {
if (d->arguments->at(1) == 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really want to compare with 0? Not with IR::Constant(0)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you want to add a test for this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am facing an issue w.r.t adding a test for this case.

I added a test in testdata/p4_16_samples/ for emitting this warning and added the warning in reference stderr output "psa-example-dpdk-meter1.p4-stderr". This test compiles as expected and produces a warning when compiled with p4c-dpdk. However, make check fails while compiling this test using p4test. It fails because of output mismatch as there is no warning when compiling with p4test and reference stderr output has warning. What should I do in this case?

Copy link
Contributor

@mihaibudiu mihaibudiu Jun 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far the p4 reference outputs have always been produced by p4test.
Is the dpdk backend testing framework also saving reference outputs?
Ideally it should only save the .spec output. Then there should be no conflict: the .p4 and -stderr outputs come from p4test, and the .spec output from p4c-dpdk.
If both compilers produce reference outputs we have a second problem, since the test has an inherent data race. When we run tests on multiple cores one test could overwrite the reference outputs files of the other one while they are running. So this should not be done. The likelihood of this happening is low, since we have many tests, but it's not zero.
Finally, note that we have already this problem where a test should pass with p4test and fail with a specific backend which has more constraints. Then the solution is to list the test as xfail into the makefile of the backend where it is supposed to fail, with comments explaining why.

auto externTypeName = type->baseType->path->name.name;
if (externTypeName == "Counter"){
if (d->arguments->size() != 2 ) {
::error("%1%: expected n_counters and counter type as arguments", d);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this error message does not seem very clear to me.

class AddRegisterDeclaration : public PassManager {
/* This pass collects PSA counter declaration instances and push them to a map
* for emitting to the .spec file later */
class CollectCounterDeclaration : public Inspector {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you do both of them in a single traversal? There is a lot of common code.

e->object->getName());
const IR::Expression *color_in = nullptr;
const IR::Expression *length = nullptr;
auto index = (*e->expr->arguments)[0]->expression;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using arguments->at(0) is safer.

backends/dpdk/dpdkHelpers.cpp Show resolved Hide resolved
auto args = this->arguments;
unsigned value = 0;
if (args->size() < 2) {
::error ("Counter extern declaration %1% must contain 2 parameters\n", this->Name());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

your indentation is not consistent with our standard

@@ -0,0 +1,863 @@
/* Copyright 2013-present Barefoot Networks, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this psa.p4 different from the other one?
If not, does it have to be here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This is slightly different from the standard psa.p4 in p4include directory.

This psa.p4 extends the API for Meter execute and Counter count methods. A new optional parameter is added to both of these methods to take packet length/counter increment value as a parameter.

Meter extern's execute method:
PSA_MeterColor_t execute(in S index, in PSA_MeterColor_t color, @optional in bit<32> pkt_len);

Counter extern's count method
void count(in S index, @optional in bit<32> increment);

This API is required to meet DPDK target's requirements.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also refer to #2751 and #2818 PRs which proposes similar extensions to PSA

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this very confusing. The whole point of PSA is to be portable. If we have two different PSA.p4 I don't see how portability is helped. Only confusion can ensue.
We should find a resolution to the issues you cite before merging this file.
I would expect that extensions can be done by including psa.p4 and then additional libraries. But the externs in these libraries would have to have different names.
In the meantime we could perhaps use a different name for this file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the relation of this file and the one from #2818?

@usha1830
Copy link
Contributor Author

@mbudiu-vmw Thanks for the review. I will address rest of the comments and resubmit the changes.

@usha1830 usha1830 requested a review from mihaibudiu June 28, 2021 05:00
@usha1830
Copy link
Contributor Author

@mbudiu-vmw I have completed the requested changes. Could you please review it again?

  • Combined the extern declaration collection pass for Register, Counters and meters.
  • Added one more test for using multiple externs in same example.
  • Updated the dpdk test script to avoid saving error and P4 runtime outputs.

Regarding the customization of psa.p4, can we conclude on going with the proposed approach of having customized psa.p4 in target specific include directory (similar to #2818)?

Copy link
Contributor

@mihaibudiu mihaibudiu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am accepting this, but I still have a couple of questions. Please take a look.

new IR::DpdkMeterExecuteStatement(meter, index, color));
// DPDK target requires the result of meter execute method is assigned to a
// variable of PSA_MeterColor_t type.
::error(ErrorType::ERR_UNSUPPORTED, "LHS of meter execute statement is missing " \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no return here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, there is already a return just after the if-else chain.

@@ -0,0 +1,863 @@
/* Copyright 2013-present Barefoot Networks, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the relation of this file and the one from #2818?

@mihaibudiu mihaibudiu merged commit 64eb44d into p4lang:main Jun 29, 2021
@usha1830
Copy link
Contributor Author

What is the relation of this file and the one from #2818?

Both this PR and #2818 PR add the same new file "dpdk/psa.p4".

This new file is derived from the top-level psa.p4. This PR extends the top-level psa.p4 by modifying the signatures for Meter execute and Counter count methods.

The PR #2818 modifies the DPDK target data plane bit widths.

Both of these customized psa.p4 files should be merged.

@usha1830 usha1830 deleted the ushag/Meter_counter branch July 7, 2021 08:21
usha1830 added a commit to usha1830/p4c that referenced this pull request Aug 7, 2021
* DPDK backend: Add support for meter and counter PSA externs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants