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

Aborts in trace due to loop unroll limit and leaving loop in root trace #1239

Open
wants to merge 13 commits into
base: wingo-next
Choose a base branch
from
Open
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
6 changes: 6 additions & 0 deletions lib/luajit/src/lib_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ LJLIB_CF(jit_attach)
return 0;
}

/* Calling this forces a trace stitch. */
LJLIB_CF(jit_tracebarrier)
{
return 0;
}

LJLIB_PUSH(top-5) LJLIB_SET(os)
LJLIB_PUSH(top-4) LJLIB_SET(arch)
LJLIB_PUSH(top-3) LJLIB_SET(version_num)
Expand Down
14 changes: 7 additions & 7 deletions lib/luajit/src/lj_jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@

/* Optimization parameters and their defaults. Length is a char in octal! */
#define JIT_PARAMDEF(_) \
_(\010, maxtrace, 1000) /* Max. # of traces in cache. */ \
_(\011, maxrecord, 4000) /* Max. # of recorded IR instructions. */ \
_(\010, maxtrace, 2000) /* Max. # of traces in cache. */ \
_(\011, maxrecord, 6000) /* Max. # of recorded IR instructions. */ \
_(\012, maxirconst, 500) /* Max. # of IR constants of a trace. */ \
_(\007, maxside, 100) /* Max. # of side traces of a root trace. */ \
_(\007, maxsnap, 500) /* Max. # of snapshots for a trace. */ \
_(\007, maxside, 200) /* Max. # of side traces of a root trace. */ \
_(\007, maxsnap, 1000) /* Max. # of snapshots for a trace. */ \
_(\011, minstitch, 0) /* Min. # of IR ins for a stitched trace. */ \
\
_(\007, hotloop, 56) /* # of iter. to detect a hot loop/call. */ \
Expand All @@ -116,7 +116,7 @@
/* Size of each machine code area (in KBytes). */ \
_(\011, sizemcode, JIT_P_sizemcode_DEFAULT) \
/* Max. total size of all machine code areas (in KBytes). */ \
_(\010, maxmcode, 512) \
_(\010, maxmcode, 4096) \
/* End of list. */

enum {
Expand Down Expand Up @@ -277,13 +277,13 @@ static LJ_AINLINE MSize snap_nextofs(GCtrace *T, SnapShot *snap)
/* Round-robin penalty cache for bytecodes leading to aborted traces. */
typedef struct HotPenalty {
MRef pc; /* Starting bytecode PC. */
uint16_t val; /* Penalty value, i.e. hotcount start. */
uint32_t val; /* Penalty value, i.e. hotcount start. */
uint16_t reason; /* Abort reason (really TraceErr). */
} HotPenalty;

#define PENALTY_SLOTS 64 /* Penalty cache slot. Must be a power of 2. */
#define PENALTY_MIN (36*2) /* Minimum penalty value. */
#define PENALTY_MAX 60000 /* Maximum penalty value. */
#define PENALTY_MAX 6000000 /* Maximum penalty value. */
#define PENALTY_RNDBITS 4 /* # of random bits to add to penalty value. */

/* Round-robin backpropagation cache for narrowing conversions. */
Expand Down
3 changes: 2 additions & 1 deletion lib/luajit/src/lj_record.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,8 @@ static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev)
/* Handle the case when an already compiled loop op is hit. */
static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev)
{
if (J->parent == 0 && J->exitno == 0) { /* Root trace hit an inner loop. */
/* Root trace hit an inner loop. */
if (J->parent == 0 && J->exitno == 0 && !innerloopleft(J, J->startpc)) {
/* Better let the inner loop spawn a side trace back here. */
lj_trace_err(J, LJ_TRERR_LINNER);
} else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */
Expand Down
10 changes: 9 additions & 1 deletion lib/luajit/src/lj_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ int lj_trace_flushall(lua_State *L)
J->freetrace = 0;
/* Clear penalty cache. */
memset(J->penalty, 0, sizeof(J->penalty));
/* Reset hotcounts. */
lj_dispatch_init_hotcount(J2G(J));
/* Free the whole machine code and invalidate all exit stub groups. */
lj_mcode_free(J);
memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup));
Expand Down Expand Up @@ -392,7 +394,7 @@ static void penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e)
J->penaltyslot = (J->penaltyslot + 1) & (PENALTY_SLOTS-1);
setmref(J->penalty[i].pc, pc);
setpenalty:
J->penalty[i].val = (uint16_t)val;
J->penalty[i].val = val;
J->penalty[i].reason = e;
hotcount_set(J2GG(J), pc+1, val);
}
Expand Down Expand Up @@ -473,6 +475,7 @@ static void trace_stop(jit_State *J)
TraceNo traceno = J->cur.traceno;
GCtrace *T = J->curfinal;
lua_State *L;
int i;

switch (op) {
case BC_FORL:
Expand Down Expand Up @@ -524,6 +527,11 @@ static void trace_stop(jit_State *J)
J->postproc = LJ_POST_NONE;
trace_save(J, T);

/* Clear any penalty after successful recording. */
for (i = 0; i < PENALTY_SLOTS; i++)
if (mref(J->penalty[i].pc, const BCIns) == pc)
J->penalty[i].val = PENALTY_MIN;

L = J->L;
lj_vmevent_send(L, TRACE,
setstrV(L, L->top++, lj_str_newlit(L, "stop"));
Expand Down
84 changes: 84 additions & 0 deletions src/apps/jit_loop/ipv4_apps.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
module(..., package.seeall)

local ethernet = require("lib.protocol.ethernet")
local receive, transmit = link.receive, link.transmit
local lpm4 = require("lib.lpm.lpm4_trie").LPM4_trie
local ipv4 = require("lib.protocol.ipv4")

ChangeMAC = {}

function ChangeMAC:new(conf)
local o = setmetatable({}, {__index=ChangeMAC})
o.conf = conf
o.src_eth = ethernet:pton(conf.src_eth)
o.dst_eth = ethernet:pton(conf.dst_eth)
o.eth_pkt = ethernet:new({})
return o
end

function ChangeMAC:push()
local i, o = self.input.input, self.output.output
for _ = 1, link.nreadable(i) do
local p = receive(i)
local data, length = p.data, p.length
if length > 0 then
local eth_pkt = self.eth_pkt:new_from_mem(data, length)
eth_pkt:src(self.src_eth)
eth_pkt:dst(self.dst_eth)
transmit(o, p)
else
packet.free(p)
end
end
end

RouteNorth = {}
local IP_TYPE = 0x0800
local ARP_TYPE = 0x0806
local IPICMP_TYPE = 0x01
local ETH_SIZE = ethernet:sizeof()

function RouteNorth:new (conf)
local o = {lpm_hash = lpm4:new(),
arp_table = {},
src_eth = ethernet:pton(conf.src_eth),
eth_pkt = ethernet:new({}),
ippkt = ipv4:new({})}
o.lpm_hash:add_string("16.0.0.1/24", 1)
o.lpm_hash:build()
o.arp_table[1] = ethernet:pton("08:35:71:00:97:14")
return setmetatable(o, {__index = self})
end

function RouteNorth:push()
local i = assert(self.input.input, "input port not found")
local o = assert(self.output.output, "output port not found")

while not link.empty(i) do
local p = link.receive(i)
local result = self:process_packet(p, o)
end
end

function RouteNorth:process_packet(p, o)
local eth_pkt = self.eth_pkt:new_from_mem(p.data, p.length)
if eth_pkt:type() == IP_TYPE then
local ippkt = self.ippkt:new_from_mem(p.data+ETH_SIZE, ipv4:sizeof())
if ippkt:protocol() == IPICMP_TYPE then
packet.free(p)
end
local client_ip = ippkt:dst()
local gw_idx = self.lpm_hash:search_string(ipv4:ntop(client_ip))
if gw_idx == nil then
logger:log("Freeing a packet as index is nil")
packet.free(p)
else
local lookedup_mac = self.arp_table[gw_idx]
eth_pkt:src(self.src_eth)
eth_pkt:dst(lookedup_mac)
link.transmit(o,p)
end
else
packet.free(p)
end
end
2 changes: 2 additions & 0 deletions src/core/app.lua
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ end
-- Run app:methodname() in protected mode (pcall). If it throws an
-- error app will be marked as dead and restarted eventually.
function with_restart (app, method)
jit.tracebarrier() -- don't mix engine and apps in traces
local status, result
if use_restart then
-- Run fn in protected mode using pcall.
Expand All @@ -95,6 +96,7 @@ function with_restart (app, method)
else
status, result = true, method(app)
end
jit.tracebarrier()
return status, result
end

Expand Down
40 changes: 40 additions & 0 deletions src/program/jit_loop/jit_loop.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module(..., package.seeall)

local lib = require("core.lib")
local logger = lib.logger_new({ rate = 32, module = 'minapp' });
local intel = require("apps.intel_mp.intel_mp")
local ipv4_apps = require("apps.jit_loop.ipv4_apps")

function run (parameters)
local north_pci_address = "0000:01:00.1"
local south_pci_address = "0000:01:00.0"
local north_mac = "08:35:71:02:6a:63"
local south_mac = "08:35:71:02:6a:62"
local north_next_hop_mac = "08:35:71:00:97:15"
local south_next_hop_mac = "08:35:71:00:97:14"

local south_if_config = {pciaddr=south_pci_address, rxq = 0, txq = 0}
local north_if_config = {pciaddr=north_pci_address, rxq = 0, txq = 0}

local north_mac_config = {src_eth = north_mac, dst_eth = north_next_hop_mac}
local south_mac_config = {src_eth = south_mac, dst_eth = south_next_hop_mac}

local south_rt_config = {src_eth = south_mac}

local c = config.new()
config.app(c, "south_if", intel.Intel, south_if_config)
config.app(c, "north_if", intel.Intel, north_if_config)
config.app(c, "north_setmac", ipv4_apps.ChangeMAC, north_mac_config)
config.app(c, "south_setmac", ipv4_apps.ChangeMAC, south_mac_config)
config.app(c, "south_rt", ipv4_apps.RouteNorth, south_rt_config)

config.link(c, "south_if.output -> north_setmac.input")
config.link(c, "north_setmac.output -> north_if.input")

config.link(c, "north_if.output -> south_rt.input")
config.link(c, "south_rt.output -> south_if.input")

engine.configure(c)
logger:log ("Engine ready to start processing")
engine.main({report = {showlinks=true, showapps=true}})
end