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

next: Changes queued for the v2015.08 release #981

Merged
merged 29 commits into from
Aug 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a95751f
core.packet: Remove data/length reader functions.
eugeneia Jul 15, 2016
0be75ab
SnabbNFV: Add support for virtual/software I/O mode.
eugeneia May 24, 2016
38cf53c
SnabbNFV test reorganization and parameterization.
eugeneia Jul 13, 2016
f6ef311
SnabbNFV: make virtio mrg_rxbuf option configurable.
eugeneia May 27, 2016
0814fd9
apps.bridge.flooding: Fix regression introduced by 4b4b8ad / #638.
eugeneia May 26, 2016
2552468
SnabbNFV: add port option no_indirect_desc.
eugeneia May 27, 2016
3018249
Merge PR #967 (Remove core.packet merge cruft) into kbara-next
Jul 18, 2016
16c72ae
Merge PR #968 (Fix flooding regression) into kbara-next
Jul 18, 2016
dcaf4f9
pci_bind: A utility to bind/unbind PCI cards
Jul 19, 2016
afbd3be
Merge branch 'master' into max-next
eugeneia Jul 21, 2016
e0f71fd
Merge PR #971 (add snabb pci_bind utility) into max-next
eugeneia Jul 21, 2016
28a3de1
statistics: introduce shm frame abstraction to eliminate boilerplate …
eugeneia Jul 21, 2016
70ad231
snabb top: remove obsolete unlinking of runtime files (supervisor).
eugeneia Jul 21, 2016
f9e8307
Merge tag 'v2016.07' into next
lukego Jul 22, 2016
946e266
Merge #970 branch 'snabbco/kbara-next' into next
lukego Jul 22, 2016
51e023c
Merge PR #969 (SnabbNFV software/virtual IO) into max-next
eugeneia Jul 25, 2016
a37441f
snabbnfv: Added symlink to dpdk_bench.sh for Hydra compatibility.
eugeneia Jul 28, 2016
00f6ff6
Fix intel1g selftest
dpino Jul 28, 2016
bf09217
Replace os.getenv for lib.getenv
dpino Jul 29, 2016
24297c7
Merge PR #975 (Skip intel1g selftest if env var is empty) into max-next
eugeneia Jul 29, 2016
19b4861
Merge #974 branch 'snabbco/max-next' into next
lukego Jul 29, 2016
78c6764
core.shm: $SNABB_SHM_ROOT overrides /var/run/snabb
lukego May 10, 2016
5c317aa
main: $SNABB_SHM_KEEP prevents removal of shm dir
lukego Aug 1, 2016
e437bb9
Merge PR #979 (SNABB_SHM_* env debug vars) into kbara-next
Aug 1, 2016
2f7ae97
Merge #980 remote-tracking branch 'snabbco/kbara-next' into next
lukego Aug 1, 2016
e55afad
Merge PR #972 (Extended shm management support) into kbara-next
Aug 1, 2016
77c0d57
vhost_user: revert statistics.
eugeneia Aug 1, 2016
4cd0fba
Merge #982 remote-tracking branch 'snabbco/kbara-next' into next
lukego Aug 2, 2016
e1fdc74
Merge #983 remote-tracking branch 'snabbco/max-next' into next
lukego Aug 2, 2016
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
215 changes: 213 additions & 2 deletions src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ the engine for use in processing and are *read-only*.
Name of the app. *Read-only*.


— Field **myapp.shm**

Can be set to a specification for `core.shm.create_frame` during `new`. When
set, this field will be initialized to a frame of shared memory objects by the
engine.


— Method **myapp:link**

*Optional*. Called any time the app’s links may have been changed (including on
Expand Down Expand Up @@ -401,7 +408,7 @@ can be accessed directly by network cards. The important
characteristic of DMA memory is being located in contiguous physical
memory at a stable address.

— Function **memory.dma_alloc** *bytes*, *[alignment]*
— Function **memory.dma_alloc** *bytes*, [*alignment*]

Returns a pointer to *bytes* of new DMA memory.

Expand All @@ -417,6 +424,210 @@ Returns the physical address (`uint64_t`) the DMA memory at *pointer*.
Size of a single huge page in bytes. Read-only.


## Shared Memory (core.shm)

This module facilitates creation and management of named shared memory objects.
Objects can be created using `shm.create` similar to `ffi.new`, except that
separate calls to `shm.open` for the same name will each return a new mapping
of the same shared memory. Different processes can share memory by mapping an
object with the same name (and type). Each process can map any object any
number of times.

Mappings are deleted on process termination or with an explicit `shm.unmap`.
Names are unlinked from objects that are no longer needed using `shm.unlink`.
Object memory is freed when the name is unlinked and all mappings have been
deleted.

Names can be fully qualified or abbreviated to be within the current process.
Here are examples of names and how they are resolved where `<pid>` is the PID
of this process:

- Local: `foo/bar` ⇒ `/var/run/snabb/<pid>/foo/bar`
- Fully qualified: `/1234/foo/bar` ⇒ `/var/run/snabb/1234/foo/bar`

Behind the scenes the objects are backed by files on ram disk
(`/var/run/snabb/<pid>`) and accessed with the equivalent of POSIX shared
memory (`shm_overview(7)`).

The practical limit on the number of objects that can be mapped will depend on
the operating system limit for memory mappings. On Linux the default limit is
65,530 mappings:

```
$ sysctl vm.max_map_count vm.max_map_count = 65530
```

— Function **shm.create** *name*, *type*

Creates and maps a shared object of *type* into memory via a hierarchical
*name*. Returns a pointer to the mapped object.

— Function **shm.open** *name*, *type*, [*readonly*]

Maps an existing shared object of *type* into memory via a hierarchical *name*.
If *readonly* is non-nil the shared object is mapped in read-only mode.
*Readonly* defaults to nil. Fails if the shared object does not already exist.
Returns a pointer to the mapped object.

— Function **shm.unmap** *pointer*

Deletes the memory mapping for *pointer*.

— Function **shm.unlink** *path*

Unlinks the subtree of objects designated by *path* from the filesystem.

— Function **shm.children** *path*

Returns an array of objects in the directory designated by *path*.

— Function **shm.register** *type*, *module*

Registers an abstract shared memory object *type* implemented by *module* in
`shm.types`. *Module* must provide the following functions:

- **create** *name*, ...
- **open**, *name*

and can optionally provide the function:

- **delete**, *name*

The *module*’s `type` variable must be bound to *type*. To register a new type
a module might invoke `shm.register` like so:

```
type = shm.register('mytype', getfenv())
-- Now the following holds true:
-- shm.types[type] == getfenv()
```

— Variable **shm.types**

A table that maps types to modules. See `shm.register`.

— Function **shm.create_frame** *path*, *specification*

Creates and returns a shared memory frame by *specification* under *path*. A
frame is a table of mapped—possibly abstract‑shared memory objects.
*Specification* must be of the form:

```
{ <name> = {<module>, ...},
... }
```

*Module* must implement an abstract type registered with `shm.register`, and is
followed by additional initialization arguments to its `create` function.
Example usage:

```
local counter = require("core.counter")
-- Create counters foo/bar/{dtime,rxpackets,txpackets}.counter
local f = shm.create_frame(
"foo/bar",
{dtime = {counter, C.get_unix_time()},
rxpackets = {counter},
txpackets = {counter}})
counter.add(f.rxpackets)
counter.read(f.dtime)
```

— Function **shm.open_frame** *path*

Opens and returns the shared memory frame under *path* for reading.

— Function **shm.delete_frame** *frame*

Deletes/unmaps a shared memory *frame*. The *frame* directory is unlinked if
*frame* was created by `shm.create_frame`.


### Counter (core.counter)

Double-buffered shared memory counters. Counters are 64-bit unsigned values.
Registered with `core.shm` as type `counter`.

— Function **counter.create** *name*, [*initval*]

Creates and returns a `counter` by *name*, initialized to *initval*. *Initval*
defaults to 0.

— Function **counter.open** *name*

Opens and returns the counter by *name* for reading.

— Function **counter.delete** *name*

Deletes and unmaps the counter by *name*.

— Function **counter.commit**

Commits buffered counter values to public shared memory.

— Function **counter.set** *counter*, *value*

Sets *counter* to *value*.

— Function **counter.add** *counter*, [*value*]

Increments *counter* by *value*. *Value* defaults to 1.

— Function **counter.read** *counter*

Returns the value of *counter*.


### Histogram (core.histogram)

Shared memory histogram with logarithmic buckets. Registered with `core.shm` as
type `histogram`.

— Function **histogram.new** *min*, *max*

Returns a new `histogram`, with buckets covering the range from *min* to *max*.
The range between *min* and *max* will be divided logarithmically.

— Function **histogram.create** *name*, *min*, *max*

Creates and returns a `histogram` as in `histogram.new` by *name*. If the file
exists already, it will be cleared.

— Function **histogram.open** *name*

Opens and returns `histogram` by *name* for reading.

— Method **histogram:add** *measurement*

Adds *measurement* to *histogram*.

— Method **histogram:iterate** *prev*

When used as `for count, lo, hi in histogram:iterate()`, visits all buckets in
*histogram* in order from lowest to highest. *Count* is the number of samples
recorded in that bucket, and *lo* and *hi* are the lower and upper bounds of
the bucket. Note that *count* is an unsigned 64-bit integer; to get it as a Lua
number, use `tonumber`.

If *prev* is given, it should be a snapshot of the previous version of the
histogram. In that case, the *count* values will be returned as a difference
between their values in *histogram* and their values in *prev*.

— Method **histogram:snapshot** [*dest*]

Copies out the contents of *histogram* into the `histogram` *dest* and returns
*dest*. If *dest* is not given, the result will be a fresh `histogram`.

— Method **histogram:clear**

Clears the buckets of *histogram*.

— Method **histogram:wrap_thunk* *thunk*, *now*

Returns a closure that wraps *thunk*, measuring and recording the difference
between calls to *now* before and after *thunk* into *histogram*.


## Lib (core.lib)

The `core.lib` module contains miscellaneous utilities.
Expand Down Expand Up @@ -674,4 +885,4 @@ A list of command-line arguments to the running script. Read-only.

— Function **main.exit** *status*

Cleanly exists the process with *status*.
Cleanly exits the process with *status*.
16 changes: 7 additions & 9 deletions src/apps/bridge/flooding.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,18 @@ function bridge:new (arg)
end

function bridge:push()
local src_ports = self._src_ports
local ports = self._ports
local dst_ports = self._dst_ports
local output = self.output
local i = 1
while src_ports[i] do
local src_port = src_ports[i]
local l_in = self.input[src_port]
while ports[i] do
local l_in = ports[i].l_in
while not empty(l_in) do
local ports = dst_ports[src_port]
local dst = dst_ports[i]
local p = receive(l_in)
transmit(output[ports[1]], p)
transmit(ports[dst[1]].l_out, p)
local j = 2
while ports[j] do
transmit(output[ports[j]], clone(p))
while dst[j] do
transmit(ports[dst[j]].l_out, clone(p))
j = j + 1
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/apps/intel/intel1g.lua
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ end -- function Intel1g:new()

function selftest ()
print("selftest: Intel1g")
local pciaddr = os.getenv("SNABB_PCI_INTEL1G0")
local pciaddr = lib.getenv("SNABB_PCI_INTEL1G0")
if not pciaddr then
print("SNABB_PCI_INTEL1G0 not set")
os.exit(engine.test_skipped_code)
Expand Down
55 changes: 28 additions & 27 deletions src/apps/intel/intel_app.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@ local function firsthole(t)
end
end

local provided_counters = {
'type', 'dtime', 'mtu', 'speed', 'status', 'promisc', 'macaddr',
'rxbytes', 'rxpackets', 'rxmcast', 'rxbcast', 'rxdrop', 'rxerrors',
'txbytes', 'txpackets', 'txmcast', 'txbcast', 'txdrop', 'txerrors'
}

-- Create an Intel82599 App for the device with 'pciaddress'.
function Intel82599:new (arg)
local conf = config.parse_app_arg(arg)
Expand All @@ -63,21 +57,31 @@ function Intel82599:new (arg)
self.stats = { s = self.dev.s, r = self.dev.r, qs = self.dev.qs }
self.zone = "intel"
end
if not self.stats.counters then
self.stats.path = "/counters/"..conf.pciaddr.."/"
if not self.stats.shm then
self.stats.shm = shm.create_frame(
"pci/"..conf.pciaddr,
{dtime = {counter, C.get_unix_time()},
mtu = {counter, self.dev.mtu},
speed = {counter, 10000000000}, -- 10 Gbits
status = {counter, 2}, -- Link down
promisc = {counter},
macaddr = {counter},
rxbytes = {counter},
rxpackets = {counter},
rxmcast = {counter},
rxbcast = {counter},
rxdrop = {counter},
rxerrors = {counter},
txbytes = {counter},
txpackets = {counter},
txmcast = {counter},
txbcast = {counter},
txdrop = {counter},
txerrors = {counter}})
self.stats.sync_timer = lib.timer(0.001, 'repeating', engine.now)
self.stats.counters = {}
for _, name in ipairs(provided_counters) do
self.stats.counters[name] = counter.open(self.stats.path..name)
end
counter.set(self.stats.counters.type, 0x1000) -- Hardware interface
counter.set(self.stats.counters.dtime, C.get_unix_time())
counter.set(self.stats.counters.mtu, self.dev.mtu)
counter.set(self.stats.counters.speed, 10000000000) -- 10 Gbits
counter.set(self.stats.counters.status, 2) -- down

if not conf.vmdq and conf.macaddr then
counter.set(self.stats.counters.macaddr,
macaddress:new(conf.macaddr).bits)
counter.set(self.stats.shm.macaddr, macaddress:new(conf.macaddr).bits)
end
end
return setmetatable(self, Intel82599)
Expand All @@ -102,10 +106,7 @@ function Intel82599:stop()
close_pf:close()
end
if not self.dev.pf or close_pf then
for name, _ in pairs(self.stats.counters) do
counter.delete(self.stats.path..name)
end
shm.unlink(self.stats.path)
shm.delete_frame(self.stats.shm)
end
end

Expand All @@ -117,7 +118,7 @@ function Intel82599:reconfig(arg)
self.dev:reconfig(conf)

if not self.dev.pf and conf.macaddr then
counter.set(self.stats.counters.macaddr,
counter.set(self.stats.shm.macaddr,
macaddress:new(conf.macaddr).bits)
end
end
Expand Down Expand Up @@ -153,11 +154,11 @@ function Intel82599:add_receive_buffers ()
end
end

-- Synchronize self.stats.s/r a and self.stats.counters.
-- Synchronize self.stats.s/r a and self.stats.shm.
local link_up_mask = lib.bits{Link_up=30}
local promisc_mask = lib.bits{UPE=9}
function Intel82599:sync_stats ()
local counters = self.stats.counters
local counters = self.stats.shm
local s, r, qs = self.stats.s, self.stats.r, self.stats.qs
counter.set(counters.rxbytes, s.GORC64())
counter.set(counters.rxpackets, s.GPRC())
Expand Down Expand Up @@ -195,7 +196,7 @@ function Intel82599:push ()
-- check is currently disabled to satisfy some selftests until
-- agreement on this strategy is reached.
-- if p.length > self.dev.mtu then
-- counter.add(self.stats.counters.txdrop)
-- counter.add(self.stats.shm.txdrop)
-- packet.free(p)
-- else
do local p = receive(l)
Expand Down
Loading