From: Mathieu Desnoyers Date: Fri, 15 Dec 2023 19:17:00 +0000 (-0500) Subject: Add "key" to callback registration X-Git-Url: http://git.efficios.com/?p=libside.git;a=commitdiff_plain;h=92c377f9b51720376d64c8d7c5bb5a2f67eabc9d Add "key" to callback registration This is in preparation to support the state-dump feature. Signed-off-by: Mathieu Desnoyers --- diff --git a/include/side/trace.h b/include/side/trace.h index 5df637f..22d88c7 100644 --- a/include/side/trace.h +++ b/include/side/trace.h @@ -81,6 +81,13 @@ void side_call(const struct side_event_state *state, void side_call_variadic(const struct side_event_state *state, const struct side_arg_vec *side_arg_vec, const struct side_arg_dynamic_struct *var_struct); +void side_call_key(const struct side_event_state *state, + const struct side_arg_vec *side_arg_vec, + void *key); +void side_call_variadic_key(const struct side_event_state *state, + const struct side_arg_vec *side_arg_vec, + const struct side_arg_dynamic_struct *var_struct, + void *key); struct side_events_register_handle *side_events_register(struct side_event_description **events, uint32_t nr_events); @@ -102,16 +109,16 @@ typedef void (*side_tracer_callback_variadic_func)(const struct side_event_descr int side_tracer_callback_register(struct side_event_description *desc, side_tracer_callback_func call, - void *priv); + void *priv, void *key); int side_tracer_callback_variadic_register(struct side_event_description *desc, side_tracer_callback_variadic_func call_variadic, - void *priv); + void *priv, void *key); int side_tracer_callback_unregister(struct side_event_description *desc, side_tracer_callback_func call, - void *priv); + void *priv, void *key); int side_tracer_callback_variadic_unregister(struct side_event_description *desc, side_tracer_callback_variadic_func call_variadic, - void *priv); + void *priv, void *key); enum side_tracer_notification { SIDE_TRACER_NOTIFICATION_INSERT_EVENTS, diff --git a/src/side.c b/src/side.c index b781712..67f57be 100644 --- a/src/side.c +++ b/src/side.c @@ -49,6 +49,7 @@ struct side_callback { void *priv); } u; void *priv; + void *key; }; static struct side_rcu_gp_state rcu_gp; @@ -76,7 +77,7 @@ static DEFINE_SIDE_LIST_HEAD(side_tracer_list); */ const char side_empty_callback[sizeof(struct side_callback)]; -void side_call(const struct side_event_state *event_state, const struct side_arg_vec *side_arg_vec) +void side_call_key(const struct side_event_state *event_state, const struct side_arg_vec *side_arg_vec, void *key) { struct side_rcu_read_state rcu_read_state; const struct side_event_state_0 *es0; @@ -96,14 +97,24 @@ void side_call(const struct side_event_state *event_state, const struct side_arg // TODO: call kernel write. } side_rcu_read_begin(&rcu_gp, &rcu_read_state); - for (side_cb = side_rcu_dereference(es0->callbacks); side_cb->u.call != NULL; side_cb++) + for (side_cb = side_rcu_dereference(es0->callbacks); side_cb->u.call != NULL; side_cb++) { + /* A NULL key is always a match. */ + if (key && side_cb->key && side_cb->key != key) + continue; side_cb->u.call(es0->desc, side_arg_vec, side_cb->priv); + } side_rcu_read_end(&rcu_gp, &rcu_read_state); } -void side_call_variadic(const struct side_event_state *event_state, +void side_call(const struct side_event_state *event_state, const struct side_arg_vec *side_arg_vec) +{ + side_call_key(event_state, side_arg_vec, NULL); +} + +void side_call_variadic_key(const struct side_event_state *event_state, const struct side_arg_vec *side_arg_vec, - const struct side_arg_dynamic_struct *var_struct) + const struct side_arg_dynamic_struct *var_struct, + void *key) { struct side_rcu_read_state rcu_read_state; const struct side_event_state_0 *es0; @@ -123,15 +134,26 @@ void side_call_variadic(const struct side_event_state *event_state, // TODO: call kernel write. } side_rcu_read_begin(&rcu_gp, &rcu_read_state); - for (side_cb = side_rcu_dereference(es0->callbacks); side_cb->u.call_variadic != NULL; side_cb++) + for (side_cb = side_rcu_dereference(es0->callbacks); side_cb->u.call_variadic != NULL; side_cb++) { + /* A NULL key is always a match. */ + if (key && side_cb->key && side_cb->key != key) + continue; side_cb->u.call_variadic(es0->desc, side_arg_vec, var_struct, side_cb->priv); + } side_rcu_read_end(&rcu_gp, &rcu_read_state); } +void side_call_variadic(const struct side_event_state *event_state, + const struct side_arg_vec *side_arg_vec, + const struct side_arg_dynamic_struct *var_struct) +{ + side_call_variadic_key(event_state, side_arg_vec, var_struct, NULL); +} + static const struct side_callback *side_tracer_callback_lookup( const struct side_event_description *desc, - void *call, void *priv) + void *call, void *priv, void *key) { struct side_event_state *event_state = side_ptr_get(desc->state); const struct side_event_state_0 *es0; @@ -141,7 +163,7 @@ const struct side_callback *side_tracer_callback_lookup( abort(); es0 = side_container_of(event_state, const struct side_event_state_0, parent); for (cb = es0->callbacks; cb->u.call != NULL; cb++) { - if ((void *) cb->u.call == call && cb->priv == priv) + if ((void *) cb->u.call == call && cb->priv == priv && cb->key == key) return cb; } return NULL; @@ -149,7 +171,7 @@ const struct side_callback *side_tracer_callback_lookup( static int _side_tracer_callback_register(struct side_event_description *desc, - void *call, void *priv) + void *call, void *priv, void *key) { struct side_event_state *event_state; struct side_callback *old_cb, *new_cb; @@ -174,7 +196,7 @@ int _side_tracer_callback_register(struct side_event_description *desc, goto unlock; } /* Reject duplicate (call, priv) tuples. */ - if (side_tracer_callback_lookup(desc, call, priv)) { + if (side_tracer_callback_lookup(desc, call, priv, key)) { ret = SIDE_ERROR_EXIST; goto unlock; } @@ -193,6 +215,7 @@ 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; + new_cb[old_nr_cb].key = key; /* High order bits are already zeroed. */ side_rcu_assign_pointer(es0->callbacks, new_cb); side_rcu_wait_grace_period(&rcu_gp); @@ -209,24 +232,24 @@ unlock: int side_tracer_callback_register(struct side_event_description *desc, side_tracer_callback_func call, - void *priv) + void *priv, void *key) { if (desc->flags & SIDE_EVENT_FLAG_VARIADIC) return SIDE_ERROR_INVAL; - return _side_tracer_callback_register(desc, (void *) call, priv); + return _side_tracer_callback_register(desc, (void *) call, priv, key); } int side_tracer_callback_variadic_register(struct side_event_description *desc, side_tracer_callback_variadic_func call_variadic, - void *priv) + void *priv, void *key) { if (!(desc->flags & SIDE_EVENT_FLAG_VARIADIC)) return SIDE_ERROR_INVAL; - return _side_tracer_callback_register(desc, (void *) call_variadic, priv); + return _side_tracer_callback_register(desc, (void *) call_variadic, priv, key); } static int _side_tracer_callback_unregister(struct side_event_description *desc, - void *call, void *priv) + void *call, void *priv, void *key) { struct side_event_state *event_state; struct side_callback *old_cb, *new_cb; @@ -247,7 +270,7 @@ static int _side_tracer_callback_unregister(struct side_event_description *desc, if (side_unlikely(event_state->version != 0)) abort(); es0 = side_container_of(event_state, struct side_event_state_0, parent); - cb_pos = side_tracer_callback_lookup(desc, call, priv); + cb_pos = side_tracer_callback_lookup(desc, call, priv, key); if (!cb_pos) { ret = SIDE_ERROR_NOENT; goto unlock; @@ -283,20 +306,20 @@ unlock: int side_tracer_callback_unregister(struct side_event_description *desc, side_tracer_callback_func call, - void *priv) + void *priv, void *key) { if (desc->flags & SIDE_EVENT_FLAG_VARIADIC) return SIDE_ERROR_INVAL; - return _side_tracer_callback_unregister(desc, (void *) call, priv); + return _side_tracer_callback_unregister(desc, (void *) call, priv, key); } int side_tracer_callback_variadic_unregister(struct side_event_description *desc, side_tracer_callback_variadic_func call_variadic, - void *priv) + void *priv, void *key) { if (!(desc->flags & SIDE_EVENT_FLAG_VARIADIC)) return SIDE_ERROR_INVAL; - return _side_tracer_callback_unregister(desc, (void *) call_variadic, priv); + return _side_tracer_callback_unregister(desc, (void *) call_variadic, priv, key); } struct side_events_register_handle *side_events_register(struct side_event_description **events, uint32_t nr_events) diff --git a/src/tracer.c b/src/tracer.c index e4ccd86..427f9e6 100644 --- a/src/tracer.c +++ b/src/tracer.c @@ -2120,21 +2120,21 @@ void tracer_event_notification(enum side_tracer_notification notif, event->nr_side_attr_type - _NR_SIDE_ATTR_TYPE); } if (event->flags & SIDE_EVENT_FLAG_VARIADIC) { - ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL); + ret = side_tracer_callback_variadic_register(event, tracer_call_variadic, NULL, NULL); if (ret) abort(); } else { - ret = side_tracer_callback_register(event, tracer_call, NULL); + ret = side_tracer_callback_register(event, tracer_call, NULL, NULL); if (ret) abort(); } } else { if (event->flags & SIDE_EVENT_FLAG_VARIADIC) { - ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL); + ret = side_tracer_callback_variadic_unregister(event, tracer_call_variadic, NULL, NULL); if (ret) abort(); } else { - ret = side_tracer_callback_unregister(event, tracer_call, NULL); + ret = side_tracer_callback_unregister(event, tracer_call, NULL, NULL); if (ret) abort(); }