Skip to content

Commit b8ad60a

Browse files
committed
[UserEvents] Register configured tracepoints
1 parent ba894a5 commit b8ad60a

File tree

7 files changed

+161
-2
lines changed

7 files changed

+161
-2
lines changed

src/native/eventpipe/configure.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ if (CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID)
1717
set(FEATURE_PERFTRACING_DISABLE_DEFAULT_LISTEN_PORT 1)
1818
endif()
1919

20+
check_include_files(
21+
"linux/user_events.h;sys/ioctl.h"
22+
HAVE_LINUX_USER_EVENTS_H
23+
)
24+
2025
if (NOT DEFINED EP_GENERATED_HEADER_PATH)
2126
message(FATAL_ERROR "Required configuration EP_GENERATED_HEADER_PATH not set.")
2227
endif (NOT DEFINED EP_GENERATED_HEADER_PATH)

src/native/eventpipe/ep-session-provider.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@ ep_session_provider_alloc (
5151
uint64_t keywords,
5252
EventPipeEventLevel logging_level,
5353
const ep_char8_t *filter_data)
54+
{
55+
return ep_session_provider_alloc (
56+
provider_name,
57+
keywords,
58+
logging_level,
59+
filter_data,
60+
NULL,
61+
NULL);
62+
}
63+
64+
EventPipeSessionProvider *
65+
ep_session_provider_alloc (
66+
const ep_char8_t *provider_name,
67+
uint64_t keywords,
68+
EventPipeEventLevel logging_level,
69+
const ep_char8_t *filter_data,
70+
EventPipeEventFilter *event_filter,
71+
ProviderTracepointConfiguration *tracepoint_config)
5472
{
5573
EventPipeSessionProvider *instance = ep_rt_object_alloc (EventPipeSessionProvider);
5674
ep_raise_error_if_nok (instance != NULL);
@@ -67,6 +85,8 @@ ep_session_provider_alloc (
6785

6886
instance->keywords = keywords;
6987
instance->logging_level = logging_level;
88+
instance->event_filter = event_filter;
89+
instance->tracepoint_config = tracepoint_config;
7090

7191
ep_on_exit:
7292
return instance;
@@ -169,7 +189,9 @@ ep_session_provider_list_alloc (
169189
ep_provider_config_get_provider_name (config),
170190
ep_provider_config_get_keywords (config),
171191
ep_provider_config_get_logging_level (config),
172-
ep_provider_config_get_filter_data (config));
192+
ep_provider_config_get_filter_data (config),
193+
ep_provider_config_get_event_filter (config),
194+
ep_provider_config_get_tracepoint_config (config));
173195
ep_raise_error_if_nok (dn_list_push_back (instance->providers, session_provider));
174196
}
175197
}

src/native/eventpipe/ep-session-provider.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ struct _EventPipeSessionProvider_Internal {
2424
uint64_t keywords;
2525
EventPipeEventLevel logging_level;
2626
ep_char8_t *filter_data;
27+
EventPipeEventFilter *event_filter;
28+
ProviderTracepointConfiguration *tracepoint_config;
29+
dn_umap_t *event_id_to_tracepoint_map;
30+
EventPipeTracepoint *default_tracepoint;
2731
};
2832

2933
#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_SESSION_PROVIDER_GETTER_SETTER)
@@ -36,6 +40,10 @@ EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, const ep_char8_t
3640
EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, uint64_t, keywords)
3741
EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, EventPipeEventLevel, logging_level)
3842
EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, const ep_char8_t *, filter_data)
43+
EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, EventPipeEventFilter *, event_filter)
44+
EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, ProviderTracepointConfiguration *, tracepoint_config)
45+
EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, dn_umap_t *, event_id_to_tracepoint_map)
46+
EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, EventPipeTracepoint *, default_tracepoint)
3947

4048
EventPipeSessionProvider *
4149
ep_session_provider_alloc (
@@ -44,6 +52,15 @@ ep_session_provider_alloc (
4452
EventPipeEventLevel logging_level,
4553
const ep_char8_t *filter_data);
4654

55+
EventPipeSessionProvider *
56+
ep_session_provider_alloc (
57+
const ep_char8_t *provider_name,
58+
uint64_t keywords,
59+
EventPipeEventLevel logging_level,
60+
const ep_char8_t *filter_data,
61+
EventPipeEventFilter *event_filter,
62+
ProviderTracepointConfiguration *tracepoint_config);
63+
4764
void
4865
ep_session_provider_free (EventPipeSessionProvider * session_provider);
4966

src/native/eventpipe/ep-session.c

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,110 @@ session_disable_streaming_thread (EventPipeSession *session)
154154
ep_rt_wait_event_free (rt_thread_shutdown_event);
155155
}
156156

157+
static
158+
uint32_t
159+
event_reg(uint32_t fd, const char *command, uint32_t *write, uint32_t *enabled)
160+
{
161+
#ifdef HAVE_LINUX_USER_EVENTS_H
162+
struct user_reg reg = {0};
163+
164+
reg.size = sizeof(reg); // uint32_t
165+
reg.enable_bit = 31; // uint8_t
166+
reg.enable_size = sizeof(*enabled); // uint8_t
167+
// reg.flags //uint16_t
168+
reg.enable_addr = (uint64_t)enabled; // uint64_t
169+
reg.name_args = (uint64_t)command; // uint64_t
170+
171+
if (ioctl(fd, DIAG_IOCSREG, &reg) == -1)
172+
return -1;
173+
174+
*write = reg.write_index; // uint32_t
175+
176+
return 0;
177+
#else // HAVE_LINUX_USER_EVENTS_H
178+
// Not Supported
179+
return -1;
180+
#endif // HAVE_LINUX_USER_EVENTS_H
181+
}
182+
183+
// Could bump this to when we are deserializing the payload
184+
// And then the ProviderConfigurations would instead own the actual
185+
// Tracepoint info like write_index, enable bit, mapping
186+
static
187+
void
188+
ep_session_user_events_tracepoints_init (
189+
EventPipeSession *session)
190+
{
191+
EP_ASSERT (session != NULL);
192+
EP_ASSERT (session->session_type == EP_SESSION_TYPE_USEREVENTS);
193+
194+
EP_ASSERT (session->user_events_data_fd != 0);
195+
196+
EventPipeSessionProviderList *providers = ep_session_get_providers (session);
197+
EP_ASSERT (providers != NULL);
198+
199+
// Create a mapping of event_id to Tracepoint that we generate, for writing.
200+
for (dn_list_it_t it = dn_list_begin (ep_session_provider_list_get_providers (providers)); !dn_list_it_end (it); it = dn_list_it_next (it)) {
201+
EventPipeSessionProvider *session_provider = *dn_list_it_data_t (it, EventPipeSessionProvider *);
202+
EP_ASSERT (session_provider != NULL);
203+
204+
// Should this be owned by each EventPipeSession ProviderConfiguration
205+
dn_umap_custom_alloc_params_t params = {0, };
206+
params.hash_func = dn_int_hash;
207+
params.equal_func = dn_int_equal;
208+
dn_umap_t *provider_event_id_to_tracepoint_map = dn_umap_custom_alloc (&params);
209+
210+
// Should we bother to register tracepoints whos events don't pass the event_filter?
211+
ProviderTracepointConfiguration *tracepoint_config = ep_session_provider_get_tracepoint_config (session_provider);
212+
213+
dn_vector_t *tracepoints = tracepoint_config->tracepoints;
214+
if (tracepoints != NULL) {
215+
for (int32_t i = 0; i < tracepoints->size; ++i) {
216+
// Get the tracepoint set
217+
ProviderTracepointSet *tracepoint_set = *dn_vector_index_t (tracepoints, ProviderTracepointSet *, i);
218+
EP_ASSERT (tracepoint_set != NULL);
219+
220+
// Get the tracepoint name for this set
221+
const ep_char8_t *tracepoint_name = tracepoint_set->tracepoint_name;
222+
EP_ASSERT (tracepoint_name != NULL);
223+
224+
EventPipeTracepoint *tracepoint = ep_rt_object_alloc (EventPipeTracepoint);
225+
EP_ASSERT(tracepoint != NULL);
226+
if (event_reg (session->user_events_data_fd, tracepoint_name, &tracepoint->write_index, &tracepoint->enabled) == -1) {
227+
ep_raise_error ();
228+
}
229+
230+
dn_vector_t *event_ids = tracepoint_set->event_ids;
231+
if (event_ids != NULL) {
232+
for (int32_t j = 0; j < event_ids->size; ++j) {
233+
uint32_t *event_id = dn_vector_index_t (event_ids, uint32_t, j);
234+
dn_umap_result_t result = dn_umap_insert (provider_event_id_to_tracepoint_map, event_id, tracepoint);
235+
EP_ASSERT (result.result);
236+
}
237+
}
238+
}
239+
}
240+
session_provider->event_id_to_tracepoint_map = provider_event_id_to_tracepoint_map;
241+
242+
const ep_char8_t *default_tracepoint_name = tracepoint_config->default_tracepoint_name;
243+
if (default_tracepoint_name != NULL) {
244+
EventPipeTracepoint *default_tracepoint = ep_rt_object_alloc (EventPipeTracepoint);
245+
EP_ASSERT(default_tracepoint != NULL);
246+
if (event_reg (session->user_events_data_fd, default_tracepoint_name, &default_tracepoint->write_index, &default_tracepoint->enabled) == -1) {
247+
ep_raise_error ();
248+
}
249+
250+
session_provider->default_tracepoint = default_tracepoint;
251+
}
252+
}
253+
254+
ep_on_exit:
255+
return;
256+
257+
ep_on_error:
258+
ep_exit_error_handler ();
259+
}
260+
157261
EventPipeSession *
158262
ep_session_alloc (
159263
uint32_t index,
@@ -236,7 +340,7 @@ ep_session_alloc (
236340
// Transfer ownership of the user_events_data file descriptor to the EventPipe Session.
237341
instance->user_events_data_fd = user_events_data_fd;
238342
// With the user_events_data file, register tracepoints for each provider's tracepoint configurations
239-
// ep_session_user_events_tracepoints_init (instance);
343+
ep_session_user_events_tracepoints_init (instance);
240344
break;
241345

242346
default:

src/native/eventpipe/ep-session.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
#endif
1414
#include "ep-getter-setter.h"
1515

16+
#ifdef HAVE_LINUX_USER_EVENTS_H
17+
#include <linux/user_events.h> // DIAG_IOCSREG
18+
#include <sys/ioctl.h> // event_reg
19+
#endif // HAVE_LINUX_USER_EVENTS_H
20+
1621
/*
1722
* EventPipeSession.
1823
*/

src/native/eventpipe/ep-shared-config.h.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define EP_SHARED_CONFIG_H_INCLUDED
33

44
#cmakedefine01 HAVE_SYS_SOCKET_H
5+
#cmakedefine01 HAVE_LINUX_USER_EVENTS_H
56
/* This platforms supports setting flags atomically when accepting connections. */
67
#cmakedefine01 HAVE_ACCEPT4
78

src/native/eventpipe/ep-types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ ep_provider_callback_data_queue_try_dequeue (
175175
EventPipeProviderCallbackDataQueue *provider_callback_data_queue,
176176
EventPipeProviderCallbackData *provider_callback_data);
177177

178+
struct EventPipeTracepoint {
179+
uint32_t write_index;
180+
uint32_t enabled;
181+
};
182+
178183
struct EventPipeEventFilter {
179184
bool enable;
180185
dn_vector_t *event_ids;

0 commit comments

Comments
 (0)