Skip to content

Commit

Permalink
Do not generate TC Egress program if PSA Egress pipeline is empty (p4…
Browse files Browse the repository at this point in the history
…lang#3349)

* Do not generate TC Egress program if PSA Egress pipeline is empty
  • Loading branch information
osinstom authored and github-sajan committed May 26, 2022
1 parent c977d5c commit b757ea9
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 2 deletions.
3 changes: 2 additions & 1 deletion backends/ebpf/psa/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ The TC-based design of PSA for eBPF is depicted in Figure below.
The role of Traffic Manager is to redirect traffic between the Ingress (TC) and Egress (TC).
It is also responsible for packet replication via clone sessions or multicast groups and sending packet to CPU.
- `tc-egress` - The PSA Egress pipeline (composed of Parser, Control block and Deparser) is attached to the TC Egress hook. As there is no
XDP hook in the Egress path, the use of TC is mandatory for the egress processing.
XDP hook in the Egress path, the use of TC is mandatory for the egress processing. **Note!** If the PSA Egress pipeline is not used (i.e. it is left empty by a developer),
the PSA-eBPF compiler will not generate the TC Egress program. This brings a noticeable performance gain, if the egress pipeline is not used.

## Packet paths

Expand Down
26 changes: 26 additions & 0 deletions backends/ebpf/psa/ebpfPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,32 @@ limitations under the License.

namespace EBPF {

bool EBPFPipeline::isEmpty() const {
// check if parser doesn't have any state
// Why 3? Parser will always have at least start, accept and reject states.
if (parser->parserBlock->container->states.size() > 3) {
return false;
}

auto startState = parser->parserBlock->container->states.at(0);
auto pathExpr = startState->selectExpression->to<IR::PathExpression>()->path;
if (!startState->components.empty() || pathExpr->name.name != IR::ParserState::accept) {
return false;
}

// check if control is empty
if (!control->controlBlock->container->body->components.empty()) {
return false;
}

// check if deparser doesn't emit anything
if (!deparser->controlBlock->container->body->components.empty()) {
return false;
}

return true;
}

void EBPFPipeline::emitLocalVariables(CodeBuilder* builder) {
builder->emitIndent();
builder->appendFormat("unsigned %s = 0;", offsetVar.c_str());
Expand Down
4 changes: 4 additions & 0 deletions backends/ebpf/psa/ebpfPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ class EBPFPipeline : public EBPFProgram {
oneKey = EBPFModel::reserved("one");
}

/* Check if pipeline does any processing.
* Return false if not. */
bool isEmpty() const;

virtual cstring dropReturnCode() {
if (sectionName.startsWith("xdp")) {
return "XDP_DROP";
Expand Down
5 changes: 4 additions & 1 deletion backends/ebpf/psa/ebpfPsaGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,10 @@ void PSAArchTC::emit(CodeBuilder *builder) const {
/*
* 10. TC Egress program.
*/
egress->emit(builder);
if (!egress->isEmpty()) {
// Do not generate TC Egress program if PSA egress pipeline is not used (empty).
egress->emit(builder);
}

builder->target->emitLicense(builder, ingress->license);
}
Expand Down

0 comments on commit b757ea9

Please sign in to comment.