Interface ABI with probe list
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Thu, 23 Dec 2010 16:43:52 +0000 (11:43 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Thu, 23 Dec 2010 16:43:52 +0000 (11:43 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
ltt-debugfs-abi.c
ltt-events.c
ltt-events.h
ltt-probes.c

index 9043759f960102c443196f4e9567680cd8371f05..0ac886113c35c5711dfb6c1060aeda22ee1df0dc 100644 (file)
@@ -241,8 +241,11 @@ int lttng_abi_open_stream(struct file *channel_file)
                goto file_error;
        }
        fd_install(stream_fd, stream_file);
-       /* The stream holds a reference on the channel */
-       atomic_long_inc(&channel_file->f_count);
+       /*
+        * The stream holds a reference to the channel within the generic ring
+        * buffer library, so no need to hold a refcount on the channel and
+        * session files here.
+        */
        return stream_fd;
 
 file_error:
@@ -262,6 +265,7 @@ int lttng_abi_create_event(struct file *channel_file,
        struct lttng_event event_param;
        int event_fd, ret;
        struct file *event_file;
+       void *probe;
 
        if (copy_from_user(&event_param, uevent_param, sizeof(event_param)))
                return -EFAULT;
@@ -273,6 +277,12 @@ int lttng_abi_create_event(struct file *channel_file,
                goto name_error;
        }
        event_name[PATH_MAX - 1] = '\0';
+
+       probe = ltt_probe_get(event_name);
+       if (!probe) {
+               ret = -ENOENT;
+               goto probe_error;
+       }
        event_fd = get_unused_fd();
        if (event_fd < 0) {
                ret = event_fd;
@@ -290,7 +300,7 @@ int lttng_abi_create_event(struct file *channel_file,
         * invariant for the rest of the session.
         */
        event = ltt_event_create(channel, event_name, event_param.itype,
-                                (void *) 0x1, NULL);   /* TODO connect real probe */
+                                probe, NULL);
        if (!event) {
                goto event_error;
                ret = -EEXIST;
@@ -307,6 +317,8 @@ event_error:
 file_error:
        put_unused_fd(event_fd);
 fd_error:
+       ltt_probe_put(probe);
+probe_error:
 name_error:
        kfree(event_name);
        return ret;
index 0e34f6f8b0585bdc3f192467a4e5f75096f33d66..c2a6a9206304f6e5a06b4b30e55a465d0f70f589 100644 (file)
@@ -46,9 +46,14 @@ void ltt_session_destroy(struct ltt_session *session)
 {
        struct ltt_channel *chan, *tmpchan;
        struct ltt_event *event, *tmpevent;
+       int ret;
 
        mutex_lock(&sessions_mutex);
        session->active = 0;
+       list_for_each_entry(event, &session->events, list) {
+               ret = _ltt_event_unregister(event);
+               WARN_ON(ret);
+       }
        synchronize_trace();    /* Wait for in-flight events to complete */
        list_for_each_entry_safe(event, tmpevent, &session->events, list)
                _ltt_event_destroy(event);
@@ -172,8 +177,8 @@ struct ltt_event *ltt_event_create(struct ltt_channel *chan, char *name,
        if (chan->free_event_id == -1UL)
                goto full;
        /*
-        * This is O(n^2) (for each event loop called at event creation).
-        * Might require a hash if we have lots of events.
+        * This is O(n^2) (for each event, the loop is called at event
+        * creation). Might require a hash if we have lots of events.
         */
        list_for_each_entry(event, &chan->session->events, list)
                if (!strcmp(event->name, name))
@@ -201,6 +206,7 @@ struct ltt_event *ltt_event_create(struct ltt_channel *chan, char *name,
        default:
                WARN_ON_ONCE(1);
        }
+       list_add(&event->list, &chan->session->events);
        mutex_unlock(&sessions_mutex);
        return event;
 
@@ -218,7 +224,7 @@ full:
 /*
  * Only used internally at session destruction.
  */
-int _ltt_event_destroy(struct ltt_event *event)
+int _ltt_event_unregister(struct ltt_event *event)
 {
        int ret = -EINVAL;
 
@@ -232,9 +238,17 @@ int _ltt_event_destroy(struct ltt_event *event)
        default:
                WARN_ON_ONCE(1);
        }
+       return ret;
+}
+
+/*
+ * Only used internally at session destruction.
+ */
+void _ltt_event_destroy(struct ltt_event *event)
+{
        kfree(event->name);
+       list_del(&event->list);
        kmem_cache_free(event_cache, event);
-       return ret;
 }
 
 /**
index b888dd2b493b873a6155c2725bbcf9b496f8ab61..e8171b032110138198e4405a30de191b2757912e 100644 (file)
@@ -88,7 +88,8 @@ struct ltt_event *ltt_event_create(struct ltt_channel *chan,
                                   char *name,
                                   enum instrum_type itype,
                                   void *probe, void *filter);
-int _ltt_event_destroy(struct ltt_event *event);
+int _ltt_event_unregister(struct ltt_event *event);
+void _ltt_event_destroy(struct ltt_event *event);
 
 void ltt_transport_register(struct ltt_transport *transport);
 void ltt_transport_unregister(struct ltt_transport *transport);
index 9870b9d8bfd380fb71277c1146fc9feea77aa6b7..f8f1ef225b417473fb0c6a69fc969fe4cbac40bd 100644 (file)
@@ -21,13 +21,13 @@ static LIST_HEAD(probe_list);
 static DEFINE_MUTEX(probe_mutex);
 static struct kmem_cache *probe_cache;
 
-static void *find_probe(const char *name)
+static struct ltt_probe *find_probe(const char *name)
 {
        struct ltt_probe *probe;
 
        list_for_each_entry(probe, &probe_list, list) {
                if (!strcmp(probe->name, name))
-                       return probe->cb;
+                       return probe;
        }
        return NULL;
 }
This page took 0.02978 seconds and 4 git commands to generate.