Skip to content

Commit

Permalink
snabb top: refactor queue stats filtering
Browse files Browse the repository at this point in the history
Use a simpler method to figure out which queue stats to filter
out. Revert change to symlink each counter for intel_mp and
just symlink the whole folder again. Then add a counter in the
per-app shm that just stores the rxcounter/txcounter.

Snabb top then looks through all the apps in a process and filters
out queue counters that don't match any app. This is not totally precise
in the case that a process uses multiple NICs with counters set
(it may show more counters than necessary).
  • Loading branch information
takikawa committed Jul 10, 2018
1 parent 1c536e2 commit c40f0ea
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 55 deletions.
48 changes: 10 additions & 38 deletions src/apps/intel_mp/intel_mp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -313,15 +313,6 @@ byPciID = {
[0x10fb] = { registers = "82599ES", driver = Intel82599, max_q = 16 }
}

-- constant used in constructor below, keep synced with the actual
-- keys used for the driver stats shm frame that should be shared between
-- NIC processes
local shm_frame_keys = { "dtime", "mtu", "speed", "status", "type",
"promisc", "macaddr", "rxbytes", "rxpackets",
"rxmcast", "rxbcast", "rxdrop", "rxerrors",
"txbytes", "txpackets", "txmcast", "txbcast",
"txdrop", "txerrors", "rxdmapackets" }

-- The `driver' variable is used as a reference to the driver class in
-- order to interchangeably use NIC drivers.
driver = Intel
Expand Down Expand Up @@ -388,8 +379,10 @@ function Intel:new (conf)

-- Initialize per app statistics
self.shm = {
mtu = {counter, self.mtu},
txdrop = {counter}
mtu = {counter, self.mtu},
rxcounter = {counter, self.rxcounter},
txcounter = {counter, self.txcounter},
txdrop = {counter}
}

-- Figure out if we are supposed to collect device statistics
Expand Down Expand Up @@ -424,33 +417,14 @@ function Intel:new (conf)
self:init_queue_stats(frame)
self.stats = shm.create_frame(self.shm_root.."stats", frame)
self.sync_timer = lib.throttle(0.01)
else
-- use a dummy frame, this is just used to populate shm_frame_keys
self:init_queue_stats({})
end

-- Alias each counter in the shared stats frame in each process's pci dir
-- Not all counters in pci/ are shared, some are process specific
for _, name in ipairs(shm_frame_keys) do
-- The conditional checks if the symlink exists with lstat since
-- shm.exists requires the target exist, and the run_stats process
-- could go down and make the target cease to exist
if not S.lstat(shm.root.."/"..S.getpid().."/pci/"..
self.pciaddress.."/"..name..".counter") then
shm.alias("pci/"..self.pciaddress.."/"..name..".counter",
self.shm_root.."stats".."/"..name..".counter")
end
end

-- Expose per-instance queue counter assignment, which allows a program like
-- `snabb top` to associate PIDs to queue counters
if self.rxcounter then
local rxcs = counter.create("pci/"..self.pciaddress.."/rxcounters.counter")
counter.set(rxcs, lib.bits({rxc=self.rxcounter}, counter.read(rxcs)))
end
if self.txcounter then
local txcs = counter.create("pci/"..self.pciaddress.."/txcounters.counter")
counter.set(txcs, lib.bits({rxc=self.txcounter}, counter.read(txcs)))
-- Alias to the shared stats frame in each process's pci dir
-- The conditional checks if the symlink exists with lstat since
-- shm.exists requires the target exist, and the run_stats process
-- could go down and make the target cease to exist
if not S.lstat(shm.root.."/"..S.getpid().."/pci/"..self.pciaddress) then
shm.alias("pci/"..self.pciaddress, self.shm_root.."stats")
end

alarms.add_to_inventory(
Expand Down Expand Up @@ -1219,7 +1193,6 @@ function Intel1g:init_queue_stats (frame)
local name = "q" .. i .. "_" .. k
table.insert(self.queue_stats, name)
table.insert(self.queue_stats, self.r[v][i])
table.insert(shm_frame_keys, name)
frame[name] = {counter}
end
end
Expand Down Expand Up @@ -1327,7 +1300,6 @@ function Intel82599:init_queue_stats (frame)
local name = "q" .. i .. "_" .. k
table.insert(self.queue_stats, name)
table.insert(self.queue_stats, self.r[v][i])
table.insert(shm_frame_keys, name)
frame[name] = {counter}
end
end
Expand Down
45 changes: 28 additions & 17 deletions src/program/top/top.lua
Original file line number Diff line number Diff line change
Expand Up @@ -352,14 +352,32 @@ local function compute_histograms_tree(histograms)
return ret
end

-- given a prefix (tx or rx), bitmap of enabled queue counters, & a table
-- of counters, remove the counters not matching the bitmap
local function filter_queue_counters(prefix, bitmap, counters)
for i=0, 15 do
if not lib.bitset(bitmap, i) then
counters["q"..i.."_"..prefix.."packets"] = nil
counters["q"..i.."_"..prefix.."drops"] = nil
counters["q"..i.."_"..prefix.."bytes"] = nil
-- given a table of apps in the process & table of sets of pci counters,
-- remove the counters not used by the apps in the process
local function filter_queue_counters(apps, pcis)
local enabled_rx = 0
local enabled_tx = 0
for _, app in pairs(apps) do
for name, leaf in pairs(app) do
if name == "rxcounter" then
enabled_rx = lib.bits({bit=leaf.value()}, enabled_rx)
elseif name == "txcounter" then
enabled_tx = lib.bits({bit=leaf.value()}, enabled_tx)
end
end
end
for _, pci in pairs(pcis) do
for i=0, 15 do
if not lib.bitset(enabled_rx, i) then
pci["q"..i.."_".."rxpackets"] = nil
pci["q"..i.."_".."rxdrops"] = nil
pci["q"..i.."_".."rxbytes"] = nil
end
if not lib.bitset(enabled_tx, i) then
pci["q"..i.."_".."txpackets"] = nil
pci["q"..i.."_".."txdrops"] = nil
pci["q"..i.."_".."txbytes"] = nil
end
end
end
end
Expand All @@ -379,15 +397,8 @@ local function compute_counters_tree(counters, rrds)
function() return counter.read(v) end, rrds[k])
end
end
if ret.pci then
for pci, counters in pairs(ret.pci) do
if counters.rxcounters then
filter_queue_counters("rx", counters.rxcounters.value(), counters)
end
if counters.txcounters then
filter_queue_counters("tx", counters.txcounters.value(), counters)
end
end
if ret.pci and ret.apps then
filter_queue_counters(ret.apps, ret.pci)
end
-- The rxpackets and rxbytes link counters are redundant.
if ret.links then
Expand Down

0 comments on commit c40f0ea

Please sign in to comment.