Skip to content

Commit 36c0c19

Browse files
committed
Add DTrace script to monitor viona activity
1 parent 2dc6437 commit 36c0c19

2 files changed

Lines changed: 251 additions & 0 deletions

File tree

scripts/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ individual files for details.
1414
- `vm_exit_codes.d`: Measure VM exits and information about them both for
1515
#VMEXIT events and returns to Propolis.
1616
- `cpuid-queries.d`: Report guest CPUID queries and returned leaves.
17+
- `viona.d`: Report Viona ioctl and notification events in real time.

scripts/viona.d

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
#!/usr/sbin/dtrace -qCs
2+
3+
#pragma D option quiet
4+
5+
/*
6+
* Dtrace ioctl calls into the viona kernel module as they occur, and show
7+
* in-kernel ring notifications.
8+
*
9+
* This script needs the `viona` module to be loaded. If you want to run it
10+
* before starting a VM utter: `modload /usr/kernel/drv/amd64/viona`
11+
*/
12+
13+
#define VNA_IOC (('V' << 16)|('C' << 8))
14+
#define VNA_IOC_CREATE (VNA_IOC | 0x01)
15+
#define VNA_IOC_DELETE (VNA_IOC | 0x02)
16+
#define VNA_IOC_VERSION (VNA_IOC | 0x03)
17+
#define VNA_IOC_DEFAULT_PARAMS (VNA_IOC | 0x04)
18+
19+
#define VNA_IOC_RING_INIT (VNA_IOC | 0x10)
20+
#define VNA_IOC_RING_RESET (VNA_IOC | 0x11)
21+
#define VNA_IOC_RING_KICK (VNA_IOC | 0x12)
22+
#define VNA_IOC_RING_SET_MSI (VNA_IOC | 0x13)
23+
#define VNA_IOC_RING_INTR_CLR (VNA_IOC | 0x14)
24+
#define VNA_IOC_RING_SET_STATE (VNA_IOC | 0x15)
25+
#define VNA_IOC_RING_GET_STATE (VNA_IOC | 0x16)
26+
#define VNA_IOC_RING_PAUSE (VNA_IOC | 0x17)
27+
#define VNA_IOC_RING_INIT_MODERN (VNA_IOC | 0x18)
28+
29+
#define VNA_IOC_INTR_POLL (VNA_IOC | 0x20)
30+
#define VNA_IOC_SET_FEATURES (VNA_IOC | 0x21)
31+
#define VNA_IOC_GET_FEATURES (VNA_IOC | 0x22)
32+
#define VNA_IOC_SET_NOTIFY_IOP (VNA_IOC | 0x23)
33+
#define VNA_IOC_SET_PROMISC (VNA_IOC | 0x24)
34+
#define VNA_IOC_GET_PARAMS (VNA_IOC | 0x25)
35+
#define VNA_IOC_SET_PARAMS (VNA_IOC | 0x26)
36+
#define VNA_IOC_GET_MTU (VNA_IOC | 0x27)
37+
#define VNA_IOC_SET_MTU (VNA_IOC | 0x28)
38+
#define VNA_IOC_SET_NOTIFY_MMIO (VNA_IOC | 0x29)
39+
#define VNA_IOC_INTR_POLL_MQ (VNA_IOC | 0x2a)
40+
41+
#define VNA_IOC_GET_PAIRS (VNA_IOC | 0x30)
42+
#define VNA_IOC_SET_PAIRS (VNA_IOC | 0x31)
43+
#define VNA_IOC_GET_USEPAIRS (VNA_IOC | 0x32)
44+
#define VNA_IOC_SET_USEPAIRS (VNA_IOC | 0x33)
45+
46+
BEGIN {
47+
printf("Tracing...\n");
48+
}
49+
50+
viona_ioctl:entry {
51+
self->dptr = arg2;
52+
self->rvp = args[5];
53+
}
54+
55+
viona_ioctl:entry/arg1 == VNA_IOC_CREATE/ {
56+
self->cmd = "CREATE";
57+
create = (vioc_create_t *)copyin(arg2, sizeof (vioc_create_t));
58+
printf("%s (link 0x%x)\n", self->cmd, create->c_linkid);
59+
}
60+
61+
viona_ioctl:entry/arg1 == VNA_IOC_DELETE/ {
62+
self->cmd = "DELETE";
63+
printf("%s\n", self->cmd);
64+
}
65+
66+
viona_ioctl:entry/arg1 == VNA_IOC_VERSION/ {
67+
self->pending = arg1;
68+
}
69+
70+
viona_ioctl:return/self->pending == VNA_IOC_VERSION/ {
71+
printf("VERSION 0x%x\n", *self->rvp);
72+
}
73+
74+
viona_ioctl:entry/arg1 == VNA_IOC_DEFAULT_PARAMS/ {
75+
self->cmd = "DEFAULT_PARAMS";
76+
printf("%s\n", self->cmd);
77+
}
78+
79+
viona_ioctl:entry/arg1 == VNA_IOC_RING_INIT/ {
80+
self->cmd = "RING_INIT";
81+
init = (vioc_ring_init_t *)copyin(arg2, sizeof (vioc_ring_init_t));
82+
printf("%s 0x%x %x %x\n", self->cmd,
83+
init->ri_index, init->ri_qaddr, init->ri_qsize);
84+
}
85+
86+
viona_ioctl:entry/arg1 == VNA_IOC_RING_INIT_MODERN/ {
87+
self->cmd = "RING_INIT_MODERN";
88+
initm = (vioc_ring_init_modern_t *)copyin(arg2,
89+
sizeof (vioc_ring_init_modern_t));
90+
printf("%s 0x%x %x/%x/%x %x\n", self->cmd,
91+
initm->rim_index, initm->rim_qaddr_desc, initm->rim_qaddr_avail,
92+
initm->rim_qaddr_used, initm->rim_qsize);
93+
}
94+
95+
viona_ioctl:entry/arg1 == VNA_IOC_RING_RESET/ {
96+
self->cmd = "RING_RESET";
97+
printf("%s 0x%x\n", self->cmd, arg2);
98+
}
99+
100+
viona_ioctl:entry/arg1 == VNA_IOC_RING_KICK/ {
101+
self->cmd = "RING_KICK";
102+
printf("%s 0x%x\n", self->cmd, arg2);
103+
}
104+
105+
viona_ioctl:entry/arg1 == VNA_IOC_RING_SET_MSI/ {
106+
self->cmd = "RING_SET_MSI";
107+
msi = (vioc_ring_msi_t *)copyin(arg2, sizeof (vioc_ring_msi_t));
108+
printf("%s 0x%x addr=%x msg=%x\n", self->cmd,
109+
msi->rm_index, msi->rm_addr, msi->rm_msg);
110+
}
111+
112+
viona_ioctl:entry/arg1 == VNA_IOC_RING_INTR_CLR/ {
113+
self->cmd = "RING_INTR_CLR";
114+
printf("%s 0x%x\n", self->cmd, arg2);
115+
}
116+
117+
viona_ioctl:entry/arg1 == VNA_IOC_RING_SET_STATE/ {
118+
self->cmd = "RING_SET_STATE";
119+
printf("%s\n", self->cmd);
120+
}
121+
122+
viona_ioctl:entry/arg1 == VNA_IOC_RING_GET_STATE/ {
123+
self->pending = arg1;
124+
}
125+
126+
viona_ioctl:return/self->pending == VNA_IOC_RING_GET_STATE/ {
127+
self->pending = 0;
128+
statep = (vioc_ring_state_t *)copyin(self->dptr,
129+
sizeof (vioc_ring_state_t));
130+
printf("GET_STATE %x %x/%x/%x AV %x USED %x\n",
131+
statep->vrs_index, statep->vrs_qaddr_desc, statep->vrs_qaddr_avail,
132+
statep->vrs_qaddr_used, statep->vrs_avail_idx,
133+
statep->vrs_used_idx);
134+
}
135+
136+
viona_ioctl:entry/arg1 == VNA_IOC_RING_PAUSE/ {
137+
self->cmd = "RING_PAUSE";
138+
printf("%s 0x%x\n", self->cmd, arg2);
139+
}
140+
141+
viona_ioctl:entry/arg1 == VNA_IOC_INTR_POLL_MQ/ {
142+
self->pending = arg1;
143+
}
144+
145+
viona_ioctl:return/self->pending == VNA_IOC_INTR_POLL_MQ/ {
146+
self->pending = 0;
147+
intrp = (vioc_intr_poll_mq_t *)copyin(self->dptr,
148+
sizeof (vioc_intr_poll_mq_t));
149+
printf("INTR_POLL %x set (0x%08x)\n", *self->rvp,
150+
intrp->vipm_status[0]);
151+
}
152+
153+
viona_ioctl:entry/arg1 == VNA_IOC_SET_FEATURES/ {
154+
self->cmd = "SET_FEATURES";
155+
featp = (uint64_t *)copyin(arg2, sizeof (uint64_t));
156+
printf("%s 0x%x\n", self->cmd, *featp);
157+
}
158+
159+
viona_ioctl:entry/arg1 == VNA_IOC_GET_FEATURES/ {
160+
self->pending = arg1;;
161+
}
162+
163+
viona_ioctl:return/self->pending == VNA_IOC_GET_FEATURES/ {
164+
self->pending = 0;
165+
gfeatp = (uint64_t *)copyin(self->dptr, sizeof (uint64_t));
166+
printf("GET_FEATURES 0x%x\n", *gfeatp);
167+
}
168+
169+
viona_ioctl:entry/arg1 == VNA_IOC_SET_NOTIFY_IOP/ {
170+
self->cmd = "SET_NOTIFY_IOP";
171+
printf("%s 0x%x\n", self->cmd, arg2);
172+
}
173+
174+
viona_ioctl:entry/arg1 == VNA_IOC_SET_PROMISC/ {
175+
self->cmd = "SET_PROMISC";
176+
printf("%s\n", self->cmd);
177+
}
178+
179+
viona_ioctl:entry/arg1 == VNA_IOC_GET_PARAMS/ {
180+
self->cmd = "GET_PARAMS";
181+
printf("%s\n", self->cmd);
182+
}
183+
184+
viona_ioctl:entry/arg1 == VNA_IOC_SET_PARAMS/ {
185+
self->cmd = "SET_PARAMS";
186+
printf("%s\n", self->cmd);
187+
}
188+
189+
viona_ioctl:entry/arg1 == VNA_IOC_GET_MTU/ {
190+
self->cmd = "GET_MTU";
191+
printf("%s\n", self->cmd);
192+
}
193+
194+
viona_ioctl:entry/arg1 == VNA_IOC_SET_MTU/ {
195+
self->cmd = "SET_MTU";
196+
printf("%s %u\n", self->cmd, arg2);
197+
}
198+
199+
viona_ioctl:entry/arg1 == VNA_IOC_SET_NOTIFY_MMIO && !arg2/ {
200+
self->cmd = "SET_NOTIFY_MMIO <NULL>";
201+
printf("%s\n", self->cmd);
202+
}
203+
204+
viona_ioctl:entry/arg1 == VNA_IOC_SET_NOTIFY_MMIO && arg2/ {
205+
self->cmd = "SET_NOTIFY_MMIO";
206+
mmio = (vioc_notify_mmio_t *)copyin(arg2, sizeof (vioc_notify_mmio_t));
207+
printf("%s %x+%x\n", self->cmd, mmio->vim_address, mmio->vim_size);
208+
}
209+
210+
viona_ioctl:entry/arg1 == VNA_IOC_GET_PAIRS/ {
211+
self->cmd = "GET_PAIRS";
212+
printf("%s\n", self->cmd);
213+
}
214+
215+
viona_ioctl:entry/arg1 == VNA_IOC_SET_PAIRS/ {
216+
self->cmd = "SET_PAIRS";
217+
printf("%s 0x%x\n", self->cmd, arg2);
218+
}
219+
220+
viona_ioctl:entry/arg1 == VNA_IOC_GET_USEPAIRS/ {
221+
self->cmd = "GET_USEPAIRS";
222+
printf("%s\n", self->cmd);
223+
}
224+
225+
viona_ioctl:entry/arg1 == VNA_IOC_SET_USEPAIRS/ {
226+
self->cmd = "SET_USEPAIRS";
227+
printf("%s 0x%x\n", self->cmd, arg2);
228+
}
229+
230+
viona_notify_iop:entry/arg1/ {
231+
printf("IOP NOTIFY read %x+%x\n", arg2, arg3);
232+
}
233+
234+
viona_notify_iop:entry/!arg1/ {
235+
printf("IOP NOTIFY write %x+%x = %x\n", arg2, arg3, *args[4]);
236+
}
237+
238+
viona_notify_mmio:entry/!arg1/ {
239+
printf("MMIO NOTIFY read %x+%x\n", arg2, arg3);
240+
}
241+
242+
viona_notify_mmio:entry/arg1/ {
243+
printf("MMIO NOTIFY write %x+%x = %x\n", arg2, arg3, *args[4]);
244+
}
245+
246+
viona_ioctl:return/self->cmd != 0 && arg1 != 0/ {
247+
printf("ioctl(%s) returning 0x%x\n", self->cmd, arg1);
248+
self->cmd = 0;
249+
}
250+

0 commit comments

Comments
 (0)