@@ -27,8 +27,9 @@ import (
2727// For the proc file format details,
2828// See:
2929// * Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2343
30- // * Linux 4.17 https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162
31- // and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810.
30+ // * Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086
31+ // * Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162
32+ // * Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169
3233
3334// SoftnetStat contains a single row of data from /proc/net/softnet_stat.
3435type SoftnetStat struct {
@@ -38,6 +39,18 @@ type SoftnetStat struct {
3839 Dropped uint32
3940 // Number of times processing packets ran out of quota.
4041 TimeSqueezed uint32
42+ // Number of collision occur while obtaining device lock while transmitting.
43+ CPUCollision uint32
44+ // Number of times cpu woken up received_rps.
45+ ReceivedRps uint32
46+ // number of times flow limit has been reached.
47+ FlowLimitCount uint32
48+ // Softnet backlog status.
49+ SoftnetBacklogLen uint32
50+ // CPU id owning this softnet_data.
51+ Index uint32
52+ // softnet_data's Width.
53+ Width int
4154}
4255
4356var softNetProcFile = "net/softnet_stat"
@@ -66,22 +79,57 @@ func parseSoftnet(r io.Reader) ([]SoftnetStat, error) {
6679 for s .Scan () {
6780 columns := strings .Fields (s .Text ())
6881 width := len (columns )
82+ softnetStat := SoftnetStat {}
6983
7084 if width < minColumns {
7185 return nil , fmt .Errorf ("%d columns were detected, but at least %d were expected" , width , minColumns )
7286 }
7387
74- // We only parse the first three columns at the moment.
75- us , err := parseHexUint32s (columns [0 :3 ])
76- if err != nil {
77- return nil , err
88+ // Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2347
89+ if width >= minColumns {
90+ us , err := parseHexUint32s (columns [0 :9 ])
91+ if err != nil {
92+ return nil , err
93+ }
94+
95+ softnetStat .Processed = us [0 ]
96+ softnetStat .Dropped = us [1 ]
97+ softnetStat .TimeSqueezed = us [2 ]
98+ softnetStat .CPUCollision = us [8 ]
99+ }
100+
101+ // Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086
102+ if width >= 10 {
103+ us , err := parseHexUint32s (columns [9 :10 ])
104+ if err != nil {
105+ return nil , err
106+ }
107+
108+ softnetStat .ReceivedRps = us [0 ]
78109 }
79110
80- stats = append (stats , SoftnetStat {
81- Processed : us [0 ],
82- Dropped : us [1 ],
83- TimeSqueezed : us [2 ],
84- })
111+ // Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162
112+ if width >= 11 {
113+ us , err := parseHexUint32s (columns [10 :11 ])
114+ if err != nil {
115+ return nil , err
116+ }
117+
118+ softnetStat .FlowLimitCount = us [0 ]
119+ }
120+
121+ // Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169
122+ if width >= 13 {
123+ us , err := parseHexUint32s (columns [11 :13 ])
124+ if err != nil {
125+ return nil , err
126+ }
127+
128+ softnetStat .SoftnetBacklogLen = us [0 ]
129+ softnetStat .Index = us [1 ]
130+ }
131+ softnetStat .Width = width
132+ stats = append (stats , softnetStat )
85133 }
86134
87135 return stats , nil
0 commit comments