Skip to content

Commit

Permalink
Merge branch 'master' into standardise-link-names
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/apps/intel/intel_app.lua
#	src/apps/tap/tap.lua
#	src/apps/test/match.lua
#	src/apps/vlan/vlan.lua
  • Loading branch information
eugeneia committed Oct 11, 2016
2 parents 7147f32 + eb9d141 commit 51c135f
Show file tree
Hide file tree
Showing 22 changed files with 192 additions and 142 deletions.
4 changes: 2 additions & 2 deletions src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -877,14 +877,14 @@ Returns a copy of *array*. *Array* must not be a "sparse array".
— Function **lib.htons** *n*

Host to network byte order conversion functions for 32 and 16 bit
integers *n* respectively.
integers *n* respectively. Unsigned.

— Function **lib.ntohl** *n*

— Function **lib.ntohs** *n*

Network to host byte order conversion functions for 32 and 16 bit
integers *n* respectively.
integers *n* respectively. Unsigned.

— Function **lib.parse** *arg*, *config*

Expand Down
2 changes: 1 addition & 1 deletion src/apps/basic/basic_apps.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ end
function Join:push ()
for _, inport in ipairs(self.input) do
while not link.empty(inport) do
transmit(self.output.out, receive(inport))
transmit(self.output.output, receive(inport))
end
end
end
Expand Down
13 changes: 12 additions & 1 deletion src/apps/intel/intel10g.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,18 @@ local timer = require("core.timer")
local bits, bitset = lib.bits, lib.bitset
local band, bor, lshift = bit.band, bit.bor, bit.lshift

num_descriptors = 1024
local num_descriptors = 1024
function ring_buffer_size (arg)
if not arg then return num_descriptors end
local ring_size = assert(tonumber(arg), "bad ring size: " .. arg)
if ring_size > 32*1024 then
error("ring size too large for hardware: " .. ring_size)
end
if math.log(ring_size)/math.log(2) % 1 ~= 0 then
error("ring size is not a power of two: " .. arg)
end
num_descriptors = assert(tonumber(arg))
end

-- Defaults for configurable items
local default = {
Expand Down
18 changes: 9 additions & 9 deletions src/apps/intel/intel_app.lua
Original file line number Diff line number Diff line change
Expand Up @@ -388,14 +388,14 @@ function mq_sq(pcidevA, pcidevB)
print("Send traffic from a nicA (SF) to nicB (two VFs)")
print("The packets should arrive evenly split between the VFs")
config.app(c, 'sink_ms', basic_apps.Sink)
config.link(c, 'source_ms.out -> repeater_ms.input')
config.link(c, 'source_ms.output -> repeater_ms.input')
config.link(c, 'repeater_ms.output -> nicAs.input')
config.link(c, 'nicAs.output -> sink_ms.in1')
config.link(c, 'nicBm0.output -> sink_ms.in2')
config.link(c, 'nicBm1.output -> sink_ms.in3')
engine.configure(c)
link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d1))
link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d2))
link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d1))
link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d2))
end

-- one multiqueue driver with two apps and do switch stuff
Expand Down Expand Up @@ -436,13 +436,13 @@ function mq_sw(pcidevA)
print ("Send a bunch of packets from Am0")
print ("half of them go to nicAm1 and half go nowhere")
config.app(c, 'sink_ms', basic_apps.Sink)
config.link(c, 'source_ms.out -> repeater_ms.input')
config.link(c, 'source_ms.output -> repeater_ms.input')
config.link(c, 'repeater_ms.output -> nicAm0.input')
config.link(c, 'nicAm0.output -> sink_ms.in1')
config.link(c, 'nicAm1.output -> sink_ms.in2')
engine.configure(c)
link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d1))
link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d2))
link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d1))
link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d2))
end

function manyreconf(pcidevA, pcidevB, n, do_pf)
Expand Down Expand Up @@ -488,14 +488,14 @@ function manyreconf(pcidevA, pcidevB, n, do_pf)
vlan = 100+i,
})
config.app(c, 'sink_ms', basic_apps.Sink)
config.link(c, 'source_ms.out -> repeater_ms.input')
config.link(c, 'source_ms.output -> repeater_ms.input')
config.link(c, 'repeater_ms.output -> nicAm0.input')
config.link(c, 'nicAm0.output -> sink_ms.in1')
config.link(c, 'nicAm1.output -> sink_ms.in2')
if do_pf then engine.configure(config.new()) end
engine.configure(c)
link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d1))
link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d2))
link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d1))
link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d2))
engine.main({duration = 0.1, no_report=true})
cycles = cycles + 1
redos = redos + engine.app_table.nicAm1.dev.pf.redos
Expand Down
6 changes: 3 additions & 3 deletions src/apps/intel/loadgen.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function disable_tx_descriptor_writeback (dev)
-- Disable writeback of transmit descriptors.
-- That way our transmit descriptors stay fresh and reusable.
-- Tell hardware write them to this other memory instead.
local bytes = intel10g.num_descriptors * ffi.sizeof(intel10g.rxdesc_t)
local bytes = intel10g.ring_buffer_size() * ffi.sizeof(intel10g.rxdesc_t)
local ptr, phy = memory.dma_alloc(bytes)
dev.r.TDWBAL(phy % 2^32)
dev.r.TDWBAH(phy / 2^32)
Expand All @@ -40,7 +40,7 @@ end
function zero_descriptors (dev)
-- Clear unused descriptors
local b = memory.dma_alloc(4096)
for i = 0, intel10g.num_descriptors-1 do
for i = 0, intel10g.ring_buffer_size()-1 do
-- Make each descriptors point to valid DMA memory but be 0 bytes long.
dev.txdesc[i].address = memory.virtual_to_physical(b)
dev.txdesc[i].options = bit.lshift(1, 24) -- End of Packet flag
Expand All @@ -64,7 +64,7 @@ function LoadGen:pull ()
if dev.tdt == 0 then return end
C.full_memory_barrier()
if tdh == 0 then
dev.r.TDT(intel10g.num_descriptors)
dev.r.TDT(intel10g.ring_buffer_size())
else
dev.r.TDT(tdh - 1)
end
Expand Down
7 changes: 0 additions & 7 deletions src/apps/socket/raw.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,6 @@ local ethernet = require("lib.protocol.ethernet")
local ffi = require("ffi")
local C = ffi.C

--ljsyscall returns error as a a cdata instead of a string,
--and the standard assert() doesn't use tostring() on it.
local function assert(v, ...)
if not v then error(tostring(... or 'assertion failed'), 2) end
return v, ...
end

local c, t = S.c, S.types.t

RawSocket = {}
Expand Down
7 changes: 0 additions & 7 deletions src/apps/socket/unix.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ local link = require("core.link")
local packet = require("core.packet")
local S = require("syscall")

--ljsyscall returns error as a a cdata instead of a string,
--and the standard assert() doesn't use tostring() on it.
local function assert(v, ...)
if not v then error(tostring(... or 'assertion failed'), 2) end
return v, ...
end

UnixSocket = {}
UnixSocket.__index = UnixSocket

Expand Down
17 changes: 8 additions & 9 deletions src/apps/tap/tap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,34 @@ function Tap:new (name)
sock:close()
error("Error opening /dev/net/tun: " .. tostring(err))
end
return setmetatable({sock = sock, name = name}, {__index = Tap})
return setmetatable({sock = sock, name = name, pkt = packet.allocate()},
{__index = Tap})
end

function Tap:pull ()
local l = self.output.output
if l == nil then return end
for i=1,engine.pull_npackets do
local p = packet.allocate()
local len, err = S.read(self.sock, p.data, C.PACKET_PAYLOAD_SIZE)
local len, err = S.read(self.sock, self.pkt.data, C.PACKET_PAYLOAD_SIZE)
-- errno == EAGAIN indicates that the read would of blocked as there is no
-- packet waiting. It is not a failure.
if not len and err.errno == const.E.AGAIN then
packet.free(p)
return
end
if not len then
packet.free(p)
error("Failed read on " .. self.name .. ": " .. tostring(err))
end
p.length = len
link.transmit(l, p)
self.pkt.length = len
link.transmit(l, self.pkt)
counter.add(self.shm.input_bytes, len)
counter.add(self.shm.input_packets)
if ethernet:is_mcast(p.data) then
if ethernet:is_mcast(self.pkt.data) then
counter.add(self.shm.input_mcast)
end
if ethernet:is_bcast(p.data) then
if ethernet:is_bcast(self.pkt.data) then
counter.add(self.shm.input_bcast)
end
self.pkt = packet.allocate()
end
end

Expand Down
2 changes: 1 addition & 1 deletion src/apps/test/match.lua
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function selftest()
config.app(c, "join", basic_apps.Join)
config.link(c, "src.output -> join.src")
config.link(c, "garbage.output -> join.garbage")
config.link(c, "join.out -> sink.input")
config.link(c, "join.output -> sink.input")
engine.configure(c)
engine.main({duration=0.0001})
assert(#engine.app_table.sink:errors() == 0)
Expand Down
25 changes: 25 additions & 0 deletions src/apps/vlan/vlan.lua
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,29 @@ function VlanMux:transmit(o, pkt)
end
end

function test_tag_untag ()
local pkt = packet.from_string(lib.hexundump([[
02:aa:aa:aa:aa:aa 02:99:99:99:99:99 08 00 45 00
00 54 43 58 40 00 40 01 7c 5c c0 a8 0d 28 ac 14
01 10 08 00 9c d4 07 c0 00 01 bc fa e3 57 00 00
00 00 f3 44 01 00 00 00 00 00 10 11 12 13 14 15
16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25
26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35
36 37
]], 82))
local payload = pkt.data + o_ethernet_ethertype
local vid = 0
for i=0,15 do
for j=0,255 do
local tag = build_tag(vid)
push_tag(pkt, tag)
assert(cast(uint32_ptr_t, payload)[0] == tag)
vid = vid + 1
end
end
assert(vid == 4096)
print("Sucessfully tagged/untagged all potential VLAN tags (0-4095)")
end

function selftest()
local app = require("core.app")
Expand All @@ -164,4 +187,6 @@ function selftest()

print("source sent: " .. link.stats(app.app_table.source.output.output).input_packets)
print("sink received: " .. link.stats(app.app_table.sink.input.input).output_packets)

test_tag_untag()
end
12 changes: 10 additions & 2 deletions src/core/lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ require("core.clib_h")
local bit = require("bit")
local band, bor, bnot, lshift, rshift, bswap =
bit.band, bit.bor, bit.bnot, bit.lshift, bit.rshift, bit.bswap
local tonumber = tonumber -- Yes, this makes a performance difference.
local cast = ffi.cast

-- Returns true if x and y are structurally similar (isomorphic).
function equal (x, y)
Expand Down Expand Up @@ -373,7 +375,8 @@ if ffi.abi("be") then
function htonl(b) return b end
function htons(b) return b end
else
function htonl(b) return bswap(b) end
-- htonl is unsigned, matching the C version and expectations.
function htonl(b) return tonumber(cast('uint32_t', bswap(b))) end
function htons(b) return rshift(bswap(b), 16) end
end
ntohl = htonl
Expand Down Expand Up @@ -760,7 +763,12 @@ function selftest ()
assert(hexdump('\x45\x00\xb6\x7d\x00\xFA\x40\x00\x40\x11'):upper()
:match('^45.00.B6.7D.00.FA.40.00.40.11$'), "wrong hex dump")
assert(hexundump('4500 B67D 00FA400040 11', 10)
=='\x45\x00\xb6\x7d\x00\xFA\x40\x00\x40\x11', "wrong hex undump")
=='\x45\x00\xb6\x7d\x00\xFA\x40\x00\x40\x11', "wrong hex undump")
print("Testing ntohl")
local raw_val = 0xf0d0b0f0
assert(ntohl(raw_val) > 0, "ntohl must be unsigned")
assert(ntohl(ntohl(raw_val)) == raw_val,
"calling ntohl twice must return the original value")

-- test parse
print("Testing parse")
Expand Down
17 changes: 11 additions & 6 deletions src/core/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ local S = require("syscall")
require("lib.lua.strict")
require("lib.lua.class")

-- ljsyscall returns error as a cdata instead of a string, and the standard
-- assert doesn't use tostring on it.
_G.assert = function (v, ...)
if v then return v, ... end
error(tostring(... or "assertion failed!"))
end

-- Reserve names that we want to use for global module.
-- (This way we avoid errors from the 'strict' module.)
_G.config, _G.engine, _G.memory, _G.link, _G.packet, _G.timer,
Expand Down Expand Up @@ -164,7 +171,7 @@ function selftest ()
end

-- Fork into worker process and supervisor
local worker_pid = S.fork()
local worker_pid = assert(S.fork())
if worker_pid == 0 then
-- Worker: Use prctl to ensure we are killed (SIGHUP) when our parent quits
-- and run main.
Expand All @@ -179,16 +186,14 @@ else
while true do
-- Read signals from signalfd. Only process the first signal because any
-- signal causes shutdown.
local signals, err = S.util.signalfd_read(signalfd)
assert(signals, tostring(err))
local signals = assert(S.util.signalfd_read(signalfd))
for i = 1, #signals do
local exit_status
if signals[i].chld then
-- SIGCHILD means worker state changed: retrieve its status using
-- waitpid and set exit status accordingly.
local status, err, worker =
S.waitpid(worker_pid, "stopped,continued")
assert(status, tostring(err))
local status, _, worker =
assert(S.waitpid(worker_pid, "stopped,continued"))
if worker.WIFEXITED then exit_status = worker.EXITSTATUS
elseif worker.WIFSIGNALED then exit_status = 128 + worker.WTERMSIG
-- WIFSTOPPED and WIFCONTINUED are ignored.
Expand Down
3 changes: 1 addition & 2 deletions src/core/memory.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ end
--- ### HugeTLB: Allocate contiguous memory in bulk from Linux

function allocate_hugetlb_chunk ()
local fd, err = syscall.open("/proc/sys/vm/nr_hugepages","rdonly")
assert(fd, tostring(err))
local fd = assert(syscall.open("/proc/sys/vm/nr_hugepages","rdonly"))
fd:flock("ex")
for i =1, 3 do
local page = C.allocate_huge_page(huge_page_size)
Expand Down
4 changes: 2 additions & 2 deletions src/doc/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ stdenv.mkDerivation rec {

buildInputs = [ ditaa pandoc git
(texlive.combine {
inherit (texlive) scheme-small luatex luatexbase sectsty titlesec cprotect bigfoot titling droid;
})
inherit (texlive) scheme-small luatex luatexbase sectsty titlesec cprotect bigfoot titling droid collection-luatex;
})
];

patchPhase = ''
Expand Down
12 changes: 4 additions & 8 deletions src/lib/hardware/pci.lua
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,12 @@ function map_pci_memory (device, n, lock)
if lock then
assert(f:flock("ex, nb"), "failed to lock " .. filepath)
end
local st, err = f:stat()
assert(st, tostring(err))
local mem, err = f:mmap(nil, st.size, "read, write", "shared", 0)
assert(mem, tostring(err))
local st = assert(f:stat())
local mem = assert(f:mmap(nil, st.size, "read, write", "shared", 0))
return ffi.cast("uint32_t *", mem), f
end
function close_pci_resource (fd, base)
local st, err = fd:stat()
assert(st, tostring(err))
local st = assert(fd:stat())
S.munmap(base, st.size)
fd:close()
end
Expand All @@ -159,8 +156,7 @@ end
--- mastering is enabled.
function set_bus_master (device, enable)
root_check()
local f,err = S.open(path(device).."/config", "rdwr")
assert(f, tostring(err))
local f = assert(S.open(path(device).."/config", "rdwr"))
local fd = f:getfd()

local value = ffi.new("uint16_t[1]")
Expand Down
9 changes: 1 addition & 8 deletions src/program/firehose/firehose.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,6 @@ function run (args)
end
function opt.r (arg)
ring_size = tonumber(arg)
if type(ring_size) ~= 'number' then fatal("bad ring size: " .. arg) end
if ring_size > 32*1024 then
fatal("ring size too large for hardware: " .. ring_size)
end
if math.log(ring_size)/math.log(2) % 1 ~= 0 then
fatal("ring size is not a power of two: " .. arg)
end
end
args = lib.dogetopt(args, opt, "hHet:i:r:", long_opts)
if #pciaddresses == 0 then
Expand Down Expand Up @@ -79,7 +72,7 @@ int firehose_callback_v1(const char *pciaddr, char **packets, void *rxring,

local intel10g = require("apps.intel.intel10g")
-- Maximum buffers to avoid packet drops
intel10g.num_descriptors = ring_size
intel10g.ring_buffer_size(ring_size)
local nic = intel10g.new_sf({pciaddr=pciaddr})
nic:open()

Expand Down
Loading

0 comments on commit 51c135f

Please sign in to comment.