From 1ec3f75aca46d4196d4d7dbbbe0b791f663203f1 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 17 May 2011 08:06:54 -0400 Subject: [PATCH] trace_uuid -> uuid Signed-off-by: Mathieu Desnoyers --- ltt-events.c | 64 +++++++++++++++++++------------ ltt-events.h | 6 +++ ltt-ring-buffer-client.h | 5 ++- ltt-ring-buffer-metadata-client.h | 24 ++++++++++-- 4 files changed, 69 insertions(+), 30 deletions(-) diff --git a/ltt-events.c b/ltt-events.c index db1ac86f..1aadd9f3 100644 --- a/ltt-events.c +++ b/ltt-events.c @@ -287,6 +287,12 @@ void _ltt_event_destroy(struct ltt_event *event) kmem_cache_free(event_cache, event); } +/* + * We have exclusive access to our metadata buffer (protected by the + * sessions_mutex), so we can do racy operations such as looking for + * remaining space left in packet and write, since mutual exclusion + * protects us from concurrent writes. + */ int lttng_metadata_printf(struct ltt_session *session, const char *fmt, ...) { @@ -294,7 +300,7 @@ int lttng_metadata_printf(struct ltt_session *session, struct ltt_channel *chan = session->metadata; char *str; int ret = 0, waitret; - size_t len; + size_t len, reserve_len, pos; va_list ap; WARN_ON_ONCE(!ACCESS_ONCE(session->active)); @@ -305,30 +311,38 @@ int lttng_metadata_printf(struct ltt_session *session, if (!str) return -ENOMEM; - len = strlen(str) + 1; - lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, len, sizeof(char), -1); - /* - * We don't care about metadata buffer's records lost count, because we - * always retry here. Report error if we need to bail out after timeout - * or being interrupted. - */ - waitret = wait_event_interruptible_timeout(*chan->ops->get_reader_wait_queue(chan), - ({ - ret = chan->ops->event_reserve(&ctx); - ret != -ENOBUFS || !ret; - }), - msecs_to_jiffies(LTTNG_METADATA_TIMEOUT_MSEC)); - if (!waitret || waitret == -ERESTARTSYS || ret) { - printk(KERN_WARNING "LTTng: Failure to write metadata to buffers (%s)\n", - waitret == -ERESTARTSYS ? "interrupted" : - (ret == -ENOBUFS ? "timeout" : "I/O error")); - printk("waitret %d retval %d\n", waitret, ret); - if (waitret == -ERESTARTSYS) - ret = waitret; - goto end; + len = strlen(str); + pos = 0; + + for (pos = 0; pos < len; pos += reserve_len) { + reserve_len = min_t(size_t, + chan->ops->packet_avail_size(chan->chan), + len - pos); + lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len, + sizeof(char), -1); + /* + * We don't care about metadata buffer's records lost + * count, because we always retry here. Report error if + * we need to bail out after timeout or being + * interrupted. + */ + waitret = wait_event_interruptible_timeout(*chan->ops->get_reader_wait_queue(chan), + ({ + ret = chan->ops->event_reserve(&ctx); + ret != -ENOBUFS || !ret; + }), + msecs_to_jiffies(LTTNG_METADATA_TIMEOUT_MSEC)); + if (!waitret || waitret == -ERESTARTSYS || ret) { + printk(KERN_WARNING "LTTng: Failure to write metadata to buffers (%s)\n", + waitret == -ERESTARTSYS ? "interrupted" : + (ret == -ENOBUFS ? "timeout" : "I/O error")); + if (waitret == -ERESTARTSYS) + ret = waitret; + goto end; + } + chan->ops->event_write(&ctx, &str[pos], len); + chan->ops->event_commit(&ctx); } - chan->ops->event_write(&ctx, str, len); - chan->ops->event_commit(&ctx); end: kfree(str); return ret; @@ -542,7 +556,7 @@ int _ltt_session_metadata_statedump(struct ltt_session *session) " byte_order = %s;\n" " packet.header := struct {\n" " uint32_t magic;\n" - " uint8_t trace_uuid[16];\n" + " uint8_t uuid[16];\n" " uint32_t stream_id;\n" " uint64_t timestamp_begin;\n" " uint64_t timestamp_end;\n" diff --git a/ltt-events.h b/ltt-events.h index 5b5dcb50..a5eab5b8 100644 --- a/ltt-events.h +++ b/ltt-events.h @@ -147,6 +147,12 @@ struct ltt_channel_ops { void (*event_commit)(struct lib_ring_buffer_ctx *ctx); void (*event_write)(struct lib_ring_buffer_ctx *ctx, const void *src, size_t len); + /* + * packet_avail_size returns the available size in the current + * packet. Note that the size returned is only a hint, since it + * may change due to concurrent writes. + */ + size_t (*packet_avail_size)(struct channel *chan); wait_queue_head_t *(*get_reader_wait_queue)(struct ltt_channel *chan); }; diff --git a/ltt-ring-buffer-client.h b/ltt-ring-buffer-client.h index aa763837..8bb66af8 100644 --- a/ltt-ring-buffer-client.h +++ b/ltt-ring-buffer-client.h @@ -26,7 +26,7 @@ struct packet_header { * Trace magic number. * contains endianness information. */ - uint8_t trace_uuid[16]; + uint8_t uuid[16]; uint32_t stream_id; uint64_t timestamp_begin; /* Cycle count at subbuffer start */ uint64_t timestamp_end; /* Cycle count at subbuffer end */ @@ -249,7 +249,7 @@ static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc, struct ltt_session *session = channel_get_private(chan); header->magic = CTF_MAGIC_NUMBER; - memcpy(header->trace_uuid, session->uuid.b, sizeof(session->uuid)); + memcpy(header->uuid, session->uuid.b, sizeof(session->uuid)); header->timestamp_begin = tsc; header->timestamp_end = 0; header->content_size = 0xFFFFFFFF; /* for debugging */ @@ -406,6 +406,7 @@ static struct ltt_transport ltt_relay_transport = { .event_reserve = ltt_event_reserve, .event_commit = ltt_event_commit, .event_write = ltt_event_write, + .packet_avail_size = NULL, /* Would be racy anyway */ .get_reader_wait_queue = ltt_get_reader_wait_queue, }, }; diff --git a/ltt-ring-buffer-metadata-client.h b/ltt-ring-buffer-metadata-client.h index c6dce5f9..bde712e6 100644 --- a/ltt-ring-buffer-metadata-client.h +++ b/ltt-ring-buffer-metadata-client.h @@ -16,7 +16,7 @@ struct metadata_packet_header { uint32_t magic; /* 0x75D11D57 */ - uint8_t trace_uuid[16]; /* Unique Universal Identifier */ + uint8_t uuid[16]; /* Unique Universal Identifier */ uint32_t checksum; /* 0 if unused */ uint32_t content_size; /* in bits */ uint32_t packet_size; /* in bits */ @@ -89,7 +89,7 @@ static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc, struct ltt_session *session = channel_get_private(chan); header->magic = TSDL_MAGIC_NUMBER; - memcpy(header->trace_uuid, session->uuid.b, sizeof(session->uuid)); + memcpy(header->uuid, session->uuid.b, sizeof(session->uuid)); header->checksum = 0; /* 0 if unused */ header->content_size = 0xFFFFFFFF; /* in bits, for debugging */ header->packet_size = 0xFFFFFFFF; /* in bits, for debugging */ @@ -107,7 +107,7 @@ static void client_buffer_end(struct lib_ring_buffer *buf, u64 tsc, { struct channel *chan = buf->backend.chan; struct metadata_packet_header *header = - (struct packet_header *) + (struct metadata_packet_header *) lib_ring_buffer_offset_address(&buf->backend, subbuf_idx * chan->backend.subbuf_size); unsigned long records_lost = 0; @@ -204,6 +204,23 @@ void ltt_event_write(struct lib_ring_buffer_ctx *ctx, const void *src, lib_ring_buffer_write(&client_config, ctx, src, len); } +static +size_t ltt_packet_avail_size(struct channel *chan) + +{ + unsigned long o_begin; + struct lib_ring_buffer *buf; + + buf = chan->backend.buf; /* Only for global buffer ! */ + o_begin = v_read(&client_config, &buf->offset); + if (subbuf_offset(o_begin, chan) != 0) { + return chan->backend.subbuf_size - subbuf_offset(o_begin, chan); + } else { + return chan->backend.subbuf_size - subbuf_offset(o_begin, chan) + - sizeof(struct metadata_packet_header); + } +} + static wait_queue_head_t *ltt_get_reader_wait_queue(struct ltt_channel *chan) { @@ -221,6 +238,7 @@ static struct ltt_transport ltt_relay_transport = { .event_reserve = ltt_event_reserve, .event_commit = ltt_event_commit, .event_write = ltt_event_write, + .packet_avail_size = ltt_packet_avail_size, .get_reader_wait_queue = ltt_get_reader_wait_queue, }, }; -- 2.34.1