-
Notifications
You must be signed in to change notification settings - Fork 299
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
[wip] snabb top --yang: dump RFC7223 interface stats as JSON #886
Changes from 14 commits
b34c3ee
94ff234
aac0c8c
fad0f43
7ed4ed0
eb9005b
5fbe0d6
8bb3215
7a55478
dde5da2
924ff4e
8e34093
5f9efd2
7b39148
8984741
ee00d16
45490b8
f0ed10b
aca8064
c186591
b09e843
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,9 @@ local lib = require("core.lib") | |
local link = require("core.link") | ||
local main = require("core.main") | ||
local memory = require("core.memory") | ||
local counter = require("core.counter") | ||
local pci = require("lib.hardware.pci") | ||
local ethernet = require("lib.protocol.ethernet") | ||
local net_device= require("lib.virtio.net_device") | ||
local timer = require("core.timer") | ||
local ffi = require("ffi") | ||
|
@@ -52,6 +54,15 @@ function VhostUser:new (args) | |
else | ||
self.qemu_connect = self.client_connect | ||
end | ||
-- initialize counters | ||
self.counters = {} | ||
for _, name in ipairs({'type', 'discontinuity-time', | ||
'in-octets', 'in-unicast', 'in-multicast', 'in-discards', | ||
'out-octets', 'out-unicast', 'out-multicast'}) do | ||
self.counters[name] = counter.open(name) | ||
end | ||
counter.set(self.counters['type'], 0x1001) -- Virtual interface | ||
counter.set(self.counters['discontinuity-time'], C.get_unix_time()) | ||
return self | ||
end | ||
|
||
|
@@ -68,6 +79,9 @@ function VhostUser:stop() | |
self:free_mem_table() | ||
|
||
if self.link_down_proc then self.link_down_proc() end | ||
|
||
-- delete counters | ||
for name, _ in pairs(self.counters) do counter.delete(name) end | ||
end | ||
|
||
function VhostUser:pull () | ||
|
@@ -86,6 +100,28 @@ function VhostUser:push () | |
end | ||
end | ||
|
||
function VhostUser:tx_callback (p) | ||
counter.add(self.counters['out-octets'], packet.length(p)) | ||
if ethernet:is_mcast(packet.data(p)) then | ||
counter.add(self.counters['out-multicast']) | ||
else | ||
counter.add(self.counters['out-unicast']) | ||
end | ||
end | ||
|
||
function VhostUser:rx_callback (p) | ||
counter.add(self.counters['in-octets'], packet.length(p)) | ||
if ethernet:is_mcast(packet.data(p)) then | ||
counter.add(self.counters['in-multicast']) | ||
else | ||
counter.add(self.counters['in-unicast']) | ||
end | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it safe to introduce this potentially unbiased branch onto the "fast path" for Virtio-net? The risk I see is that on a workload with 50/50 mix of unicast/multicast traffic you will take the penalty of both a LuaJIT side-trace and also a CPU branch-misprediction half of the time. This could be significant and we don't currently have performance test coverage for such a workload. One alternative would be to write this branch-free (using arithmetic, bitwise operators, and min/max). Sketch: -- Set unicast and multicast to 0 and 1 as appropriate.
local multicast = bit.band(packet.data[0], 1)
local unicast = 1 - multicast
counter.add(self.counters['in-multicast'], multicast)
counter.add(self.counters['in-unicast'], unicast) This way the same instructions would execute every time and only the values would change. |
||
|
||
function VhostUser:rxdrop_callback (p) | ||
counter.add(self.counters['in-discards']) | ||
end | ||
|
||
-- Try to connect to QEMU. | ||
function VhostUser:client_connect () | ||
return C.vhost_user_connect(self.socket_path) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How frequently do these counters need to be synchronized with hardware?
This code is synchronizing them every breath but that adds up to a significant number of PCIe accesses even e.g. for NICs that are completely idle. This may cause performance degradation in scenarios that we don't have CI performance coverage on at the moment e.g. app network with very many NICs where most are idle but some are active.
One alternative would be to use a timer to update every e.g. one millisecond.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, honestly I had/have trouble getting a good understanding of Intel10G stat registers code. Could definitely use a thorough review with SHM stats in mind (e.g. get rid of
Intel10G.dev.get_rx/tx_stats()
altogether). In this PR I attempted to be make mostly non-disruptive (light bolt-on) changes.