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: Fix core dump while generating bfrt json for PNA programs with action selector #3115

Merged
merged 5 commits into from
Mar 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 41 additions & 13 deletions backends/dpdk/control-plane/bfruntime_arch_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ struct ActionSelector {
}
};

class BFRuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PSA> {
template <Arch arch>
class BFRuntimeArchHandler : public P4RuntimeArchHandlerCommon<arch> {
protected:
std::unordered_map<const IR::Block *, cstring> blockNamePrefixMap;

public:
Expand All @@ -109,19 +111,19 @@ class BFRuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS
}
}

using ArchCounterExtern = CounterExtern<Arch::PSA>;
using ArchCounterExtern = CounterExtern<arch>;
using CounterTraits = Helpers::CounterlikeTraits<ArchCounterExtern>;
using ArchMeterExtern = MeterExtern<Arch::PSA>;
using ArchMeterExtern = MeterExtern<arch>;
using MeterTraits = Helpers::CounterlikeTraits<ArchMeterExtern>;

using Counter = p4configv1::Counter;
using Meter = p4configv1::Meter;
using CounterSpec = p4configv1::CounterSpec;
using MeterSpec = p4configv1::MeterSpec;

BFRuntimeArchHandlerPSA(ReferenceMap* refMap, TypeMap* typeMap,
BFRuntimeArchHandler(ReferenceMap* refMap, TypeMap* typeMap,
const IR::ToplevelBlock* evaluatedProgram)
: P4RuntimeArchHandlerCommon<Arch::PSA>(refMap, typeMap, evaluatedProgram) {
: P4RuntimeArchHandlerCommon<arch>(refMap, typeMap, evaluatedProgram) {
// Create a map of all blocks to their pipe names. This map will
// be used during collect and post processing to prefix
// table/extern instances wherever applicable with a fully qualified
Expand Down Expand Up @@ -194,8 +196,8 @@ class BFRuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS
selector.set_num_groups(actionSelector.numGroups);
p4configv1::ActionProfile profile;
profile.set_size(actionSelector.size);
auto tablesIt = actionProfilesRefs.find(actionSelector.name);
if (tablesIt != actionProfilesRefs.end()) {
auto tablesIt = this->actionProfilesRefs.find(actionSelector.name);
if (tablesIt != this->actionProfilesRefs.end()) {
for (const auto& table : tablesIt->second) {
profile.add_table_ids(symbols.getId(P4RuntimeSymbolType::TABLE(), table));
selector.add_table_ids(symbols.getId(P4RuntimeSymbolType::TABLE(), table));
Expand All @@ -214,13 +216,13 @@ class BFRuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS

void collectExternInstance(P4RuntimeSymbolTableIface* symbols,
const IR::ExternBlock* externBlock) override {
P4RuntimeArchHandlerCommon<Arch::PSA>::collectExternInstance(symbols, externBlock);
P4RuntimeArchHandlerCommon<arch>::collectExternInstance(symbols, externBlock);

auto decl = externBlock->node->to<IR::IDeclaration>();
if (decl == nullptr) return;
if (externBlock->type->name == "Digest") {
symbols->add(SymbolType::DIGEST(), decl);
} else if (externBlock->type->name == ActionSelectorTraits<Arch::PSA>::typeName()) {
} else if (externBlock->type->name == ActionSelectorTraits<arch>::typeName()) {
auto selName = decl->controlPlaneName() + "_sel";
auto profName = decl->controlPlaneName();
symbols->add(SymbolTypeDPDK::ACTION_SELECTOR(), selName);
Expand All @@ -232,7 +234,7 @@ class BFRuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS
p4configv1::P4Info* p4info,
p4configv1::Table* table,
const IR::TableBlock* tableBlock) override {
P4RuntimeArchHandlerCommon<Arch::PSA>::addTableProperties(
P4RuntimeArchHandlerCommon<arch>::addTableProperties(
symbols, p4info, table, tableBlock);

auto tableDeclaration = tableBlock->container;
Expand All @@ -253,7 +255,7 @@ class BFRuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS
void addExternInstance(const P4RuntimeSymbolTableIface& symbols,
p4configv1::P4Info* p4info,
const IR::ExternBlock* externBlock) override {
P4RuntimeArchHandlerCommon<Arch::PSA>::addExternInstance(
P4RuntimeArchHandlerCommon<arch>::addExternInstance(
symbols, p4info, externBlock);

auto decl = externBlock->node->to<IR::Declaration_Instance>();
Expand All @@ -266,7 +268,7 @@ class BFRuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS
auto p4RtTypeInfo = p4info->mutable_type_info();
if (externBlock->type->name == "Digest") {
auto digest = getDigest(decl, p4RtTypeInfo);
if (digest) addDigest(symbols, p4info, *digest);
if (digest) this->addDigest(symbols, p4info, *digest);
} else if (externBlock->type->name == "ActionSelector") {
auto actionSelector = getActionSelector(externBlock);
if (actionSelector) addActionSelector(symbols, p4info, *actionSelector, pipeName);
Expand Down Expand Up @@ -312,7 +314,8 @@ class BFRuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS
auto type = decl->type->to<IR::Type_Specialized>();
BUG_CHECK(type->arguments->size() == 1, "%1%: expected one type argument", decl);
auto typeArg = type->arguments->at(0);
auto typeSpec = TypeSpecConverter::convert(refMap, typeMap, typeArg, p4RtTypeInfo);
auto typeSpec = TypeSpecConverter::convert(this->refMap, this->typeMap,
typeArg, p4RtTypeInfo);
BUG_CHECK(typeSpec != nullptr,
"P4 type %1% could not be converted to P4Info P4DataTypeSpec");

Expand Down Expand Up @@ -352,6 +355,20 @@ class BFRuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS
}
};

class BFRuntimeArchHandlerPSA final : public BFRuntimeArchHandler<Arch::PSA> {
public:
BFRuntimeArchHandlerPSA(ReferenceMap* refMap, TypeMap* typeMap,
const IR::ToplevelBlock* evaluatedProgram)
: BFRuntimeArchHandler(refMap, typeMap, evaluatedProgram) {}
};

class BFRuntimeArchHandlerPNA final : public BFRuntimeArchHandler<Arch::PNA> {
public:
BFRuntimeArchHandlerPNA(ReferenceMap* refMap, TypeMap* typeMap,
const IR::ToplevelBlock* evaluatedProgram)
: BFRuntimeArchHandler(refMap, typeMap, evaluatedProgram) {}
};

/// The architecture handler builder implementation for PSA.
struct PSAArchHandlerBuilderForDPDK : public P4::ControlPlaneAPI::P4RuntimeArchHandlerBuilderIface {
P4::ControlPlaneAPI::P4RuntimeArchHandlerIface* operator()(
Expand All @@ -363,6 +380,17 @@ struct PSAArchHandlerBuilderForDPDK : public P4::ControlPlaneAPI::P4RuntimeArchH
}
};

/// The architecture handler builder implementation for PNA.
struct PNAArchHandlerBuilderForDPDK : public P4::ControlPlaneAPI::P4RuntimeArchHandlerBuilderIface {
P4::ControlPlaneAPI::P4RuntimeArchHandlerIface* operator()(
ReferenceMap* refMap,
TypeMap* typeMap,
const IR::ToplevelBlock* evaluatedProgram) const override {
return new P4::ControlPlaneAPI::Standard::BFRuntimeArchHandlerPNA(refMap, typeMap,
evaluatedProgram);
}
};

} // namespace Standard

} // namespace ControlPlaneAPI
Expand Down
2 changes: 1 addition & 1 deletion backends/dpdk/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ int main(int argc, char *const argv[]) {
new P4::ControlPlaneAPI::Standard::PSAArchHandlerBuilderForDPDK());
if (options.arch == "pna")
p4RuntimeSerializer->registerArch("pna",
new P4::ControlPlaneAPI::Standard::PSAArchHandlerBuilderForDPDK());
new P4::ControlPlaneAPI::Standard::PNAArchHandlerBuilderForDPDK());
auto p4Runtime = P4::generateP4Runtime(program, options.arch);
auto p4rt = new P4::BFRT::BFRuntimeSchemaGenerator(*p4Runtime.p4Info);
std::ostream* out = openFile(options.bfRtSchema, false);
Expand Down
3 changes: 3 additions & 0 deletions backends/dpdk/run-dpdk-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ def process_file(options, argv):
bfRtSchemaFile = os.path.join(tmpdir, basename + ".bfrt.json")
def getArch(path):
v1Pattern = re.compile('include.*v1model\.p4')
pnaPattern = re.compile('include.*pna\.p4')
psaPattern = re.compile('include.*psa\.p4')
ubpfPattern = re.compile('include.*ubpf_model\.p4')
with open(path, 'r', encoding='utf-8') as f:
Expand All @@ -202,6 +203,8 @@ def getArch(path):
return "v1model"
elif psaPattern.search(line):
return "psa"
elif pnaPattern.search(line):
return "pna"
elif ubpfPattern.search(line):
return "ubpf"
return None
Expand Down
39 changes: 25 additions & 14 deletions control-plane/p4RuntimeArchStandard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,19 +161,21 @@ V1ModelArchHandlerBuilder::operator()(
return new P4RuntimeArchHandlerV1Model(refMap, typeMap, evaluatedProgram);
}

/// Implements @ref P4RuntimeArchHandlerIface for the PSA architecture. The
/// Implements a common @ref P4RuntimeArchHandlerIface for the PSA and PNA architecture. The
/// overridden methods will be called by the @P4RuntimeSerializer to collect and
/// serialize PSA-specific symbols which are exposed to the control-plane.
class P4RuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PSA> {
/// serialize PSA and PNA specific symbols which are exposed to the control-plane.
template <Arch arch>
class P4RuntimeArchHandlerPSAPNA : public P4RuntimeArchHandlerCommon<arch> {
public:
P4RuntimeArchHandlerPSA(ReferenceMap* refMap,
P4RuntimeArchHandlerPSAPNA(ReferenceMap* refMap,
TypeMap* typeMap,
const IR::ToplevelBlock* evaluatedProgram)
: P4RuntimeArchHandlerCommon<Arch::PSA>(refMap, typeMap, evaluatedProgram) { }
: P4RuntimeArchHandlerCommon<arch>(refMap, typeMap, evaluatedProgram) {
}

void collectExternInstance(P4RuntimeSymbolTableIface* symbols,
const IR::ExternBlock* externBlock) override {
P4RuntimeArchHandlerCommon<Arch::PSA>::collectExternInstance(symbols, externBlock);
P4RuntimeArchHandlerCommon<arch>::collectExternInstance(symbols, externBlock);

auto decl = externBlock->node->to<IR::IDeclaration>();
if (decl == nullptr) return;
Expand All @@ -186,7 +188,7 @@ class P4RuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS
p4configv1::P4Info* p4info,
p4configv1::Table* table,
const IR::TableBlock* tableBlock) override {
P4RuntimeArchHandlerCommon<Arch::PSA>::addTableProperties(
P4RuntimeArchHandlerCommon<arch>::addTableProperties(
symbols, p4info, table, tableBlock);

auto tableDeclaration = tableBlock->container;
Expand All @@ -201,15 +203,15 @@ class P4RuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS
void addExternInstance(const P4RuntimeSymbolTableIface& symbols,
p4configv1::P4Info* p4info,
const IR::ExternBlock* externBlock) override {
P4RuntimeArchHandlerCommon<Arch::PSA>::addExternInstance(
P4RuntimeArchHandlerCommon<arch>::addExternInstance(
symbols, p4info, externBlock);

auto decl = externBlock->node->to<IR::Declaration_Instance>();
if (decl == nullptr) return;
auto p4RtTypeInfo = p4info->mutable_type_info();
if (externBlock->type->name == "Digest") {
auto digest = getDigest(decl, p4RtTypeInfo);
if (digest) addDigest(symbols, p4info, *digest);
if (digest) this->addDigest(symbols, p4info, *digest);
}
}

Expand All @@ -221,7 +223,8 @@ class P4RuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS
auto type = decl->type->to<IR::Type_Specialized>();
BUG_CHECK(type->arguments->size() == 1, "%1%: expected one type argument", decl);
auto typeArg = type->arguments->at(0);
auto typeSpec = TypeSpecConverter::convert(refMap, typeMap, typeArg, p4RtTypeInfo);
auto typeSpec = TypeSpecConverter::convert(this->refMap, this->typeMap,
typeArg, p4RtTypeInfo);
BUG_CHECK(typeSpec != nullptr,
"P4 type %1% could not be converted to P4Info P4DataTypeSpec");

Expand Down Expand Up @@ -261,20 +264,28 @@ class P4RuntimeArchHandlerPSA final : public P4RuntimeArchHandlerCommon<Arch::PS
}
};

class P4RuntimeArchHandlerPSA final : public P4RuntimeArchHandlerPSAPNA<Arch::PSA> {
public:
P4RuntimeArchHandlerPSA(ReferenceMap* refMap,
TypeMap* typeMap,
const IR::ToplevelBlock* evaluatedProgram)
: P4RuntimeArchHandlerPSAPNA(refMap, typeMap, evaluatedProgram) {
}
};

P4RuntimeArchHandlerIface*
PSAArchHandlerBuilder::operator()(
ReferenceMap* refMap, TypeMap* typeMap, const IR::ToplevelBlock* evaluatedProgram) const {
return new P4RuntimeArchHandlerPSA(refMap, typeMap, evaluatedProgram);
}

/// Implements @ref P4RuntimeArchHandlerIface for the PNA architecture.
/// We re-use PSA to handle externs as most of the PSA externs are available for PNA as well.
class P4RuntimeArchHandlerPNA final : public P4RuntimeArchHandlerCommon<Arch::PSA> {
class P4RuntimeArchHandlerPNA final : public P4RuntimeArchHandlerPSAPNA<Arch::PNA> {
public:
P4RuntimeArchHandlerPNA(ReferenceMap* refMap,
TypeMap* typeMap,
const IR::ToplevelBlock* evaluatedProgram)
: P4RuntimeArchHandlerCommon<Arch::PSA>(refMap, typeMap, evaluatedProgram) { }
: P4RuntimeArchHandlerPSAPNA(refMap, typeMap, evaluatedProgram) {
}
};

P4RuntimeArchHandlerIface*
Expand Down
Loading