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

handle more columns from softnet_data #473

Merged
merged 3 commits into from Dec 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 59 additions & 11 deletions net_softnet.go
Expand Up @@ -27,8 +27,9 @@ import (
// For the proc file format details,
// See:
// * Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2343
// * Linux 4.17 https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162
// and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810.
// * Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086
// * Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162
// * Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169

// SoftnetStat contains a single row of data from /proc/net/softnet_stat.
type SoftnetStat struct {
Expand All @@ -38,6 +39,18 @@ type SoftnetStat struct {
Dropped uint32
// Number of times processing packets ran out of quota.
TimeSqueezed uint32
// Number of collision occur while obtaining device lock while transmitting.
CPUCollision uint32
// Number of times cpu woken up received_rps.
ReceivedRps uint32
// number of times flow limit has been reached.
FlowLimitCount uint32
// Softnet backlog status.
SoftnetBacklogLen uint32
// CPU id owning this softnet_data.
Index uint32
// softnet_data's Width.
Width int
}

var softNetProcFile = "net/softnet_stat"
Expand Down Expand Up @@ -66,22 +79,57 @@ func parseSoftnet(r io.Reader) ([]SoftnetStat, error) {
for s.Scan() {
columns := strings.Fields(s.Text())
width := len(columns)
softnetStat := SoftnetStat{}

if width < minColumns {
return nil, fmt.Errorf("%d columns were detected, but at least %d were expected", width, minColumns)
}

// We only parse the first three columns at the moment.
us, err := parseHexUint32s(columns[0:3])
if err != nil {
return nil, err
// Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2347
if width >= minColumns {
us, err := parseHexUint32s(columns[0:9])
if err != nil {
return nil, err
}

softnetStat.Processed = us[0]
softnetStat.Dropped = us[1]
softnetStat.TimeSqueezed = us[2]
softnetStat.CPUCollision = us[8]
}

// Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086
if width >= 10 {
us, err := parseHexUint32s(columns[9:10])
if err != nil {
return nil, err
}

softnetStat.ReceivedRps = us[0]
}

stats = append(stats, SoftnetStat{
Processed: us[0],
Dropped: us[1],
TimeSqueezed: us[2],
})
// Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162
if width >= 11 {
us, err := parseHexUint32s(columns[10:11])
if err != nil {
return nil, err
}

softnetStat.FlowLimitCount = us[0]
}

// Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169
if width >= 13 {
us, err := parseHexUint32s(columns[11:13])
if err != nil {
return nil, err
}

softnetStat.SoftnetBacklogLen = us[0]
softnetStat.Index = us[1]
}
softnetStat.Width = width
stats = append(stats, softnetStat)
}

return stats, nil
Expand Down
51 changes: 45 additions & 6 deletions net_softnet_test.go
Expand Up @@ -25,15 +25,54 @@ func TestNetSoftnet(t *testing.T) {
t.Fatal(err)
}

want := []SoftnetStat{{
Processed: 0x00015c73,
Dropped: 0x00020e76,
TimeSqueezed: 0xf0000769,
},
want := []SoftnetStat{
{
Processed: 0x00358fe3,
Dropped: 0x00006283,
TimeSqueezed: 0x00000000,
CPUCollision: 0x00000000,
ReceivedRps: 0x000855fc,
FlowLimitCount: 0x00000076,
SoftnetBacklogLen: 0x00000000,
Index: 0x00000000,
Width: 13,
},
{
Processed: 0x00953d1a,
Dropped: 0x00000446,
TimeSqueezed: 0x000000b1,
CPUCollision: 0x00000000,
ReceivedRps: 0x008eeb9a,
FlowLimitCount: 0x0000002b,
SoftnetBacklogLen: 0x000000dc,
Index: 0x00000001,
Width: 13,
},
{
Processed: 0x00015c73,
Dropped: 0x00020e76,
TimeSqueezed: 0xf0000769,
CPUCollision: 0x00000004,
ReceivedRps: 0x00000003,
FlowLimitCount: 0x00000002,
Width: 11,
},
{
Processed: 0x01663fb2,
Dropped: 0x00000000,
TimeSqueezed: 0x0109a4,
}}
CPUCollision: 0x00020e76,
Width: 9,
},
{
Processed: 0x00008e78,
Dropped: 0x00000001,
TimeSqueezed: 0x00000011,
CPUCollision: 0x00000020,
ReceivedRps: 0x00000010,
Width: 10,
},
}

got, err := fs.NetSoftnetStat()
if err != nil {
Expand Down
9 changes: 6 additions & 3 deletions testdata/fixtures.ttar
Expand Up @@ -2378,9 +2378,12 @@ FRAG6: inuse 0 memory 0
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/softnet_stat
Lines: 2
00015c73 00020e76 F0000769 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
01663fb2 00000000 000109a4 00000000 00000000 00000000 00000000 00000000 00000000
Lines: 5
00358fe3 00006283 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000855fc 00000076 00000000 00000000
00953d1a 00000446 000000b1 00000000 00000000 00000000 00000000 00000000 00000000 008eeb9a 0000002b 000000dc 00000001
00015c73 00020e76 f0000769 00000000 00000000 00000000 00000000 00000000 00000004 00000003 00000002
01663fb2 00000000 000109a4 00000000 00000000 00000000 00000000 00000000 00020e76
00008e78 00000001 00000011 00000000 00000000 00000000 00000000 00000000 00000020 00000010
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/softnet_stat.broken
Expand Down