From 54e7b9000858c64dce3b6596287968abc2e96759 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Wed, 15 Jun 2016 14:34:40 +0200 Subject: [PATCH 1/6] remove link.full, increase link buffer size, add engine.pull_npackets. --- src/README.md | 6 ------ src/core/app.lua | 3 +++ src/core/link.h | 2 +- src/core/link.lua | 11 +---------- 4 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/README.md b/src/README.md index 911ebf501f..60b385d966 100644 --- a/src/README.md +++ b/src/README.md @@ -269,12 +269,6 @@ Predicate used to test if a link is empty. Returns true if *link* is empty and false otherwise. -— Function **link.full** *link* - -Predicate used to test if a link is full. Returns true if *link* is full -and false otherwise. - - — Function **link.receive** *link* Returns the next available packet (and advances the read cursor) on diff --git a/src/core/app.lua b/src/core/app.lua index c4fb94836c..6dc6f753aa 100644 --- a/src/core/app.lua +++ b/src/core/app.lua @@ -15,6 +15,9 @@ local ffi = require("ffi") local C = ffi.C require("core.packet_h") +-- Packet per pull +pull_npackets = math.floor(link.max / 10) + -- Set to true to enable logging log = false local use_restart = false diff --git a/src/core/link.h b/src/core/link.h index c4ca2b45a5..83e078b144 100644 --- a/src/core/link.h +++ b/src/core/link.h @@ -1,6 +1,6 @@ /* Use of this source code is governed by the Apache 2.0 license; see COPYING. */ -enum { LINK_RING_SIZE = 256, +enum { LINK_RING_SIZE = 1001, LINK_MAX_PACKETS = LINK_RING_SIZE - 1 }; diff --git a/src/core/link.lua b/src/core/link.lua index ed825e2606..32af0282f5 100644 --- a/src/core/link.lua +++ b/src/core/link.lua @@ -55,7 +55,7 @@ end function transmit (r, p) -- assert(p) - if full(r) then + if band(r.write + 1, size - 1) == r.read then counter.add(r.stats.txdrop) packet.free(p) else @@ -72,11 +72,6 @@ function empty (r) return r.read == r.write end --- Return true if the ring is full. -function full (r) - return band(r.write + 1, size - 1) == r.read -end - -- Return the number of packets that are ready for read. function nreadable (r) if r.read > r.write then @@ -86,10 +81,6 @@ function nreadable (r) end end -function nwritable (r) - return max - nreadable(r) -end - function stats (r) local stats = {} for _, c From a1f60a2fbaa2f76022e77efbaef7dc73770a9d3b Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Mon, 20 Jun 2016 19:41:22 +0200 Subject: [PATCH 2/6] Replace usage of link.full/nwritable with engine.pull_npackets. --- src/apps/basic/basic_apps.lua | 16 ++++++---------- src/apps/intel/intel1g.lua | 9 ++------- src/apps/intel/intel_app.lua | 6 +++--- src/apps/ipv6/nd_light.lua | 4 ++-- src/apps/ipv6/ns_responder.lua | 4 ++-- src/apps/keyed_ipv6_tunnel/tunnel.lua | 4 ++-- src/apps/lwaftr/generator.lua | 4 ++-- src/apps/lwaftr/ipv4_apps.lua | 6 +++--- src/apps/lwaftr/ipv6_apps.lua | 4 ++-- src/apps/lwaftr/loadgen.lua | 4 ++-- src/apps/pcap/pcap.lua | 4 +++- src/apps/rate_limiter/rate_limiter.lua | 2 +- src/apps/socket/raw.lua | 4 +++- src/apps/socket/unix.lua | 6 ++++-- src/apps/solarflare/solarflare.lua | 14 +++++++------- src/apps/tap/tap.lua | 2 +- src/apps/test/lwaftr.lua | 5 +++-- src/apps/test/synth.lua | 2 +- src/apps/virtio_net/virtio_net.lua | 4 ++-- src/apps/vlan/vlan.lua | 12 +----------- src/apps/vpn/vpws.lua | 2 +- src/doc/getting-started.md | 11 +++++------ src/program/example_spray/sprayer.lua | 2 +- src/program/lisper/lisper.lua | 11 ++++------- src/program/snabbmark/snabbmark.lua | 2 +- 25 files changed, 64 insertions(+), 80 deletions(-) diff --git a/src/apps/basic/basic_apps.lua b/src/apps/basic/basic_apps.lua index 10ec6e1c90..aa39889268 100644 --- a/src/apps/basic/basic_apps.lua +++ b/src/apps/basic/basic_apps.lua @@ -21,7 +21,7 @@ end function Source:pull () for _, o in ipairs(self.output) do - for i = 1, link.nwritable(o) do + for i = 1, engine.pull_npackets do transmit(o, packet.clone(self.packet)) end end @@ -41,7 +41,7 @@ end function Join:push () for _, inport in ipairs(self.input) do - for n = 1,math.min(link.nreadable(inport), link.nwritable(self.output.out)) do + while not link.empty(inport) do transmit(self.output.out, receive(inport)) end end @@ -60,7 +60,7 @@ end function Split:push () for _, i in ipairs(self.input) do for _, o in ipairs(self.output) do - for _ = 1, math.min(link.nreadable(i), link.nwritable(o)) do + for _ = 1, link.nreadable(i) do transmit(o, receive(i)) end end @@ -95,12 +95,8 @@ end function Tee:push () noutputs = #self.output if noutputs > 0 then - local maxoutput = link.max - for _, o in ipairs(self.output) do - maxoutput = math.min(maxoutput, link.nwritable(o)) - end for _, i in ipairs(self.input) do - for _ = 1, math.min(link.nreadable(i), maxoutput) do + for _ = 1, link.nreadable(i) do local p = receive(i) maxoutput = maxoutput - 1 do local output = self.output @@ -122,7 +118,7 @@ function Repeater:new () {__index=Repeater}) end -function Repeater:push () +function Repeater:pull () local i, o = self.input.input, self.output.output for _ = 1, link.nreadable(i) do local p = receive(i) @@ -130,7 +126,7 @@ function Repeater:push () end local npackets = #self.packets if npackets > 0 then - for i = 1, link.nwritable(o) do + for i = 1, engine.pull_npackets do assert(self.packets[self.index]) transmit(o, packet.clone(self.packets[self.index])) self.index = (self.index % npackets) + 1 diff --git a/src/apps/intel/intel1g.lua b/src/apps/intel/intel1g.lua index 74f116d0bf..3725c3557d 100644 --- a/src/apps/intel/intel1g.lua +++ b/src/apps/intel/intel1g.lua @@ -59,7 +59,7 @@ function Intel1g:new(conf) local txq = conf.txqueue or 0 local rxq = conf.rxqueue or 0 local ndesc = conf.ndescriptors or 512 - local rxburst = conf.rxburst or 128 + local rxburst = conf.rxburst or engine.pull_npackets -- 8.1.3 Register Summary, p.359 local r = {} @@ -589,12 +589,7 @@ function Intel1g:new(conf) while limit > 0 and can_receive() do limit = limit - 1 if lo then -- a link connects NIC to a sink - if not link.full(lo) then -- from SolarFlareNic:pull() - link.transmit(lo, receive()) - else - counters.pullTxLinkFull= counters.pullTxLinkFull +1 - packet.free(receive()) - end + link.transmit(lo, receive()) else counters.pullNoTxLink= counters.pullNoTxLink +1 packet.free(receive()) diff --git a/src/apps/intel/intel_app.lua b/src/apps/intel/intel_app.lua index 2490a09798..7ce531f9f1 100644 --- a/src/apps/intel/intel_app.lua +++ b/src/apps/intel/intel_app.lua @@ -9,7 +9,7 @@ local lib = require("core.lib") local pci = require("lib.hardware.pci") local register = require("lib.hardware.register") local intel10g = require("apps.intel.intel10g") -local receive, transmit, full, empty = link.receive, link.transmit, link.full, link.empty +local receive, transmit, empty = link.receive, link.transmit, link.empty Intel82599 = {} Intel82599.__index = Intel82599 @@ -90,8 +90,8 @@ function Intel82599:pull () local l = self.output.tx if l == nil then return end self.dev:sync_receive() - for i=1,128 do - if full(l) or not self.dev:can_receive() then break end + for i = 1, engine.pull_npackets do + if not self.dev:can_receive() then break end transmit(l, self.dev:receive()) end self:add_receive_buffers() diff --git a/src/apps/ipv6/nd_light.lua b/src/apps/ipv6/nd_light.lua index 2717338d68..3c79349e76 100644 --- a/src/apps/ipv6/nd_light.lua +++ b/src/apps/ipv6/nd_light.lua @@ -287,7 +287,7 @@ function nd_light:push () local l_in = self.input.south local l_out = self.output.north local l_reply = self.output.south - while not link.empty(l_in) and not link.full(l_out) do + while not link.empty(l_in) do local p = cache.p p[0] = link.receive(l_in) local status = from_south(self, p) @@ -306,7 +306,7 @@ function nd_light:push () l_in = self.input.north l_out = self.output.south - while not link.empty(l_in) and not link.full(l_out) do + while not link.empty(l_in) do if not self._eth_header then -- Drop packets until ND for the next-hop -- has completed. diff --git a/src/apps/ipv6/ns_responder.lua b/src/apps/ipv6/ns_responder.lua index a23a5151d6..3d52d187ee 100644 --- a/src/apps/ipv6/ns_responder.lua +++ b/src/apps/ipv6/ns_responder.lua @@ -88,7 +88,7 @@ function ns_responder:push() local l_in = self.input.north local l_out = self.output.south if l_in and l_out then - while not link.empty(l_in) and not link.full(l_out) do + while not link.empty(l_in) do -- Pass everything on north -> south link.transmit(l_out, link.receive(l_in)) end @@ -96,7 +96,7 @@ function ns_responder:push() l_in = self.input.south l_out = self.output.north local l_reply = self.output.south - while not link.empty(l_in) and not link.full(l_out) do + while not link.empty(l_in) do local p = link.receive(l_in) local status = process(self, p) if status == nil then diff --git a/src/apps/keyed_ipv6_tunnel/tunnel.lua b/src/apps/keyed_ipv6_tunnel/tunnel.lua index 9e394cfcfc..750979bd9b 100644 --- a/src/apps/keyed_ipv6_tunnel/tunnel.lua +++ b/src/apps/keyed_ipv6_tunnel/tunnel.lua @@ -180,7 +180,7 @@ function SimpleKeyedTunnel:push() local l_out = self.output.encapsulated assert(l_in and l_out) - while not link.empty(l_in) and not link.full(l_out) do + while not link.empty(l_in) do local p = link.receive(l_in) packet.prepend(p, self.header, HEADER_SIZE) local plength = ffi.cast(plength_ctype, p.data + LENGTH_OFFSET) @@ -192,7 +192,7 @@ function SimpleKeyedTunnel:push() l_in = self.input.encapsulated l_out = self.output.decapsulated assert(l_in and l_out) - while not link.empty(l_in) and not link.full(l_out) do + while not link.empty(l_in) do local p = link.receive(l_in) -- match next header, cookie, src/dst addresses local drop = true diff --git a/src/apps/lwaftr/generator.lua b/src/apps/lwaftr/generator.lua index ea68d497c1..258692490c 100644 --- a/src/apps/lwaftr/generator.lua +++ b/src/apps/lwaftr/generator.lua @@ -138,7 +138,7 @@ end function from_inet:pull() local o = assert(self.output.output) - while not link.full(o) do + for i=1,engine.pull_npackets do if self.max_packets then if self.tx_packets == self.max_packets then break end self.tx_packets = self.tx_packets + 1 @@ -312,7 +312,7 @@ end function from_b4:pull() local o = assert(self.output.output) - while not link.full(o) do + for i=1,engine.pull_npackets do if self.max_packets then if self.tx_packets == self.max_packets then break end self.tx_packets = self.tx_packets + 1 diff --git a/src/apps/lwaftr/ipv4_apps.lua b/src/apps/lwaftr/ipv4_apps.lua index de8709c89a..6dbac5c14c 100644 --- a/src/apps/lwaftr/ipv4_apps.lua +++ b/src/apps/lwaftr/ipv4_apps.lua @@ -83,7 +83,7 @@ function Reassembler:push () local l2_size = self.l2_size local ethertype_offset = self.ethertype_offset - for _=1,math.min(link.nreadable(input), link.nwritable(output)) do + for _=1,link.nreadable(input) do local pkt = receive(input) if is_ipv4(pkt, ethertype_offset) and is_fragment(pkt, l2_size) then local frags = self:cache_fragment(pkt) @@ -165,7 +165,7 @@ end function ICMPEcho:push() local l_in, l_out, l_reply = self.input.south, self.output.north, self.output.south - for _ = 1, math.min(link.nreadable(l_in), link.nwritable(l_out)) do + for _ = 1, link.nreadable(l_in) do local out, pkt = l_out, receive(l_in) if icmp.is_icmpv4_message(pkt, icmpv4_echo_request, 0) then @@ -199,7 +199,7 @@ function ICMPEcho:push() end l_in, l_out = self.input.north, self.output.south - for _ = 1, math.min(link.nreadable(l_in), link.nwritable(l_out)) do + for _ = 1, link.nreadable(l_in) do transmit(l_out, receive(l_in)) end end diff --git a/src/apps/lwaftr/ipv6_apps.lua b/src/apps/lwaftr/ipv6_apps.lua index 958fd75434..667064175f 100644 --- a/src/apps/lwaftr/ipv6_apps.lua +++ b/src/apps/lwaftr/ipv6_apps.lua @@ -243,7 +243,7 @@ end function ICMPEcho:push() local l_in, l_out, l_reply = self.input.south, self.output.north, self.output.south - for _ = 1, math.min(link.nreadable(l_in), link.nwritable(l_out)) do + for _ = 1, link.nreadable(l_in) do local out, pkt = l_out, receive(l_in) if icmp.is_icmpv6_message(pkt, icmpv6_echo_request, 0) then @@ -279,7 +279,7 @@ function ICMPEcho:push() end l_in, l_out = self.input.north, self.output.south - for _ = 1, math.min(link.nreadable(l_in), link.nwritable(l_out)) do + for _ = 1, link.nreadable(l_in) do transmit(l_out, receive(l_in)) end end diff --git a/src/apps/lwaftr/loadgen.lua b/src/apps/lwaftr/loadgen.lua index 70039388bf..eee63538bf 100644 --- a/src/apps/lwaftr/loadgen.lua +++ b/src/apps/lwaftr/loadgen.lua @@ -31,7 +31,7 @@ function RateLimitedRepeater:set_rate (byte_rate) self.rate = math.max(byte_rate, 0) end -function RateLimitedRepeater:push () +function RateLimitedRepeater:pull () local i, o = self.input.input, self.output.output for _ = 1, link.nreadable(i) do local p = receive(i) @@ -50,7 +50,7 @@ function RateLimitedRepeater:push () local npackets = #self.packets if npackets > 0 and self.rate > 0 then - for _ = 1, link.nwritable(o) do + for _ = 1, engine.pull_npackets do local p = self.packets[self.index] if p.length > self.bucket_content then break end self.bucket_content = self.bucket_content - p.length diff --git a/src/apps/pcap/pcap.lua b/src/apps/pcap/pcap.lua index 6edf919eec..930c4e09b8 100644 --- a/src/apps/pcap/pcap.lua +++ b/src/apps/pcap/pcap.lua @@ -19,7 +19,9 @@ end function PcapReader:pull () assert(self.output.output) - while not self.done and not link.full(self.output.output) do + local limit = engine.pull_npackets + while limit > 0 and not self.done do + limit = limit - 1 local data, record, extra = self.iterator() if data then local p = packet.from_string(data) diff --git a/src/apps/rate_limiter/rate_limiter.lua b/src/apps/rate_limiter/rate_limiter.lua index 98c1cd9347..dd1f0da811 100644 --- a/src/apps/rate_limiter/rate_limiter.lua +++ b/src/apps/rate_limiter/rate_limiter.lua @@ -72,7 +72,7 @@ function RateLimiter:push () end - while not link.empty(i) and not link.full(o) do + while not link.empty(i) do local p = link.receive(i) local length = p.length diff --git a/src/apps/socket/raw.lua b/src/apps/socket/raw.lua index 24ad578d5d..400f403491 100644 --- a/src/apps/socket/raw.lua +++ b/src/apps/socket/raw.lua @@ -46,7 +46,9 @@ end function RawSocket:pull () local l = self.output.tx if l == nil then return end - while not link.full(l) and self:can_receive() do + local limit = engine.pull_npackets + while limit > 0 and self:can_receive() do + limit = limit - 1 link.transmit(l, self:receive()) end end diff --git a/src/apps/socket/unix.lua b/src/apps/socket/unix.lua index 7b906f6ab2..57d29f2b92 100644 --- a/src/apps/socket/unix.lua +++ b/src/apps/socket/unix.lua @@ -148,7 +148,9 @@ function UnixSocket:new (arg) function self:pull() local l = self.output.tx if l == nil then return end - while not link.full(l) and can_receive() do + local limit = engine.pull_npackets + while limit > 0 and can_receive() do + limit = limit - 1 local p = receive() if p then link.transmit(l, p) --link owns p now so we mustn't free it @@ -197,7 +199,7 @@ function selftest () pull = function(self) local l = self.output.tx if l == nil then return end - while not link.full(l) do + for i=1,engine.pull_npackets do local p = packet.allocate() ffi.copy(p.data, text) p.length = #text diff --git a/src/apps/solarflare/solarflare.lua b/src/apps/solarflare/solarflare.lua index b410bc7241..f1844cd0d8 100644 --- a/src/apps/solarflare/solarflare.lua +++ b/src/apps/solarflare/solarflare.lua @@ -242,19 +242,19 @@ function SolarFlareNic:pull() self.stats.pull = (self.stats.pull or 0) + 1 repeat local n_ev = self.poll_structure.n_ev + local pull_npackets = engine.pull_npackets if n_ev > 0 then for i = 0, n_ev - 1 do local event_type = self.poll_structure.events[i].generic.type - if event_type == C.EF_EVENT_TYPE_RX then + if event_type == C.EF_EVENT_TYPE_RX and pull_npackets > 0 then + pull_npackets = pull_npackets - 1 local rxpacket = self.rxpackets[self.poll_structure.events[i].rx.rq_id] rxpacket.length = self.poll_structure.events[i].rx.len self.stats.rx = (self.stats.rx or 0) + 1 - if not link.full(self.output.tx) then - link.transmit(self.output.tx, rxpacket) - else - self.stats.link_full = (self.stats.link_full or 0) + 1 - packet.free(rxpacket) - end + link.transmit(self.output.tx, rxpacket) + self.enqueue_receive(self, self.poll_structure.events[i].rx.rq_id) + elseif event_type == C.EF_EVENT_TYPE_RX and pull_npackets == 0 then + self.stats.rxdrop = (self.stats.rxdrop or 0) + 1 self.enqueue_receive(self, self.poll_structure.events[i].rx.rq_id) elseif event_type == C.EF_EVENT_TYPE_TX then local n_tx_done = self.poll_structure.unbundled_tx_request_ids[i].n_tx_done diff --git a/src/apps/tap/tap.lua b/src/apps/tap/tap.lua index 497399d11a..3b0533dfeb 100644 --- a/src/apps/tap/tap.lua +++ b/src/apps/tap/tap.lua @@ -34,7 +34,7 @@ end function Tap:pull () local l = self.output.output if l == nil then return end - while not link.full(l) do + for i=1,engine.pull_npackets do local p = packet.allocate() local len, err = S.read(self.sock, p.data, C.PACKET_PAYLOAD_SIZE) -- errno == EAGAIN indicates that the read would of blocked as there is no diff --git a/src/apps/test/lwaftr.lua b/src/apps/test/lwaftr.lua index aec09f6f22..e8b23780c3 100644 --- a/src/apps/test/lwaftr.lua +++ b/src/apps/test/lwaftr.lua @@ -255,7 +255,7 @@ function Lwaftrgen:new(arg) return setmetatable(o, {__index=Lwaftrgen}) end -function Lwaftrgen:push () +function Lwaftrgen:pull () local output = self.output.output local input = self.input.input @@ -330,7 +330,8 @@ function Lwaftrgen:push () self.bucket_content = self.bucket_content + self.rate * 1e6 * (cur_now - last_time) self.last_time = cur_now - while link.nwritable(output) > self.total_packet_count and + while limit > self.total_packet_count and + limit = limit - 1 self.total_packet_count <= self.bucket_content do self.bucket_content = self.bucket_content - self.total_packet_count diff --git a/src/apps/test/synth.lua b/src/apps/test/synth.lua index 0ffc1c97fb..99a8d8dd75 100644 --- a/src/apps/test/synth.lua +++ b/src/apps/test/synth.lua @@ -33,7 +33,7 @@ end function Synth:pull () for _, o in ipairs(self.output) do - for i = 1, link.nwritable(o) do + for i = 1, engine.pull_npackets do for _, p in ipairs(self.packets) do transmit(o, packet.clone(p)) end diff --git a/src/apps/virtio_net/virtio_net.lua b/src/apps/virtio_net/virtio_net.lua index 1adadc857d..ffb6dc8c76 100644 --- a/src/apps/virtio_net/virtio_net.lua +++ b/src/apps/virtio_net/virtio_net.lua @@ -18,7 +18,7 @@ local main = require("core.main") VirtioNet = {} VirtioNet.__index = VirtioNet -local receive, transmit, full, nreadable, nwritable = link.receive, link.transmit, link.full, link.nreadable, link.nwritable +local receive, transmit, nreadable = link.receive, link.transmit, link.nreadable function VirtioNet:new(args) return setmetatable({ @@ -51,7 +51,7 @@ function VirtioNet:pull() local dev = self.device local l = self.output.tx if not l then return end - local to_receive = math.min(nwritable(l), dev:can_receive()) + local to_receive = math.min(engine.pull_npackets, dev:can_receive()) for i=0, to_receive - 1 do transmit(l, dev:receive()) diff --git a/src/apps/vlan/vlan.lua b/src/apps/vlan/vlan.lua index 763017beb8..09b6ce6e11 100644 --- a/src/apps/vlan/vlan.lua +++ b/src/apps/vlan/vlan.lua @@ -107,18 +107,8 @@ function VlanMux:push() local noutputs = #self.output if noutputs > 0 then for name, l in pairs(self.input) do - local maxoutput = link.max - -- find out max number of packets we can put out an interface - -- this is kind of bad because we limit ourselves by the interface with - -- the fullest queue, yet packets might go out a different interface. We - -- don't know until we've looked in the packet and parsed the VLAN id. I - -- suppose we kind of get some HOLB with this :( - for _, o in ipairs(self.output) do - maxoutput = math.min(maxoutput, link.nwritable(o)) - end - if type(name) == "string" then - for _ = 1, math.min(link.nreadable(l), maxoutput) do + for _ = 1, link.nreadable(l) do local p = receive(l) local ethertype = cast("uint16_t*", packet.data(p) + o_ethernet_ethertype)[0] diff --git a/src/apps/vpn/vpws.lua b/src/apps/vpn/vpws.lua index f7c5369526..f65d37a7b1 100644 --- a/src/apps/vpn/vpws.lua +++ b/src/apps/vpn/vpws.lua @@ -72,7 +72,7 @@ function vpws:push() local l_in = self.input[port_in] local l_out = self.output[in_to_out[port_in]] assert(l_out) - while not link.full(l_out) and not link.empty(l_in) do + while not link.empty(l_in) do local p = link.receive(l_in) local datagram = self._dgram:new(p, ethernet) if port_in == 'customer' then diff --git a/src/doc/getting-started.md b/src/doc/getting-started.md index ea8a2dbc49..aa82389cc5 100644 --- a/src/doc/getting-started.md +++ b/src/doc/getting-started.md @@ -239,18 +239,17 @@ actually exists in order to raise an exception immediately if the app was not properly connected. ``` - while not link.empty(i) and not link.full(o) do + while not link.empty(i) do self:process_packet(i, o) self.packet_counter = self.packet_counter + 1 end end ``` -Now we loop over the available packets on `i` or until `o` is full and -process each individually. This is a common Snabb idiom. The -actual logic of our app is performed by a call to the `process_packet` -method which is defined below. Note that we increment the -`packet_counter` of our instance for every packet processed. +Now we loop over the available packets on `i`and process each individually. +This is a common Snabb idiom. The actual logic of our app is performed by a +call to the `process_packet` method which is defined below. Note that we +increment the `packet_counter` of our instance for every packet processed. ``` function Sprayer:process_packet(i, o) diff --git a/src/program/example_spray/sprayer.lua b/src/program/example_spray/sprayer.lua index 51140eba84..9c206bba0f 100755 --- a/src/program/example_spray/sprayer.lua +++ b/src/program/example_spray/sprayer.lua @@ -13,7 +13,7 @@ function Sprayer: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) and not link.full(o) do + while not link.empty(i) do self:process_packet(i, o) self.packet_counter = self.packet_counter + 1 end diff --git a/src/program/lisper/lisper.lua b/src/program/lisper/lisper.lua index 64e4f3c386..0f43e4c181 100644 --- a/src/program/lisper/lisper.lua +++ b/src/program/lisper/lisper.lua @@ -574,12 +574,9 @@ local function route_packet(p, rxname, txports) if not loc.encrypt(dp) then return end --invalid packet end end - if not link.full(tx) then - link.transmit(tx, dp) - stats.tx = stats.tx + 1 - else - packet.free(dp) - end + link.transmit(tx, dp) + stats.tx = stats.tx + 1 + packet.free(dp) end return p @@ -612,7 +609,7 @@ end function Punt:pull() local tx = self.output.tx if tx == nil then return end - while not link.full(tx) do + for i=1,engine.pull_npackets do local s = get_punt_message() if not s then break end local p = packet.allocate() diff --git a/src/program/snabbmark/snabbmark.lua b/src/program/snabbmark/snabbmark.lua index 5dad61aaff..301d57a439 100644 --- a/src/program/snabbmark/snabbmark.lua +++ b/src/program/snabbmark/snabbmark.lua @@ -120,7 +120,7 @@ end function Source:pull() for _, o in ipairs(self.output) do - for i = 1, link.nwritable(o) do + for i = 1, engine.pull_npackets do local p = packet.allocate() ffi.copy(p.data, self.to_mac_address, 6) ffi.copy(p.data + 6, self.from_mac_address, 6) From 55b157221a48dc9ffbd7fc92ae7b3b227e42cf55 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Mon, 25 Jul 2016 15:48:24 +0200 Subject: [PATCH 3/6] Fix-up Lwaftrgen:pull and basic_apps.Tee. --- src/apps/basic/basic_apps.lua | 3 +-- src/apps/test/lwaftr.lua | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apps/basic/basic_apps.lua b/src/apps/basic/basic_apps.lua index aa39889268..94eb669272 100644 --- a/src/apps/basic/basic_apps.lua +++ b/src/apps/basic/basic_apps.lua @@ -93,12 +93,11 @@ function Tee:new () end function Tee:push () - noutputs = #self.output + local noutputs = #self.output if noutputs > 0 then for _, i in ipairs(self.input) do for _ = 1, link.nreadable(i) do local p = receive(i) - maxoutput = maxoutput - 1 do local output = self.output for k = 1, #output do transmit(output[k], k == #output and p or packet.clone(p)) diff --git a/src/apps/test/lwaftr.lua b/src/apps/test/lwaftr.lua index e8b23780c3..61baf079b9 100644 --- a/src/apps/test/lwaftr.lua +++ b/src/apps/test/lwaftr.lua @@ -330,9 +330,10 @@ function Lwaftrgen:pull () self.bucket_content = self.bucket_content + self.rate * 1e6 * (cur_now - last_time) self.last_time = cur_now + local limit = engine.pull_npackets while limit > self.total_packet_count and - limit = limit - 1 self.total_packet_count <= self.bucket_content do + limit = limit - 1 self.bucket_content = self.bucket_content - self.total_packet_count ipv4_hdr.dst_ip = self.b4_ipv4 From c3c34136a1381fd826e5981a0345b1206822c768 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Mon, 25 Jul 2016 15:48:57 +0200 Subject: [PATCH 4/6] core.link.size must be a power of two. --- src/core/link.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/link.h b/src/core/link.h index 83e078b144..f5f74488df 100644 --- a/src/core/link.h +++ b/src/core/link.h @@ -1,6 +1,6 @@ /* Use of this source code is governed by the Apache 2.0 license; see COPYING. */ -enum { LINK_RING_SIZE = 1001, +enum { LINK_RING_SIZE = 1024, LINK_MAX_PACKETS = LINK_RING_SIZE - 1 }; From f52861f9ece4b3d6b0741a79d84bd67f5f926e23 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Mon, 25 Jul 2016 15:57:07 +0200 Subject: [PATCH 5/6] Revert "remove link.full", document link.nwritable, link.nreadable. --- src/README.md | 16 ++++++++++++++++ src/core/link.lua | 11 ++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/README.md b/src/README.md index 60b385d966..e240cca4ee 100644 --- a/src/README.md +++ b/src/README.md @@ -269,6 +269,22 @@ Predicate used to test if a link is empty. Returns true if *link* is empty and false otherwise. +— Function **link.full** *link* + +Predicate used to test if a link is full. Returns true if *link* is full +and false otherwise. + + +— Function **link.nreadable** *link* + +Returns the number of packets on *link*. + + +— Function **link.nwriteable** *link* + +Returns the remaining number of packets that fit onto *link*. + + — Function **link.receive** *link* Returns the next available packet (and advances the read cursor) on diff --git a/src/core/link.lua b/src/core/link.lua index 32af0282f5..ed825e2606 100644 --- a/src/core/link.lua +++ b/src/core/link.lua @@ -55,7 +55,7 @@ end function transmit (r, p) -- assert(p) - if band(r.write + 1, size - 1) == r.read then + if full(r) then counter.add(r.stats.txdrop) packet.free(p) else @@ -72,6 +72,11 @@ function empty (r) return r.read == r.write end +-- Return true if the ring is full. +function full (r) + return band(r.write + 1, size - 1) == r.read +end + -- Return the number of packets that are ready for read. function nreadable (r) if r.read > r.write then @@ -81,6 +86,10 @@ function nreadable (r) end end +function nwritable (r) + return max - nreadable(r) +end + function stats (r) local stats = {} for _, c From 0214574d6afe03639b47035b2c2919f82a36f001 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Tue, 23 Aug 2016 12:36:33 +0200 Subject: [PATCH 6/6] core.packet: make packet_t public accoding to documentation. --- src/core/packet.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/packet.lua b/src/core/packet.lua index 1f8fc579a8..c74631faec 100644 --- a/src/core/packet.lua +++ b/src/core/packet.lua @@ -13,8 +13,8 @@ local counter = require("core.counter") require("core.packet_h") -local packet_t = ffi.typeof("struct packet") -local packet_ptr_t = ffi.typeof("struct packet *") +packet_t = ffi.typeof("struct packet") +local packet_ptr_t = ffi.typeof("$ *", packet_t) local packet_size = ffi.sizeof(packet_t) local header_size = 8 max_payload = tonumber(C.PACKET_PAYLOAD_SIZE)