Skip to content

Commit

Permalink
Support of Digest extern in P4TC (#4842)
Browse files Browse the repository at this point in the history
Signed-off-by: Y <komal.jain@intel.com>
  • Loading branch information
komaljai authored Aug 7, 2024
1 parent 95e590e commit c338851
Show file tree
Hide file tree
Showing 24 changed files with 2,016 additions and 143 deletions.
8 changes: 4 additions & 4 deletions backends/ebpf/psa/externs/ebpfPsaDigest.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,24 @@ class EBPFDigestPSA : public EBPFObject {
private:
cstring instanceName;
const EBPFProgram *program;
EBPFType *valueType;
cstring valueTypeName;
const IR::Declaration_Instance *declaration;
/// arbitrary value for max queue size
/// TODO: make it configurable
int maxDigestQueueSize = 128;

public:
EBPFType *valueType;
EBPFDigestPSA(const EBPFProgram *program, const IR::Declaration_Instance *di);

void emitTypes(CodeBuilder *builder);
void emitInstance(CodeBuilder *builder) const;
void processMethod(CodeBuilder *builder, cstring method, const IR::MethodCallExpression *expr,
DeparserBodyTranslatorPSA *visitor);

void emitPushElement(CodeBuilder *builder, const IR::Expression *elem,
Inspector *codegen) const;
void emitPushElement(CodeBuilder *builder, cstring elem) const;
virtual void emitPushElement(CodeBuilder *builder, const IR::Expression *elem,
Inspector *codegen) const;
virtual void emitPushElement(CodeBuilder *builder, cstring elem) const;
};

} // namespace EBPF
Expand Down
39 changes: 30 additions & 9 deletions backends/tc/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,8 @@ safe_vector<const IR::TCKey *> ConvertToBackendIR::processExternConstructor(
} else {
/* If a parameter is not annoated by tc_init or tc_numel then it is emitted as
constructor parameters.*/
IR::TCKey *key = new IR::TCKey(0, parameter->type->width_bits(),
cstring ptype = absl::StrCat("bit", parameter->type->width_bits());
IR::TCKey *key = new IR::TCKey(0, parameter->type->width_bits(), ptype,
parameter->toString(), "param"_cs, false);
keys.push_back(key);
if (exp->is<IR::Constant>()) {
Expand Down Expand Up @@ -910,8 +911,9 @@ safe_vector<const IR::TCKey *> ConvertToBackendIR::processCounterControlPathKeys
auto temp_keys = HandleTypeNameStructField(field, extn, decl, kId, annoName);
keys.insert(keys.end(), temp_keys.begin(), temp_keys.end());
} else {
IR::TCKey *key =
new IR::TCKey(kId++, field->type->width_bits(), field->toString(), annoName, true);
cstring ptype = absl::StrCat("bit", field->type->width_bits());
IR::TCKey *key = new IR::TCKey(kId++, field->type->width_bits(), ptype,
field->toString(), annoName, true);
keys.push_back(key);
}
}
Expand Down Expand Up @@ -942,8 +944,9 @@ safe_vector<const IR::TCKey *> ConvertToBackendIR::processExternControlPath(
auto temp_keys = HandleTypeNameStructField(field, extn, decl, kId, annoName);
keys.insert(keys.end(), temp_keys.begin(), temp_keys.end());
} else {
IR::TCKey *key = new IR::TCKey(kId++, field->type->width_bits(), field->toString(),
annoName, true);
cstring ptype = absl::StrCat("bit", field->type->width_bits());
IR::TCKey *key = new IR::TCKey(kId++, field->type->width_bits(), ptype,
field->toString(), annoName, true);
keys.push_back(key);
}
}
Expand All @@ -965,13 +968,27 @@ safe_vector<const IR::TCKey *> ConvertToBackendIR::HandleTypeNameStructField(
/* If 'T' is of Type_Struct, extract all fields of structure*/
if (auto param_struct = param_val->to<IR::Type_Struct>()) {
for (auto f : param_struct->fields) {
IR::TCKey *key =
new IR::TCKey(kId++, f->type->width_bits(), f->toString(), annoName, true);
cstring ptype = absl::StrCat("bit", f->type->width_bits());
if (auto anno = f->getAnnotations()->getSingle(ParseTCAnnotations::tcType)) {
auto expr = anno->expr[0];
if (auto typeLiteral = expr->to<IR::StringLiteral>()) {
ptype = typeLiteral->value;
}
}
IR::TCKey *key = new IR::TCKey(kId++, f->type->width_bits(), ptype,
f->toString(), annoName, true);
keys.push_back(key);
}
} else {
IR::TCKey *key = new IR::TCKey(kId++, param_val->width_bits(), field->toString(),
annoName, true);
cstring ptype = absl::StrCat("bit", param_val->width_bits());
if (auto anno = field->getAnnotations()->getSingle(ParseTCAnnotations::tcType)) {
auto expr = anno->expr[0];
if (auto typeLiteral = expr->to<IR::StringLiteral>()) {
ptype = typeLiteral->value;
}
}
IR::TCKey *key = new IR::TCKey(kId++, param_val->width_bits(), ptype,
field->toString(), annoName, true);
keys.push_back(key);
}
break;
Expand Down Expand Up @@ -1025,6 +1042,10 @@ void ConvertToBackendIR::postorder(const IR::Declaration_Instance *decl) {
eb->externId = "0x1A000000"_cs;
} else if (eName == "Counter") {
eb->externId = "0x19000000"_cs;
} else if (eName == "Digest") {
eb->externId = "0x05000000"_cs;
instance->is_num_elements = true;
instance->num_elements = 0;
} else {
externCount += 1;
std::stringstream value;
Expand Down
8 changes: 4 additions & 4 deletions backends/tc/ebpfCodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ void PNAEbpfGenerator::emitP4TCActionParam(EBPF::CodeBuilder *builder) const {

void PNAEbpfGenerator::emitPipelineInstances(EBPF::CodeBuilder *builder) const {
pipeline->parser->emitValueSetInstances(builder);
pipeline->deparser->emitDigestInstances(builder);

builder->target->emitTableDecl(builder, "hdr_md_cpumap"_cs, EBPF::TablePerCPUArray, "u32"_cs,
"struct hdr_md"_cs, 2);
Expand Down Expand Up @@ -1185,7 +1184,7 @@ void IngressDeparserPNA::emitPreDeparser(EBPF::CodeBuilder *builder) {

void IngressDeparserPNA::emit(EBPF::CodeBuilder *builder) {
codeGen->setBuilder(builder);

emitExternDefinition(builder);
for (auto a : controlBlock->container->controlLocals) {
if (a->is<IR::Declaration_Variable>()) {
auto vd = a->to<IR::Declaration_Variable>();
Expand Down Expand Up @@ -1324,7 +1323,7 @@ bool ConvertToEbpfPipelineTC::preorder(const IR::PackageBlock *block) {
CHECK_NULL(pipeline->control);

auto deparser_converter = new ConvertToEBPFDeparserPNA(
pipeline, pipeline->parser->headers, pipeline->control->outputStandardMetadata);
pipeline, pipeline->parser->headers, pipeline->control->outputStandardMetadata, tcIR);
deparserBlock->apply(*deparser_converter);
pipeline->deparser = deparser_converter->getEBPFDeparser();
CHECK_NULL(pipeline->deparser);
Expand Down Expand Up @@ -1516,8 +1515,9 @@ bool ConvertToEBPFDeparserPNA::preorder(const IR::Declaration_Instance *di) {
auto baseType = typeSpec->baseType;
auto typeName = baseType->to<IR::Type_Name>()->path->name.name;
if (typeName == "Digest") {
deparser->addExternDeclaration = true;
cstring instance = EBPF::EBPFObject::externalName(di);
auto digest = new EBPF::EBPFDigestPSA(program, di);
auto digest = new EBPFDigestPNA(program, di, typeName, tcIR);
deparser->digests.emplace(instance, digest);
}
}
Expand Down
16 changes: 14 additions & 2 deletions backends/tc/ebpfCodeGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,18 @@ class IngressDeparserPNA : public EBPF::EBPFDeparserPSA {
const IR::Parameter *parserHeaders, const IR::Parameter *istd)
: EBPF::EBPFDeparserPSA(program, control, parserHeaders, istd) {}

bool addExternDeclaration = false;
bool build() override;
void emit(EBPF::CodeBuilder *builder) override;
void emitPreDeparser(EBPF::CodeBuilder *builder) override;
void emitDeclaration(EBPF::CodeBuilder *builder, const IR::Declaration *decl) override;

void emitExternDefinition(EBPF::CodeBuilder *builder) {
if (addExternDeclaration) {
builder->emitIndent();
builder->appendLine("struct p4tc_ext_bpf_params ext_params = {};");
}
}
DECLARE_TYPEINFO(IngressDeparserPNA, EBPF::EBPFDeparserPSA);
};

Expand Down Expand Up @@ -329,12 +336,17 @@ class ConvertToEBPFDeparserPNA : public Inspector {
EBPF::EBPFProgram *program;
const IR::Parameter *parserHeaders;
const IR::Parameter *istd;
const ConvertToBackendIR *tcIR;
TC::IngressDeparserPNA *deparser;

public:
ConvertToEBPFDeparserPNA(EBPF::EBPFProgram *program, const IR::Parameter *parserHeaders,
const IR::Parameter *istd)
: program(program), parserHeaders(parserHeaders), istd(istd), deparser(nullptr) {}
const IR::Parameter *istd, const ConvertToBackendIR *tcIR)
: program(program),
parserHeaders(parserHeaders),
istd(istd),
tcIR(tcIR),
deparser(nullptr) {}

bool preorder(const IR::ControlBlock *) override;
bool preorder(const IR::Declaration_Instance *) override;
Expand Down
2 changes: 1 addition & 1 deletion backends/tc/introspection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ void IntrospectionGenerator::collectExternInfo() {
keyField->id = control_field->keyID;
keyField->name = control_field->keyName;
keyField->attribute = control_field->keyAttribute;
keyField->type = "bit" + Util::toString(control_field->bitwidth);
keyField->type = control_field->type;
keyField->bitwidth = control_field->bitwidth;
externInstanceInfo->keyFields.push_back(keyField);
}
Expand Down
8 changes: 8 additions & 0 deletions backends/tc/runtime/pna.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,14 @@ extern int xdp_p4tc_extern_md_write(struct xdp_md *xdp_ctx,
struct p4tc_ext_bpf_val *val,
const u32 val__sz) __ksym;

int bpf_p4tc_extern_digest_pack(struct __sk_buff *skb,
struct p4tc_ext_bpf_params *params,
const u32 params__sz) __ksym;

int xdp_p4tc_extern_digest_pack(struct xdp_md *xdp_ctx,
struct p4tc_ext_bpf_params *params,
const u32 params__sz) __ksym;

/* Timestamp PNA extern */
static inline u64 bpf_p4tc_extern_timestamp() {
return bpf_ktime_get_ns();
Expand Down
Loading

0 comments on commit c338851

Please sign in to comment.