struct ltt_channel *chan;
mutex_lock(&sessions_mutex);
+ if (session->active)
+ goto active; /* Refuse to add channel to active session */
list_for_each_entry(chan, &session->chan, list)
if (!strcmp(chan->name, name))
goto exist;
return chan;
exist:
+active:
mutex_unlock(&sessions_mutex);
return NULL;
}
kfree(chan);
}
+/*
+ * Supports event creation while tracing session is active.
+ */
struct ltt_event *ltt_event_create(struct ltt_channel *chan, char *name,
void *filter)
{
struct ltt_event *event;
mutex_lock(&sessions_mutex);
+ 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.
strcpy(event->name, name);
event->chan = chan;
event->filter = filter;
- event->id = atomic_inc_return(&chan->free_event_id) - 1;
- /* TODO register to tracepoint */
+ event->id = chan->free_event_id++;
mutex_unlock(&sessions_mutex);
+ /* Populate ltt_event structure before tracepoint registration. */
+ smp_wmb();
+ /* TODO register to tracepoint */
return event;
error:
kmem_cache_free(event);
cache_error:
exist:
+full:
mutex_unlock(&sessions_mutex);
return NULL;
}
struct channel *chan; /* Channel buffers */
/* Event ID management */
struct ltt_session *session;
- atomic_t free_event_id; /* Next event ID to allocate */
+ unsigned int free_event_id; /* Next event ID to allocate */
struct list_head list; /* Channel list */
char name[PATH_MAX];
};
struct ltt_session {
+ int active; /* Is trace session active ? */
struct list_head chan; /* Channel list head */
struct list_head events; /* Event list head */
struct list_head list; /* Session list */