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

ebpf/PSA: Support for wide fields in Register and Meter #3854

Merged
merged 2 commits into from
Jan 23, 2023

Conversation

tatry
Copy link
Contributor

@tatry tatry commented Jan 20, 2023

This commit allows to use Registers and Meters with fields wider than 64 bits.

CC: @osinstom

This commit allows to use Registers and Meters with fields wider than 64 bits.
@mihaibudiu
Copy link
Contributor

We could promote some of you to committers if you can review each other's code.

unsigned EBPFInitializerUtils::ebpfTypeWidth(P4::TypeMap *typeMap, const IR::Expression *expr) {
auto type = typeMap->getType(expr);
if (type == nullptr) type = expr->type;
if (type->is<IR::Type_InfInt>()) return 32; // let's assume 32 bit for int type
Copy link
Contributor

Choose a reason for hiding this comment

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

the only place where this can happen as far I know is in rhs of shifts.

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 can't recall where exactly hit the problem with this type.
For now I am able to make this statement true with slice, like field[127:64] (which is translated using bit shifts).

// 0x112233445566778890
// To correctly insert that padding, the length of field must be known, but tools like
// nikss-ctl (and the nikss library) don't consume P4info.txt to have such knowledge.
// There is also a bug in (de)parser causing that such fields aren't deparsed correctly.
Copy link
Contributor

Choose a reason for hiding this comment

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

causing such fields to be deparsed incorrectly.

// nikss-ctl (and the nikss library) don't consume P4info.txt to have such knowledge.
// There is also a bug in (de)parser causing that such fields aren't deparsed correctly.
::error(ErrorType::ERR_UNSUPPORTED_ON_TARGET,
"%1%: fields wider than 64 bits must have size in multiply of 8 bits (1 byte) "
Copy link
Contributor

Choose a reason for hiding this comment

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

a size multiple of 8 bits

@@ -293,6 +295,23 @@ void StateTranslationVisitor::compileExtractField(const IR::Expression *expr, cs
builder->append(")");
builder->endOfStatement(true);
} else {
if (program->options.arch == "psa" && widthToExtract % 8 != 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

yes, in my implementation I never figured out how all this stuff should be handled.

@@ -619,7 +619,8 @@ table caching pass `--table-caching` to the compiler.

We list the known bugs/limitations below. Refer to the Roadmap section for features planned in the near future.

- Larger bit fields (e.g. IPv6 addresses) may not work properly.
- Fields wider than 64 bits must have size multiply of 8 bits, otherwise they may have unexpected value in the LSB byte.
Copy link
Contributor

Choose a reason for hiding this comment

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

multiple

initialValue != nullptr ? initialValue : new IR::Constant(leftExpression->type, 0);
const auto *assigment = new IR::AssignmentStatement(leftExpression, right);
ControlBodyTranslatorPSA cg(*translator);
assigment->apply(cg);
Copy link
Contributor

Choose a reason for hiding this comment

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

does this work?
For example, the typemap won't always have a type for the right.
In general, it would be nice to do this in a separate pass before code generation.

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 think it should works (PTF tests are passing, especially register.RegisterDefaultPSATest).
If the initial value is defined for register, then type map contains type for right - because of expression generated by frontend.
If the initial value is not defined, type map does not contain type for right, but type is copied from left. For this case exist this line:

if (type == nullptr) type = expr->type;

Maybe it is not the best way, but is there any reason to not to use expression->type?

Copy link
Contributor

Choose a reason for hiding this comment

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

Expression->type is only populated if you run the type inference with a flag indicating that you want this.
Some simple expressions like constants may have the type correct, though.
If it works, let's leave it like this.

@mihaibudiu
Copy link
Contributor

Approved, but you may want to make a few changes.

@mihaibudiu mihaibudiu merged commit 383af99 into p4lang:main Jan 23, 2023
@osinstom
Copy link
Contributor

We could promote some of you to committers if you can review each other's code.

hey @mbudiu-vmw, I think it'd make sense to promote me and @tatry, so that we can review the code - especially related to eBPF backend.

@mihaibudiu
Copy link
Contributor

@jnfoster I have tried to add them to the list of committers, but I don't seem to be able to.
First they seem to need to be part of the p4lang org, and I can't edit that list.

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.

3 participants