BPF_HASH(stage6_timestamps, message_identifier_t, timestamp_value_t);
+/* This hashmap tracks task->message relationships */
+BPF_HASH(stage7_task_to_message, key_pointer_t, key_pointer_t);
+/* This hashmap tracks invocation->message relationships */
+BPF_HASH(stage7_invocation_to_message, key_pointer_t, key_pointer_t);
BPF_HASH(stage7_timestamps, key_pointer_t, timestamp_value_t);
BPF_HASH(stage8_timestamps, key_pointer_t, timestamp_value_t);
+BPF_HASH(stage9_task_to_message, key_pointer_t, key_pointer_t);
+BPF_HASH(stage9_timestamps, key_pointer_t, timestamp_value_t);
+
BPF_HISTOGRAM(timings_stage1);
BPF_HISTOGRAM(timings_stage2);
BPF_HISTOGRAM(timings_stage3);
/* There is an intermediate step for method calls - we track creation of
* GDBusMethodInvocation for a given message, and then we track when
* it is about to be used */
-/* This hashmap tracks invocation->message relationships */
-BPF_HASH(invocation_to_message, key_pointer_t, key_pointer_t);
/* Trace _g_dbus_method_invocation_new(). */
int stage7_method_call_intermediate(struct pt_regs *ctx) {
key_pointer_set_pointer(&key, invocation_ptr);
key_pointer_set_pointer(&value, (void *)invocation_ptr->message);
- invocation_to_message.update(&key, &value);
+ stage7_invocation_to_message.update(&key, &value);
return 0;
}
key_pointer_set_pointer(&itm_key, user_data);
- itm_value = invocation_to_message.lookup(&itm_key);
+ itm_value = stage7_invocation_to_message.lookup(&itm_key);
if (itm_value == 0)
return 0;
wrk_value = stage7_timestamps.lookup(itm_value);
if (wrk_value == 0) {
- invocation_to_message.delete(&itm_key);
+ stage7_invocation_to_message.delete(&itm_key);
bpf_trace_printk("no message %p connected to invocation\n", itm_value->pointer);
bpf_trace_printk(" for pid %u\n", itm_value->pid);
return 0;
timestamp -= timestamp_value_get_timestamp(wrk_value);
stage7_timestamps.delete(itm_value);
- invocation_to_message.delete(&itm_key);
+ stage7_invocation_to_message.delete(&itm_key);
timings_stage7.increment(bpf_log2l(ns_to_us(timestamp)));
int stage7_method_call_cleanup(struct pt_regs *ctx, struct _GDBusMethodInvocation *invocation) {
key_pointer_t itm_key;
key_pointer_set_pointer(&itm_key, invocation);
- invocation_to_message.delete(&itm_key);
+ stage7_invocation_to_message.delete(&itm_key);
return 0;
}
/* There is an intermediate step for method returns and errors - we track association of
* a GTask with a given message, and then we track when
* it is about to be used */
-/* This hashmap tracks task->message relationships */
-BPF_HASH(task_to_message, key_pointer_t, key_pointer_t);
/* trace g_task_return_pointer() */
int stage7_method_return_intermediate(struct pt_regs *ctx, void *task, struct GDBusMessage *message) {
key_pointer_set_pointer(&key, task);
key_pointer_set_pointer(&value, message);
- task_to_message.update(&key, &value);
+ stage7_task_to_message.update(&key, &value);
return 0;
}
u64 timestamp = get_current_timestamp();
key_pointer_set_pointer(&ttm_key, task);
- ttm_value = task_to_message.lookup(&ttm_key);
+ ttm_value = stage7_task_to_message.lookup(&ttm_key);
if (ttm_value == 0)
return 0;
wrk_value = stage7_timestamps.lookup(ttm_value);
if (wrk_value == 0) {
- task_to_message.delete(&ttm_key);
+ stage7_task_to_message.delete(&ttm_key);
bpf_trace_printk("no message %p connected to task\n", ttm_value->pointer);
bpf_trace_printk(" for pid %u\n", ttm_value->pid);
return 0;
timestamp -= timestamp_value_get_timestamp(wrk_value);
stage7_timestamps.delete(ttm_value);
- task_to_message.delete(&ttm_key);
+ stage7_task_to_message.delete(&ttm_key);
timings_stage7.increment(bpf_log2l(ns_to_us(timestamp)));
key_pointer_t ttm_key;
key_pointer_set_pointer(&ttm_key, invocation);
- task_to_message.delete(&ttm_key);
+ stage7_task_to_message.delete(&ttm_key);
return 0;
}
int stage8_method_call_erroneous_end(struct pt_regs *ctx, void *user_data) {
/* user_data is GDBusMethodInvocation */
key_pointer_t key;
- key_pointer_set_pointer(&key, invocation);
+ key_pointer_set_pointer(&key, user_data);
stage8_timestamps.delete(&key);
return 0;
}
return 0;
}
+/* trace g_task_return_pointer() */
+int stage9_method_return_prepare(struct pt_regs *ctx, void *task, struct GDBusMessage *message) {
+ key_pointer_t key;
+ key_pointer_t value;
+
+ key_pointer_set_pointer(&key, task);
+ key_pointer_set_pointer(&value, message);
+
+ stage9_task_to_message.update(&key, &value);
+ return 0;
+}
+
/* trace g_task_return_now() */
-int stage9_method_return_begin(struct pt_regs *ctx) {
- /* TODO */
+int stage9_method_return_begin(struct pt_regs *ctx, void *task) {
+ key_pointer_t ttm_key;
+ key_pointer_t *ttm_value;
+ struct GDBusMessage *message;
+ timestamp_value_t value;
+
+ key_pointer_set_pointer(&ttm_key, task);
+ ttm_value = stage9_task_to_message.lookup(&ttm_key);
+ if (ttm_value == NULL)
+ return 0;
+
+ timestamp_value_set_timestamp(&value);
+ stage9_timestamps.update(ttm_value, &value);
+
return 0;
}