unsigned long num_subbuf; /* Number of sub-buffers for writer */
u64 start_tsc; /* Channel creation TSC value */
void *priv; /* Client-specific information */
+ void *priv_ops; /* Client-specific ops pointer */
+ void (*release_priv_ops)(void *priv_ops);
struct notifier_block cpu_hp_notifier; /* CPU hotplug notifier */
/*
* We need to copy config because the module containing the
static void channel_free(struct channel *chan)
{
+ if (chan->backend.release_priv_ops) {
+ chan->backend.release_priv_ops(chan->backend.priv_ops);
+ }
channel_iterator_free(chan);
channel_backend_free(&chan->backend);
kfree(chan);
struct lib_ring_buffer *buf = filp->private_data;
struct channel *chan = buf->backend.chan;
const struct lib_ring_buffer_config *config = &chan->backend.config;
- struct lttng_channel *lttng_chan = channel_get_private(chan);
+ const struct lttng_channel_ops *ops = chan->backend.priv_ops;
int ret;
if (atomic_read(&chan->record_disabled))
{
uint64_t ts;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->timestamp_begin(config, buf, &ts);
+ ret = ops->timestamp_begin(config, buf, &ts);
if (ret < 0)
goto error;
return put_u64(ts, arg);
{
uint64_t ts;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->timestamp_end(config, buf, &ts);
+ ret = ops->timestamp_end(config, buf, &ts);
if (ret < 0)
goto error;
return put_u64(ts, arg);
{
uint64_t ed;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->events_discarded(config, buf, &ed);
+ ret = ops->events_discarded(config, buf, &ed);
if (ret < 0)
goto error;
return put_u64(ed, arg);
{
uint64_t cs;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->content_size(config, buf, &cs);
+ ret = ops->content_size(config, buf, &cs);
if (ret < 0)
goto error;
return put_u64(cs, arg);
{
uint64_t ps;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->packet_size(config, buf, &ps);
+ ret = ops->packet_size(config, buf, &ps);
if (ret < 0)
goto error;
return put_u64(ps, arg);
{
uint64_t si;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->stream_id(config, buf, &si);
+ ret = ops->stream_id(config, buf, &si);
if (ret < 0)
goto error;
return put_u64(si, arg);
{
uint64_t ts;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->current_timestamp(config, buf, &ts);
+ ret = ops->current_timestamp(config, buf, &ts);
if (ret < 0)
goto error;
return put_u64(ts, arg);
struct lib_ring_buffer *buf = filp->private_data;
struct channel *chan = buf->backend.chan;
const struct lib_ring_buffer_config *config = &chan->backend.config;
- struct lttng_channel *lttng_chan = channel_get_private(chan);
+ const struct lttng_channel_ops *ops = chan->backend.priv_ops;
int ret;
if (atomic_read(&chan->record_disabled))
{
uint64_t ts;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->timestamp_begin(config, buf, &ts);
+ ret = ops->timestamp_begin(config, buf, &ts);
if (ret < 0)
goto error;
return put_u64(ts, arg);
{
uint64_t ts;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->timestamp_end(config, buf, &ts);
+ ret = ops->timestamp_end(config, buf, &ts);
if (ret < 0)
goto error;
return put_u64(ts, arg);
{
uint64_t ed;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->events_discarded(config, buf, &ed);
+ ret = ops->events_discarded(config, buf, &ed);
if (ret < 0)
goto error;
return put_u64(ed, arg);
{
uint64_t cs;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->content_size(config, buf, &cs);
+ ret = ops->content_size(config, buf, &cs);
if (ret < 0)
goto error;
return put_u64(cs, arg);
{
uint64_t ps;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->packet_size(config, buf, &ps);
+ ret = ops->packet_size(config, buf, &ps);
if (ret < 0)
goto error;
return put_u64(ps, arg);
{
uint64_t si;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->stream_id(config, buf, &si);
+ ret = ops->stream_id(config, buf, &si);
if (ret < 0)
goto error;
return put_u64(si, arg);
{
uint64_t ts;
- if (!lttng_chan->ops)
- goto error;
- ret = lttng_chan->ops->current_timestamp(config, buf, &ts);
+ ret = ops->current_timestamp(config, buf, &ts);
if (ret < 0)
goto error;
return put_u64(ts, arg);
#define LTTNG_COMPACT_EVENT_BITS 5
#define LTTNG_COMPACT_TSC_BITS 27
+static struct lttng_transport lttng_relay_transport;
+
/*
* Keep the natural field alignment for _each field_ within this structure if
* you ever add/remove a field from this header. Packed attribute is not used
.wakeup = RING_BUFFER_WAKEUP_BY_TIMER,
};
+static
+void release_priv_ops(void *priv_ops)
+{
+ module_put(THIS_MODULE);
+}
+
+static
+void lttng_channel_destroy(struct channel *chan)
+{
+ channel_destroy(chan);
+}
+
static
struct channel *_channel_create(const char *name,
struct lttng_channel *lttng_chan, void *buf_addr,
unsigned int switch_timer_interval,
unsigned int read_timer_interval)
{
- return channel_create(&client_config, name, lttng_chan, buf_addr,
+ struct channel *chan;
+
+ chan = channel_create(&client_config, name, lttng_chan, buf_addr,
subbuf_size, num_subbuf, switch_timer_interval,
read_timer_interval);
-}
+ if (chan) {
+ /*
+ * Ensure this module is not unloaded before we finish
+ * using lttng_relay_transport.ops.
+ */
+ if (!try_module_get(THIS_MODULE)) {
+ printk(KERN_WARNING "LTT : Can't lock transport module.\n");
+ goto error;
+ }
+ chan->backend.priv_ops = <tng_relay_transport.ops;
+ chan->backend.release_priv_ops = release_priv_ops;
+ }
+ return chan;
-static
-void lttng_channel_destroy(struct channel *chan)
-{
- channel_destroy(chan);
+error:
+ lttng_channel_destroy(chan);
+ return NULL;
}
static
#include "lttng-events.h"
#include "lttng-tracer.h"
+static struct lttng_transport lttng_relay_transport;
+
struct metadata_packet_header {
uint32_t magic; /* 0x75D11D57 */
uint8_t uuid[16]; /* Unique Universal Identifier */
.wakeup = RING_BUFFER_WAKEUP_BY_TIMER,
};
+static
+void release_priv_ops(void *priv_ops)
+{
+ module_put(THIS_MODULE);
+}
+
+static
+void lttng_channel_destroy(struct channel *chan)
+{
+ channel_destroy(chan);
+}
+
static
struct channel *_channel_create(const char *name,
struct lttng_channel *lttng_chan, void *buf_addr,
unsigned int switch_timer_interval,
unsigned int read_timer_interval)
{
- return channel_create(&client_config, name, lttng_chan, buf_addr,
+ struct channel *chan;
+
+ chan = channel_create(&client_config, name, lttng_chan, buf_addr,
subbuf_size, num_subbuf, switch_timer_interval,
read_timer_interval);
-}
+ if (chan) {
+ /*
+ * Ensure this module is not unloaded before we finish
+ * using lttng_relay_transport.ops.
+ */
+ if (!try_module_get(THIS_MODULE)) {
+ printk(KERN_WARNING "LTT : Can't lock transport module.\n");
+ goto error;
+ }
+ chan->backend.priv_ops = <tng_relay_transport.ops;
+ chan->backend.release_priv_ops = release_priv_ops;
+ }
+ return chan;
-static
-void lttng_channel_destroy(struct channel *chan)
-{
- channel_destroy(chan);
+error:
+ lttng_channel_destroy(chan);
+ return NULL;
}
static