main f2d166b

flip_trace.go RawHistoryFolder

1package drm
2
3import (
4	"os"
5	"runtime"
6	"time"
7	"unsafe"
8
9	"golang.org/x/sys/unix"
10)
11
12// Flip tracing (--debug=drm-flip) logs every commit completion with the
13// times needed to tell a late client fence from a late flip: all times
14// are CLOCK_MONOTONIC, the clock of flip events and fence timestamps.
15
16// SYNC_IOC_FILE_INFO = _IOWR('>', 4, struct sync_file_info)
17const ioctlSyncFileInfo = 0xc0383e04
18
19// syncFileInfo is struct sync_file_info.
20type syncFileInfo struct {
21	name      [32]byte
22	status    int32
23	flags     uint32
24	numFences uint32
25	pad       uint32
26	fences    uint64
27}
28
29// syncFenceInfo is struct sync_fence_info.
30type syncFenceInfo struct {
31	objName, driverName [32]byte
32	status              int32
33	flags               uint32
34	timestampNs         uint64
35}
36
37// fenceSignalledAt is when every fence of the sync file f signalled
38// (0: not signalled yet or unknown).
39func fenceSignalledAt(f *os.File) time.Duration {
40	info := syncFileInfo{}
41	if ioctl(int(f.Fd()), ioctlSyncFileInfo, unsafe.Pointer(&info)) != nil || info.numFences == 0 {
42		return 0
43	}
44	fences := make([]syncFenceInfo, info.numFences)
45	info.fences = uint64(uintptr(unsafe.Pointer(&fences[0])))
46	err := ioctl(int(f.Fd()), ioctlSyncFileInfo, unsafe.Pointer(&info))
47	runtime.KeepAlive(fences)
48	if err != nil {
49		return 0
50	}
51	var at uint64
52	for _, fi := range fences {
53		if fi.status != 1 {
54			return 0
55		}
56		at = max(at, fi.timestampNs)
57	}
58	return time.Duration(at)
59}
60
61// fencesSignalledAt is the latest signal time of fs (0: none, or one
62// unsignalled).
63func fencesSignalledAt(fs []*os.File) time.Duration {
64	var at time.Duration
65	for _, f := range fs {
66		t := fenceSignalledAt(f)
67		if t == 0 {
68			return 0
69		}
70		at = max(at, t)
71	}
72	return at
73}
74
75func monotonic() time.Duration {
76	var ts unix.Timespec
77	_ = unix.ClockGettime(unix.CLOCK_MONOTONIC, &ts)
78	return time.Duration(ts.Nano())
79}
80
81// traceFlip logs the completion ev of the commit f made at commitAt and
82// handled at now. prev is the previous frame flip's timestamp (0: none).
83// fenceAt is when its fences signalled (0: none or unknown).
84func (o *Output) traceFlip(ev flipEvent, f pendingFrame, commitAt, now, prev, fenceAt time.Duration) {
85	e := o.log.Debug().Str("connector", o.conn.name).Bool("frame", f.frame).Bool("async", f.async).Bool("vrr", o.vrrOn).
86		Bool("direct", f.zeroCopy != 0).Uint32("seq", ev.seq).
87		Float64("commit_to_flip_ms", ms(ev.when-commitAt)).Float64("flip_to_read_ms", ms(now-ev.when)).
88		Int("fences", len(f.fences)).Bool("fence_ready_at_commit", f.fenceReady)
89	if fenceAt != 0 {
90		e = e.Float64("commit_to_fence_ms", ms(fenceAt-commitAt)).Float64("fence_to_flip_ms", ms(ev.when-fenceAt))
91	}
92	if f.frame && prev != 0 {
93		e = e.Float64("flip_interval_ms", ms(ev.when-prev))
94	}
95	e.Msg("flip")
96}
97
98func ms(d time.Duration) float64 { return float64(d) / float64(time.Millisecond) }

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 25

Tags 10

↑↓ moveenter openesc close