- list_for_each_entry(probe_desc, &probe_list, head) {
- for (i = 0; i < probe_desc->nr_events; i++) {
- if (!strcmp(probe_desc->event_desc[i]->name, name))
- return probe_desc->event_desc[i];
+ provider_name_len = strnlen(desc->provider,
+ LTTNG_KERNEL_SYM_NAME_LEN - 1);
+ for (i = 0; i < desc->nr_events; i++) {
+ if (strncmp(desc->event_desc[i]->name,
+ desc->provider,
+ provider_name_len))
+ return 0; /* provider mismatch */
+ /*
+ * The event needs to contain at least provider name + _ +
+ * one or more letter.
+ */
+ if (strlen(desc->event_desc[i]->name) <= provider_name_len + 1)
+ return 0; /* provider mismatch */
+ if (desc->event_desc[i]->name[provider_name_len] != '_')
+ return 0; /* provider mismatch */
+ }
+ return 1;
+}
+
+/*
+ * Called under sessions lock.
+ */
+static
+void lttng_lazy_probe_register(struct lttng_probe_desc *desc)
+{
+ struct lttng_probe_desc *iter;
+ struct list_head *probe_list;
+
+ /*
+ * Each provider enforce that every event name begins with the
+ * provider name. Check this in an assertion for extra
+ * carefulness. This ensures we cannot have duplicate event
+ * names across providers.
+ */
+ WARN_ON_ONCE(!check_event_provider(desc));
+
+ /*
+ * The provider ensures there are no duplicate event names.
+ * Duplicated TRACEPOINT_EVENT event names would generate a
+ * compile-time error due to duplicated symbol names.
+ */
+
+ /*
+ * We sort the providers by struct lttng_probe_desc pointer
+ * address.
+ */
+ probe_list = &_probe_list;
+ list_for_each_entry_reverse(iter, probe_list, head) {
+ BUG_ON(iter == desc); /* Should never be in the list twice */
+ if (iter < desc) {
+ /* We belong to the location right after iter. */
+ list_add(&desc->head, &iter->head);
+ goto desc_added;