@@ -29,7 +29,7 @@ import (
2929 "bytes"
3030 "encoding/hex"
3131 "fmt"
32- "strings "
32+ "sync "
3333 "time"
3434 "unsafe"
3535
@@ -143,6 +143,23 @@ const (
143143 DEFAULT_BLINK_DURATION = 60 * time .Second
144144)
145145
146+ var (
147+ gstringsPool = sync.Pool {
148+ New : func () interface {} {
149+ // new() will allocate and zero-initialize the struct.
150+ // The large data array within ethtoolGStrings will be zeroed.
151+ return new (ethtoolGStrings )
152+ },
153+ }
154+ statsPool = sync.Pool {
155+ New : func () interface {} {
156+ // new() will allocate and zero-initialize the struct.
157+ // The large data array within ethtoolStats will be zeroed.
158+ return new (ethtoolStats )
159+ },
160+ }
161+ )
162+
146163type ifreq struct {
147164 ifr_name [IFNAMSIZ ]byte
148165 ifr_data uintptr
@@ -1159,41 +1176,43 @@ func (e *Ethtool) Stats(intf string) (map[string]uint64, error) {
11591176 return nil , err
11601177 }
11611178
1162- if drvinfo .n_stats * ETH_GSTRING_LEN > MAX_GSTRINGS * ETH_GSTRING_LEN {
1179+ if drvinfo .n_stats > MAX_GSTRINGS {
11631180 return nil , fmt .Errorf ("ethtool currently doesn't support more than %d entries, received %d" , MAX_GSTRINGS , drvinfo .n_stats )
11641181 }
11651182
1166- gstrings := ethtoolGStrings {
1167- cmd : ETHTOOL_GSTRINGS ,
1168- string_set : ETH_SS_STATS ,
1169- len : drvinfo .n_stats ,
1170- data : [MAX_GSTRINGS * ETH_GSTRING_LEN ]byte {},
1171- }
1183+ gstringsPtr := gstringsPool .Get ().(* ethtoolGStrings )
1184+ defer gstringsPool .Put (gstringsPtr )
11721185
1173- if err := e .ioctl (intf , uintptr (unsafe .Pointer (& gstrings ))); err != nil {
1186+ gstringsPtr .cmd = ETHTOOL_GSTRINGS
1187+ gstringsPtr .string_set = ETH_SS_STATS
1188+ gstringsPtr .len = drvinfo .n_stats
1189+
1190+ if err := e .ioctl (intf , uintptr (unsafe .Pointer (gstringsPtr ))); err != nil {
11741191 return nil , err
11751192 }
11761193
1177- stats := ethtoolStats {
1178- cmd : ETHTOOL_GSTATS ,
1179- n_stats : drvinfo . n_stats ,
1180- data : [ MAX_GSTRINGS ] uint64 {},
1181- }
1194+ statsPtr := statsPool . Get ().( * ethtoolStats )
1195+ defer statsPool . Put ( statsPtr )
1196+
1197+ statsPtr . cmd = ETHTOOL_GSTATS
1198+ statsPtr . n_stats = drvinfo . n_stats
11821199
1183- if err := e .ioctl (intf , uintptr (unsafe .Pointer (& stats ))); err != nil {
1200+ if err := e .ioctl (intf , uintptr (unsafe .Pointer (statsPtr ))); err != nil {
11841201 return nil , err
11851202 }
11861203
1187- result := make (map [string ]uint64 )
1204+ result := make (map [string ]uint64 , drvinfo . n_stats )
11881205 for i := 0 ; i != int (drvinfo .n_stats ); i ++ {
1189- b := gstrings .data [i * ETH_GSTRING_LEN : i * ETH_GSTRING_LEN + ETH_GSTRING_LEN ]
1190- strEnd := strings .Index (string (b ), "\x00 " )
1206+ b := gstringsPtr .data [i * ETH_GSTRING_LEN : (i + 1 )* ETH_GSTRING_LEN ]
1207+
1208+ strEnd := bytes .IndexByte (b , 0 )
11911209 if strEnd == - 1 {
11921210 strEnd = ETH_GSTRING_LEN
11931211 }
11941212 key := string (b [:strEnd ])
1213+
11951214 if len (key ) != 0 {
1196- result [key ] = stats .data [i ]
1215+ result [key ] = statsPtr .data [i ]
11971216 }
11981217 }
11991218
0 commit comments