Skip to content

Commit

Permalink
[dpdk] Shorten the Identifer name, including dots(.) in Member expres…
Browse files Browse the repository at this point in the history
…sion

to be less than 64 because dpdk does not allow Identifer longer than 63 chars
  • Loading branch information
kamleshbhalui committed Apr 6, 2022
1 parent 40fe352 commit e03d7d6
Show file tree
Hide file tree
Showing 18 changed files with 925 additions and 41 deletions.
4 changes: 2 additions & 2 deletions backends/dpdk/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ void DpdkBackend::convert(const IR::ToplevelBlock *tlb) {
new DpdkAsmOptimization,
new CollectUsedMetadataField(used_fields),
new RemoveUnusedMetadataFields(used_fields),
new ValidateTableKeys()
new ValidateTableKeys(),
new ShortenTokenLength(IR::IDPDKNode::origNameMap),
};

dpdk_program = dpdk_program->apply(post_code_gen)->to<IR::DpdkAsmProgram>();
Expand All @@ -136,5 +137,4 @@ void DpdkBackend::convert(const IR::ToplevelBlock *tlb) {
void DpdkBackend::codegen(std::ostream &out) const {
dpdk_program->toSpec(out) << std::endl;
}

} // namespace DPDK
5 changes: 3 additions & 2 deletions backends/dpdk/dpdk.def
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
interface IDPDKNode {
virtual std::ostream& toSpec(std::ostream& out) const = 0;
static ordered_map<cstring, cstring> origNameMap;
}

class DpdkDeclaration : IDPDKNode {
Expand Down Expand Up @@ -50,8 +51,8 @@ class DpdkTable {

class DpdkSelector {
inline cstring name;
inline cstring group_id;
inline cstring member_id;
Expression group_id;
Expression member_id;
Key selectors;
int n_groups_max;
int n_members_per_group_max;
Expand Down
3 changes: 3 additions & 0 deletions backends/dpdk/dpdkAsmOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,4 +279,7 @@ bool ValidateTableKeys::preorder(const IR::DpdkAsmProgram *p) {
}
return false;
}

size_t ShortenTokenLength::count = 0;

} // namespace DPDK
119 changes: 119 additions & 0 deletions backends/dpdk/dpdkAsmOpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,125 @@ class ValidateTableKeys : public Inspector {
int getFieldSizeBits(const IR::Type *field_type);
};

// This pass shorten the Identifier length
class ShortenTokenLength : public Transform {
ordered_map<cstring, cstring> newNameMap;
ordered_map<cstring, cstring> &origNameMap;
static size_t count;
// Currently Dpdk allows Identifier of 63 char long or less
// including dots(.) for member exp.
// worst case member expression will look like below(for headers)
// 1.30.30 => 63(including dot(.))
// if id name less than allowedLength keep it same
cstring shortenString(cstring str, size_t allowedLength = 60) {
if (str.size() <= allowedLength)
return str;
auto itr = newNameMap.find(str);
if (itr != newNameMap.end())
return itr->second;
// make sure new string length less or equal allowedLength
cstring newStr = str.substr(0, allowedLength - std::to_string(count).size());
newStr += std::to_string(count);
count++;
newNameMap.insert(std::pair<cstring, cstring>(str, newStr));
origNameMap.insert(std::pair<cstring, cstring>(newStr, str));
return newStr;
}

public:
explicit ShortenTokenLength(ordered_map<cstring, cstring> &origNameMap)
: origNameMap{origNameMap} {}
const IR::Node* preorder(IR::Member *m) override {
if (m->toString().startsWith("m."))
m->member = shortenString(m->member);
else
m->member = shortenString(m->member, 30);
return m;
}

const IR::Node* preorder(IR::DpdkStructType *s) override {
if (s->getAnnotations()->getSingle("__packet_data__")) {
s->name = shortenString(s->name);
IR::IndexedVector<IR::StructField> changedFields;
for (auto field : s->fields) {
IR::StructField *f = new IR::StructField(field->name, field->type);
f->name = shortenString(f->name, 30);
changedFields.push_back(f);
}
return new IR::DpdkStructType(s->srcInfo, s->name,
s->annotations, changedFields);
} else {
s->name = shortenString(s->name);
IR::IndexedVector<IR::StructField> changedFields;
for (auto field : s->fields) {
IR::StructField *f = new IR::StructField(field->name, field->type);
f->name = shortenString(f->name);
changedFields.push_back(f);
}
return new IR::DpdkStructType(s->srcInfo, s->name,
s->annotations, changedFields);
}
return s;
}

const IR::Node* preorder(IR::DpdkHeaderType *h) override {
h->name = shortenString(h->name, 30);
IR::IndexedVector<IR::StructField> changedFields;
for (auto field : h->fields) {
IR::StructField *f = new IR::StructField(field->name, field->type);
f->name = shortenString(f->name, 30);
changedFields.push_back(f);
}
return new IR::DpdkHeaderType(h->srcInfo, h->name,
h->annotations, changedFields);
}

const IR::Node* preorder(IR::DpdkExternDeclaration *e) override {
e->name = shortenString(e->name);
return e;
}

const IR::Node* preorder(IR::Declaration *g) override {
g->name = shortenString(g->name);
return g;
}

const IR::Node* preorder(IR::Path *p) override {
p->name = shortenString(p->name);
return p;
}

const IR::Node* preorder(IR::DpdkAction *a) override {
a->name = shortenString(a->name);
return a;
}

const IR::Node* preorder(IR::DpdkTable *t) override {
t->name = shortenString(t->name);
return t;
}

const IR::Node* preorder(IR::DpdkLearner *l) override {
l->name = shortenString(l->name);
return l;
}

const IR::Node* preorder(IR::DpdkSelector *s) override {
s->name = shortenString(s->name);
return s;
}

const IR::Node* preorder(IR::DpdkLearnStatement *ls) override{
ls->action = shortenString(ls->action);
return ls;
}

const IR::Node* preorder(IR::DpdkApplyStatement *as) override{
as->table = shortenString(as->table);
return as;
}
};

// Instructions can only appear in actions and apply block of .spec file.
// All these individual passes work on the actions and apply block of .spec file.
class DpdkAsmOptimization : public PassRepeated {
Expand Down
11 changes: 6 additions & 5 deletions backends/dpdk/dpdkProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,8 @@ bool ConvertToDpdkControl::checkTableValid(const IR::P4Table *a) {
return true;
}

boost::optional<cstring> ConvertToDpdkControl::getIdFromProperty(const IR::P4Table* table,
boost::optional<const IR::Member*>
ConvertToDpdkControl::getMemExprFromProperty(const IR::P4Table* table,
cstring propertyName) {
auto property = table->properties->getProperty(propertyName);
if (property == nullptr) return boost::none;
Expand All @@ -577,7 +578,7 @@ boost::optional<cstring> ConvertToDpdkControl::getIdFromProperty(const IR::P4Tab
return boost::none;
}

return expr->to<IR::Member>()->toString();
return expr->to<IR::Member>();
}

boost::optional<int> ConvertToDpdkControl::getNumberFromProperty(const IR::P4Table* table,
Expand Down Expand Up @@ -607,8 +608,8 @@ bool ConvertToDpdkControl::preorder(const IR::P4Table *t) {
return false;

if (t->properties->getProperty("selector") != nullptr) {
auto group_id = getIdFromProperty(t, "group_id");
auto member_id = getIdFromProperty(t, "member_id");
auto group_id = getMemExprFromProperty(t, "group_id");
auto member_id = getMemExprFromProperty(t, "member_id");
auto selector_key = t->properties->getProperty("selector");
auto n_groups_max = getNumberFromProperty(t, "n_groups_max");
auto n_members_per_group_max = getNumberFromProperty(t, "n_members_per_group_max");
Expand All @@ -618,7 +619,7 @@ bool ConvertToDpdkControl::preorder(const IR::P4Table *t) {
return false;

auto selector = new IR::DpdkSelector(t->name,
*group_id, *member_id, selector_key->value->to<IR::Key>(),
(*group_id)->clone(), (*member_id)->clone(), selector_key->value->to<IR::Key>(),
*n_groups_max, *n_members_per_group_max);

selectors.push_back(selector);
Expand Down
2 changes: 1 addition & 1 deletion backends/dpdk/dpdkProgram.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class ConvertToDpdkControl : public Inspector {
void add_table(const IR::DpdkLearner*s) { learners.push_back(s); }
void add_action(const IR::DpdkAction *a) { actions.push_back(a); }

boost::optional<cstring> getIdFromProperty(const IR::P4Table*, cstring);
boost::optional<const IR::Member*> getMemExprFromProperty(const IR::P4Table*, cstring);
boost::optional<int> getNumberFromProperty(const IR::P4Table*, cstring);
};

Expand Down
51 changes: 50 additions & 1 deletion backends/dpdk/run-dpdk-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

# Runs the compiler on a sample P4 V1.2 program


from os import environ
from threading import Timer
from subprocess import Popen,PIPE
from threading import Thread
import errno
Expand Down Expand Up @@ -160,6 +161,54 @@ def check_generated_files(options, tmpdir, expecteddir):
return SUCCESS
if result != SUCCESS and not ignoreStderr(options):
return result
if produced.endswith(".spec") and environ.get('DPDK_PIPELINE') is not None:
clifile = os.path.splitext(produced)[0] + ".cli"
with open(clifile,'w',encoding = 'utf-8') as f:
f.write("; SPDX-License-Identifier: BSD-3-Clause\n")
f.write("; Copyright(c) 2020 Intel Corporation\n")
f.write("\n")
f.write("mempool MEMPOOL0 buffer 9304 pool 32K cache 256 cpu 0\n")
f.write("\n")
f.write("link LINK0 dev 0000:00:04.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on\n")
f.write("link LINK1 dev 0000:00:05.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on\n")
f.write("link LINK2 dev 0000:00:06.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on\n")
f.write("link LINK3 dev 0000:00:07.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on\n")
f.write("\n")
f.write("pipeline PIPELINE0 create 0\n")
f.write("\n")
f.write("pipeline PIPELINE0 port in 0 link LINK0 rxq 0 bsz 32\n")
f.write("pipeline PIPELINE0 port in 1 link LINK1 rxq 0 bsz 32\n")
f.write("pipeline PIPELINE0 port in 2 link LINK2 rxq 0 bsz 32\n")
f.write("pipeline PIPELINE0 port in 3 link LINK3 rxq 0 bsz 32\n")
f.write("\n")
f.write("pipeline PIPELINE0 port out 0 link LINK0 txq 0 bsz 32\n")
f.write("pipeline PIPELINE0 port out 1 link LINK1 txq 0 bsz 32\n")
f.write("pipeline PIPELINE0 port out 2 link LINK2 txq 0 bsz 32\n")
f.write("pipeline PIPELINE0 port out 3 link LINK3 txq 0 bsz 32\n")
f.write("\n")
f.write("pipeline PIPELINE0 build ")
f.write(str(expected))
f.write("\n")
f.write("pipeline PIPELINE0 commit\n")
f.write("thread 1 pipeline PIPELINE0 enable\n")
f.write("pipeline PIPELINE0 abort\n")
f.close()
dpdk_log = os.path.splitext(produced)[0] + ".log"
def kill(process):
process.kill()
print("exec " + environ.get('DPDK_PIPELINE')+ " -n 4 -c 0x3 -- -s " + str(clifile)+ " 1>" + dpdk_log)
pipe = subprocess.Popen("exec " + environ.get('DPDK_PIPELINE')+ " -n 4 -c 0x3 -- -s " + str(clifile)+ " 1>" + dpdk_log ,cwd=".", shell=True)
timer = Timer(5, kill, [pipe])
try:
timer.start()
out, err = pipe.communicate()
finally:
timer.cancel()
with open(dpdk_log, "r") as f:
readfile = f.read()
if 'Error' in readfile:
print(readfile)
return FAILURE
return SUCCESS

def file_name(tmpfolder, base, suffix, ext):
Expand Down
Loading

0 comments on commit e03d7d6

Please sign in to comment.