From 0b9e59d666095ba4a5eaa4d00161e8768dbc0edf Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 21 Sep 2023 11:06:03 +0100 Subject: [PATCH] trace.h: Use side_ptr_t for event description Signed-off-by: Mathieu Desnoyers --- include/side/trace.h | 16 +++++++------- src/side.c | 52 ++++++++++++++++++++++++++------------------ src/tracer.c | 6 ++--- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/include/side/trace.h b/include/side/trace.h index b1394f0..d941616 100644 --- a/include/side/trace.h +++ b/include/side/trace.h @@ -661,10 +661,10 @@ struct side_event_state { }; struct side_event_description { - struct side_event_state *state; - const char *provider_name; - const char *event_name; - const struct side_event_field *fields; + side_ptr_t(struct side_event_state) state; + side_ptr_t(const char) provider_name; + side_ptr_t(const char) event_name; + side_ptr_t(const struct side_event_field) fields; side_ptr_t(const struct side_attr) attr; uint64_t flags; uint32_t version; @@ -1811,10 +1811,10 @@ struct side_event_description { }; \ _linkage struct side_event_description __attribute__((section("side_event_description"))) \ _identifier = { \ - .state = &(side_event_state__##_identifier), \ - .provider_name = _provider, \ - .event_name = _event, \ - .fields = _fields, \ + .state = SIDE_PTR_INIT(&(side_event_state__##_identifier)), \ + .provider_name = SIDE_PTR_INIT(_provider), \ + .event_name = SIDE_PTR_INIT(_event), \ + .fields = SIDE_PTR_INIT(_fields), \ .attr = SIDE_PTR_INIT(SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())), \ .flags = (_flags), \ .version = 0, \ diff --git a/src/side.c b/src/side.c index 3c0f1b2..67a5bd4 100644 --- a/src/side.c +++ b/src/side.c @@ -64,6 +64,7 @@ const struct side_callback side_empty_callback = { }; void side_call(const struct side_event_description *desc, const struct side_arg_vec *side_arg_vec) { + struct side_event_state *event_state; struct side_rcu_read_state rcu_read_state; const struct side_callback *side_cb; uintptr_t enabled; @@ -76,12 +77,13 @@ void side_call(const struct side_event_description *desc, const struct side_arg_ printf("ERROR: unexpected variadic event description\n"); abort(); } - enabled = __atomic_load_n(&desc->state->enabled, __ATOMIC_RELAXED); + event_state = side_ptr_get(desc->state); + enabled = __atomic_load_n(&event_state->enabled, __ATOMIC_RELAXED); if (side_unlikely(enabled & SIDE_EVENT_ENABLED_KERNEL_USER_EVENT_MASK)) { // TODO: call kernel write. } side_rcu_read_begin(&rcu_gp, &rcu_read_state); - for (side_cb = side_rcu_dereference(desc->state->callbacks); side_cb->u.call != NULL; side_cb++) + for (side_cb = side_rcu_dereference(event_state->callbacks); side_cb->u.call != NULL; side_cb++) side_cb->u.call(desc, side_arg_vec, side_cb->priv); side_rcu_read_end(&rcu_gp, &rcu_read_state); } @@ -90,6 +92,7 @@ void side_call_variadic(const struct side_event_description *desc, const struct side_arg_vec *side_arg_vec, const struct side_arg_dynamic_struct *var_struct) { + struct side_event_state *event_state; struct side_rcu_read_state rcu_read_state; const struct side_callback *side_cb; uintptr_t enabled; @@ -102,12 +105,13 @@ void side_call_variadic(const struct side_event_description *desc, printf("ERROR: unexpected non-variadic event description\n"); abort(); } - enabled = __atomic_load_n(&desc->state->enabled, __ATOMIC_RELAXED); + event_state = side_ptr_get(desc->state); + enabled = __atomic_load_n(&event_state->enabled, __ATOMIC_RELAXED); if (side_unlikely(enabled & SIDE_EVENT_ENABLED_KERNEL_USER_EVENT_MASK)) { // TODO: call kernel write. } side_rcu_read_begin(&rcu_gp, &rcu_read_state); - for (side_cb = side_rcu_dereference(desc->state->callbacks); side_cb->u.call_variadic != NULL; side_cb++) + for (side_cb = side_rcu_dereference(event_state->callbacks); side_cb->u.call_variadic != NULL; side_cb++) side_cb->u.call_variadic(desc, side_arg_vec, var_struct, side_cb->priv); side_rcu_read_end(&rcu_gp, &rcu_read_state); } @@ -117,9 +121,10 @@ const struct side_callback *side_tracer_callback_lookup( const struct side_event_description *desc, void *call, void *priv) { + struct side_event_state *event_state = side_ptr_get(desc->state); const struct side_callback *cb; - for (cb = desc->state->callbacks; cb->u.call != NULL; cb++) { + for (cb = event_state->callbacks; cb->u.call != NULL; cb++) { if ((void *) cb->u.call == call && cb->priv == priv) return cb; } @@ -130,6 +135,7 @@ static int _side_tracer_callback_register(struct side_event_description *desc, void *call, void *priv) { + struct side_event_state *event_state; struct side_callback *old_cb, *new_cb; int ret = SIDE_ERROR_OK; uint32_t old_nr_cb; @@ -141,7 +147,8 @@ int _side_tracer_callback_register(struct side_event_description *desc, if (!initialized) side_init(); pthread_mutex_lock(&side_lock); - old_nr_cb = desc->state->nr_callbacks; + event_state = side_ptr_get(desc->state); + old_nr_cb = event_state->nr_callbacks; if (old_nr_cb == UINT32_MAX) { ret = SIDE_ERROR_INVAL; goto unlock; @@ -151,7 +158,7 @@ int _side_tracer_callback_register(struct side_event_description *desc, ret = SIDE_ERROR_EXIST; goto unlock; } - old_cb = (struct side_callback *) desc->state->callbacks; + old_cb = (struct side_callback *) event_state->callbacks; /* old_nr_cb + 1 (new cb) + 1 (NULL) */ new_cb = (struct side_callback *) calloc(old_nr_cb + 2, sizeof(struct side_callback)); if (!new_cb) { @@ -166,14 +173,14 @@ int _side_tracer_callback_register(struct side_event_description *desc, new_cb[old_nr_cb].u.call = (side_tracer_callback_func) call; new_cb[old_nr_cb].priv = priv; - side_rcu_assign_pointer(desc->state->callbacks, new_cb); + side_rcu_assign_pointer(event_state->callbacks, new_cb); side_rcu_wait_grace_period(&rcu_gp); if (old_nr_cb) free(old_cb); - desc->state->nr_callbacks++; + event_state->nr_callbacks++; /* Increment concurrently with kernel setting the top bits. */ if (!old_nr_cb) - (void) __atomic_add_fetch(&desc->state->enabled, 1, __ATOMIC_RELAXED); + (void) __atomic_add_fetch(&event_state->enabled, 1, __ATOMIC_RELAXED); unlock: pthread_mutex_unlock(&side_lock); return ret; @@ -200,6 +207,7 @@ int side_tracer_callback_variadic_register(struct side_event_description *desc, static int _side_tracer_callback_unregister(struct side_event_description *desc, void *call, void *priv) { + struct side_event_state *event_state; struct side_callback *old_cb, *new_cb; const struct side_callback *cb_pos; uint32_t pos_idx; @@ -213,17 +221,18 @@ static int _side_tracer_callback_unregister(struct side_event_description *desc, if (!initialized) side_init(); pthread_mutex_lock(&side_lock); + event_state = side_ptr_get(desc->state); cb_pos = side_tracer_callback_lookup(desc, call, priv); if (!cb_pos) { ret = SIDE_ERROR_NOENT; goto unlock; } - old_nr_cb = desc->state->nr_callbacks; - old_cb = (struct side_callback *) desc->state->callbacks; + old_nr_cb = event_state->nr_callbacks; + old_cb = (struct side_callback *) event_state->callbacks; if (old_nr_cb == 1) { new_cb = (struct side_callback *) &side_empty_callback; } else { - pos_idx = cb_pos - desc->state->callbacks; + pos_idx = cb_pos - event_state->callbacks; /* Remove entry at pos_idx. */ /* old_nr_cb - 1 (removed cb) + 1 (NULL) */ new_cb = (struct side_callback *) calloc(old_nr_cb, sizeof(struct side_callback)); @@ -234,13 +243,13 @@ static int _side_tracer_callback_unregister(struct side_event_description *desc, memcpy(new_cb, old_cb, pos_idx); memcpy(&new_cb[pos_idx], &old_cb[pos_idx + 1], old_nr_cb - pos_idx - 1); } - side_rcu_assign_pointer(desc->state->callbacks, new_cb); + side_rcu_assign_pointer(event_state->callbacks, new_cb); side_rcu_wait_grace_period(&rcu_gp); free(old_cb); - desc->state->nr_callbacks--; + event_state->nr_callbacks--; /* Decrement concurrently with kernel setting the top bits. */ if (old_nr_cb == 1) - (void) __atomic_add_fetch(&desc->state->enabled, -1, __ATOMIC_RELAXED); + (void) __atomic_add_fetch(&event_state->enabled, -1, __ATOMIC_RELAXED); unlock: pthread_mutex_unlock(&side_lock); return ret; @@ -294,20 +303,21 @@ struct side_events_register_handle *side_events_register(struct side_event_descr static void side_event_remove_callbacks(struct side_event_description *desc) { - uint32_t nr_cb = desc->state->nr_callbacks; + struct side_event_state *event_state = side_ptr_get(desc->state); + uint32_t nr_cb = event_state->nr_callbacks; struct side_callback *old_cb; if (!nr_cb) return; - old_cb = (struct side_callback *) desc->state->callbacks; - (void) __atomic_add_fetch(&desc->state->enabled, -1, __ATOMIC_RELAXED); + old_cb = (struct side_callback *) event_state->callbacks; + (void) __atomic_add_fetch(&event_state->enabled, -1, __ATOMIC_RELAXED); /* * Setting the state back to 0 cb and empty callbacks out of * caution. This should not matter because instrumentation is * unreachable. */ - desc->state->nr_callbacks = 0; - side_rcu_assign_pointer(desc->state->callbacks, &side_empty_callback); + event_state->nr_callbacks = 0; + side_rcu_assign_pointer(event_state->callbacks, &side_empty_callback); /* * No need to wait for grace period because instrumentation is * unreachable. diff --git a/src/tracer.c b/src/tracer.c index c668e4a..2e76aa7 100644 --- a/src/tracer.c +++ b/src/tracer.c @@ -1723,7 +1723,7 @@ void tracer_print_static_fields(const struct side_event_description *desc, const struct side_arg *sav = side_ptr_get(side_arg_vec->sav); uint32_t i, side_sav_len = side_arg_vec->len; - printf("provider: %s, event: %s", desc->provider_name, desc->event_name); + printf("provider: %s, event: %s", side_ptr_get(desc->provider_name), side_ptr_get(desc->event_name)); if (desc->nr_fields != side_sav_len) { fprintf(stderr, "ERROR: number of fields mismatch between description and arguments\n"); abort(); @@ -1732,7 +1732,7 @@ void tracer_print_static_fields(const struct side_event_description *desc, printf("%s", side_sav_len ? ", fields: [ " : ""); for (i = 0; i < side_sav_len; i++) { printf("%s", i ? ", " : ""); - tracer_print_field(&desc->fields[i], &sav[i]); + tracer_print_field(&side_ptr_get(desc->fields)[i], &sav[i]); } if (nr_items) *nr_items = i; @@ -1795,7 +1795,7 @@ void tracer_event_notification(enum side_tracer_notification notif, if (!event) continue; printf("provider: %s, event: %s\n", - event->provider_name, event->event_name); + side_ptr_get(event->provider_name), side_ptr_get(event->event_name)); if (notif == SIDE_TRACER_NOTIFICATION_INSERT_EVENTS) { if (event->flags & SIDE_EVENT_FLAG_VARIADIC) { ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL); -- 2.34.1