#include <linux/file.h>
#include <linux/anon_inodes.h>
#include <wrapper/file.h>
-#include <linux/jhash.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/dmi.h>
#include <lttng/abi-old.h>
#include <lttng/endian.h>
#include <lttng/string-utils.h>
+#include <lttng/utils.h>
#include <ringbuffer/backend.h>
#include <ringbuffer/frontend.h>
#include <wrapper/time.h>
#define METADATA_CACHE_DEFAULT_SIZE 4096
static LIST_HEAD(sessions);
+static LIST_HEAD(event_notifier_groups);
static LIST_HEAD(lttng_transport_list);
/*
* Protect the sessions and metadata caches.
mutex_unlock(&sessions_mutex);
}
+static struct lttng_transport *lttng_transport_find(const char *name)
+{
+ struct lttng_transport *transport;
+
+ list_for_each_entry(transport, <tng_transport_list, node) {
+ if (!strcmp(transport->name, name))
+ return transport;
+ }
+ return NULL;
+}
+
/*
* Called with sessions lock held.
*/
return NULL;
}
+struct lttng_event_notifier_group *lttng_event_notifier_group_create(void)
+{
+ struct lttng_transport *transport = NULL;
+ struct lttng_event_notifier_group *event_notifier_group;
+ const char *transport_name = "relay-event-notifier";
+ size_t subbuf_size = 4096; //TODO
+ size_t num_subbuf = 16; //TODO
+ unsigned int switch_timer_interval = 0;
+ unsigned int read_timer_interval = 0;
+
+ mutex_lock(&sessions_mutex);
+
+ transport = lttng_transport_find(transport_name);
+ if (!transport) {
+ printk(KERN_WARNING "LTTng: transport %s not found\n",
+ transport_name);
+ goto notransport;
+ }
+ if (!try_module_get(transport->owner)) {
+ printk(KERN_WARNING "LTTng: Can't lock transport %s module.\n",
+ transport_name);
+ goto notransport;
+ }
+
+ event_notifier_group = lttng_kvzalloc(sizeof(struct lttng_event_notifier_group),
+ GFP_KERNEL);
+ if (!event_notifier_group)
+ goto nomem;
+
+ /*
+ * Initialize the ring buffer used to store event notifier
+ * notifications.
+ */
+ event_notifier_group->ops = &transport->ops;
+ event_notifier_group->chan = transport->ops.channel_create(
+ transport_name, event_notifier_group, NULL,
+ subbuf_size, num_subbuf, switch_timer_interval,
+ read_timer_interval);
+ if (!event_notifier_group->chan)
+ goto create_error;
+
+ event_notifier_group->transport = transport;
+ list_add(&event_notifier_group->node, &event_notifier_groups);
+
+ mutex_unlock(&sessions_mutex);
+
+ return event_notifier_group;
+
+create_error:
+ lttng_kvfree(event_notifier_group);
+nomem:
+ if (transport)
+ module_put(transport->owner);
+notransport:
+ mutex_unlock(&sessions_mutex);
+ return NULL;
+}
+
void metadata_cache_destroy(struct kref *kref)
{
struct lttng_metadata_cache *cache =
lttng_kvfree(session);
}
+void lttng_event_notifier_group_destroy(struct lttng_event_notifier_group *event_notifier_group)
+{
+ if (!event_notifier_group)
+ return;
+
+ mutex_lock(&sessions_mutex);
+ event_notifier_group->ops->channel_destroy(event_notifier_group->chan);
+ module_put(event_notifier_group->transport->owner);
+ list_del(&event_notifier_group->node);
+ mutex_unlock(&sessions_mutex);
+ lttng_kvfree(event_notifier_group);
+}
+
int lttng_session_statedump(struct lttng_session *session)
{
int ret;
return ret;
}
-static struct lttng_transport *lttng_transport_find(const char *name)
-{
- struct lttng_transport *transport;
-
- list_for_each_entry(transport, <tng_transport_list, node) {
- if (!strcmp(transport->name, name))
- return transport;
- }
- return NULL;
-}
-
struct lttng_channel *lttng_channel_create(struct lttng_session *session,
const char *transport_name,
void *buf_addr,
struct lttng_event *event;
const char *event_name;
struct hlist_head *head;
- size_t name_len;
- uint32_t hash;
int ret;
if (chan->free_event_id == -1U) {
ret = -EINVAL;
goto type_error;
}
- name_len = strlen(event_name);
- hash = jhash(event_name, name_len, 0);
- head = &session->events_ht.table[hash & (LTTNG_EVENT_HT_SIZE - 1)];
+
+ head = utils_borrow_hash_table_bucket(session->events_ht.table,
+ LTTNG_EVENT_HT_SIZE, event_name);
lttng_hlist_for_each_entry(event, head, hlist) {
WARN_ON_ONCE(!event->desc);
if (!strncmp(event->desc->name, event_name,
/* Event will be enabled by enabler sync. */
event->enabled = 0;
event->registered = 0;
- event->desc = lttng_event_get(event_name);
+ event->desc = lttng_event_desc_get(event_name);
if (!event->desc) {
ret = -ENOENT;
goto register_error;
{
switch (event->instrumentation) {
case LTTNG_KERNEL_TRACEPOINT:
- lttng_event_put(event->desc);
+ lttng_event_desc_put(event->desc);
break;
case LTTNG_KERNEL_KPROBE:
module_put(event->desc->owner);
for (i = 0; i < probe_desc->nr_events; i++) {
int found = 0;
struct hlist_head *head;
- const char *event_name;
- size_t name_len;
- uint32_t hash;
struct lttng_event *event;
desc = probe_desc->event_desc[i];
if (!lttng_desc_match_enabler(desc,
lttng_event_enabler_as_enabler(event_enabler)))
continue;
- event_name = desc->name;
- name_len = strlen(event_name);
/*
* Check if already created.
*/
- hash = jhash(event_name, name_len, 0);
- head = &session->events_ht.table[hash & (LTTNG_EVENT_HT_SIZE - 1)];
+ head = utils_borrow_hash_table_bucket(
+ session->events_ht.table, LTTNG_EVENT_HT_SIZE,
+ desc->name);
lttng_hlist_for_each_entry(event, head, hlist) {
if (event->desc == desc
&& event->chan == event_enabler->chan)
/*
* Link filter bytecodes if not linked yet.
*/
- lttng_event_enabler_link_bytecode(event, event_enabler);
+ lttng_enabler_link_bytecode(event->desc,
+ lttng_static_ctx,
+ &event->bytecode_runtime_head,
+ lttng_event_enabler_as_enabler(event_enabler));
/* TODO: merge event context. */
}