Skip to content

Commit cba41f8

Browse files
committed
Minor increase to NVMe Metrics Performance
Signed-off-by: Connor Catlett <[email protected]>
1 parent beae491 commit cba41f8

File tree

1 file changed

+21
-29
lines changed

1 file changed

+21
-29
lines changed

pkg/metrics/nvme.go

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -283,48 +283,40 @@ func convertHistogram(hist Histogram) (uint64, map[float64]uint64) {
283283

284284
// getNVMEMetrics retrieves NVMe metrics by reading the log page from the NVMe device at the given path.
285285
func getNVMEMetrics(devicePath string) ([]byte, error) {
286-
f, err := os.OpenFile(devicePath, os.O_RDWR, 0)
287-
if err != nil {
288-
return nil, fmt.Errorf("getNVMEMetrics: error opening device: %w", err)
289-
}
290-
defer func() {
291-
if err := f.Close(); err != nil {
292-
klog.ErrorS(err, "Failed to close device file", "devicePath", devicePath)
293-
}
294-
}()
295-
296-
data, err := nvmeReadLogPage(f.Fd(), 0xD0)
297-
if err != nil {
298-
return nil, fmt.Errorf("getNVMEMetrics: error reading log page %w", err)
299-
}
300-
301-
return data, nil
302-
}
303-
304-
// nvmeReadLogPage reads an NVMe log page via an ioctl system call.
305-
func nvmeReadLogPage(fd uintptr, logID uint8) ([]byte, error) {
306-
data := make([]byte, 4096) // 4096 bytes is the length of the log page.
307-
bufferLen := len(data)
308-
309-
if bufferLen > math.MaxUint32 {
310-
return nil, errors.New("nvmeReadLogPage: bufferLen exceeds MaxUint32")
286+
bufferLen := binary.Size(EBSMetrics{})
287+
if bufferLen > math.MaxUint32 || bufferLen <= 0 {
288+
return nil, fmt.Errorf("getNVMEMetrics: invalid buffer size: %d", bufferLen)
311289
}
312290

291+
// Allocate before opening the device so we hold it open for as little time as possible
292+
data := make([]byte, bufferLen)
313293
cmd := nvmePassthruCommand{
314294
opcode: 0x02,
315295
addr: uint64(uintptr(unsafe.Pointer(&data[0]))),
316296
nsid: 1,
317297
dataLen: uint32(bufferLen),
318-
cdw10: uint32(logID) | (1024 << 16),
298+
cdw10: 0xD0 | (1024 << 16),
319299
}
320300

321-
status, _, errno := unix.Syscall(unix.SYS_IOCTL, fd, 0xC0484E41, uintptr(unsafe.Pointer(&cmd)))
301+
// Write handle is not needed to call ioctl on linux, thus open RDONLY
302+
f, err := os.OpenFile(devicePath, os.O_RDONLY, 0)
303+
if err != nil {
304+
return nil, fmt.Errorf("getNVMEMetrics: error opening device: %w", err)
305+
}
306+
defer func() {
307+
if err := f.Close(); err != nil {
308+
klog.ErrorS(err, "Failed to close device file", "devicePath", devicePath)
309+
}
310+
}()
311+
312+
status, _, errno := unix.Syscall(unix.SYS_IOCTL, f.Fd(), 0xC0484E41, uintptr(unsafe.Pointer(&cmd)))
322313
if errno != 0 {
323-
return nil, fmt.Errorf("nvmeReadLogPage: ioctl error %w", errno)
314+
return nil, fmt.Errorf("getNVMEMetrics: ioctl error %w", errno)
324315
}
325316
if status != 0 {
326-
return nil, fmt.Errorf("nvmeReadLogPage: ioctl command failed with status %d", status)
317+
return nil, fmt.Errorf("getNVMEMetrics: ioctl command failed with status %d", status)
327318
}
319+
328320
return data, nil
329321
}
330322

0 commit comments

Comments
 (0)