From: Jérémie Galarneau Date: Mon, 4 May 2020 22:21:48 +0000 (-0400) Subject: consumerd: move address computation from on_read_subbuffer_mmap X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=commitdiff_plain;h=128708c34ee7d054755d110df12940155c2dd781 consumerd: move address computation from on_read_subbuffer_mmap The computation of the subbuffer's address is moved outside of lttng_consumer_on_read_subbuffer_mmap to make it usable with a regular buffer. This facilitates an upcoming change. Moreover this has the benefit of isolating domain-specific logic from this function which is supposed to be domain-agnostic. Signed-off-by: Jérémie Galarneau Change-Id: I16f8ccaa73804f98fa03e69136548e6d6b7782e5 --- diff --git a/src/common/consumer/consumer.c b/src/common/consumer/consumer.c index c043353b9..64057c785 100644 --- a/src/common/consumer/consumer.c +++ b/src/common/consumer/consumer.c @@ -1670,12 +1670,12 @@ end: */ ssize_t lttng_consumer_on_read_subbuffer_mmap( struct lttng_consumer_local_data *ctx, - struct lttng_consumer_stream *stream, unsigned long len, + struct lttng_consumer_stream *stream, + const char *buffer, + unsigned long len, unsigned long padding, struct ctf_packet_index *index) { - unsigned long mmap_offset; - void *mmap_base; ssize_t ret = 0; off_t orig_offset = stream->out_fd_offset; /* Default is on the disk */ @@ -1697,36 +1697,6 @@ ssize_t lttng_consumer_on_read_subbuffer_mmap( } } - /* get the offset inside the fd to mmap */ - switch (consumer_data.type) { - case LTTNG_CONSUMER_KERNEL: - mmap_base = stream->mmap_base; - ret = kernctl_get_mmap_read_offset(stream->wait_fd, &mmap_offset); - if (ret < 0) { - PERROR("tracer ctl get_mmap_read_offset"); - goto end; - } - break; - case LTTNG_CONSUMER32_UST: - case LTTNG_CONSUMER64_UST: - mmap_base = lttng_ustctl_get_mmap_base(stream); - if (!mmap_base) { - ERR("read mmap get mmap base for stream %s", stream->name); - ret = -EPERM; - goto end; - } - ret = lttng_ustctl_get_mmap_read_offset(stream, &mmap_offset); - if (ret != 0) { - PERROR("tracer ctl get_mmap_read_offset"); - ret = -EINVAL; - goto end; - } - break; - default: - ERR("Unknown consumer_data type"); - assert(0); - } - /* Handle stream on the relayd if the output is on the network */ if (relayd) { unsigned long netlen = len; @@ -1803,7 +1773,7 @@ ssize_t lttng_consumer_on_read_subbuffer_mmap( * This call guarantee that len or less is returned. It's impossible to * receive a ret value that is bigger than len. */ - ret = lttng_write(outfd, mmap_base + mmap_offset, len); + ret = lttng_write(outfd, buffer, len); DBG("Consumer mmap write() ret %zd (len %lu)", ret, len); if (ret < 0 || ((size_t) ret != len)) { /* diff --git a/src/common/consumer/consumer.h b/src/common/consumer/consumer.h index 23d4faf02..3ff9dbf99 100644 --- a/src/common/consumer/consumer.h +++ b/src/common/consumer/consumer.h @@ -791,7 +791,9 @@ struct lttng_consumer_local_data *lttng_consumer_create( void lttng_consumer_destroy(struct lttng_consumer_local_data *ctx); ssize_t lttng_consumer_on_read_subbuffer_mmap( struct lttng_consumer_local_data *ctx, - struct lttng_consumer_stream *stream, unsigned long len, + struct lttng_consumer_stream *stream, + const char *buffer, + unsigned long len, unsigned long padding, struct ctf_packet_index *index); ssize_t lttng_consumer_on_read_subbuffer_splice( diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index 5075e0592..275c963df 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -7,6 +7,7 @@ * */ +#include #define _LGPL_SOURCE #include #include @@ -113,6 +114,25 @@ int lttng_kconsumer_get_consumed_snapshot(struct lttng_consumer_stream *stream, return ret; } +static +int get_current_subbuf_addr(struct lttng_consumer_stream *stream, + const char **addr) +{ + int ret; + unsigned long mmap_offset; + const char *mmap_base = stream->mmap_base; + + ret = kernctl_get_mmap_read_offset(stream->wait_fd, &mmap_offset); + if (ret < 0) { + PERROR("Failed to get mmap read offset"); + goto error; + } + + *addr = mmap_base + mmap_offset; +error: + return ret; +} + /* * Take a snapshot of all the stream of a channel * RCU read-side lock must be held across this function to ensure existence of @@ -228,6 +248,7 @@ static int lttng_kconsumer_snapshot_channel( while ((long) (consumed_pos - produced_pos) < 0) { ssize_t read_len; unsigned long len, padded_len; + const char *subbuf_addr; health_code_update(); @@ -257,7 +278,13 @@ static int lttng_kconsumer_snapshot_channel( goto error_put_subbuf; } - read_len = lttng_consumer_on_read_subbuffer_mmap(ctx, stream, len, + ret = get_current_subbuf_addr(stream, &subbuf_addr); + if (ret) { + goto error_put_subbuf; + } + + read_len = lttng_consumer_on_read_subbuffer_mmap(ctx, + stream, subbuf_addr, len, padded_len - len, NULL); /* * We write the padded len in local tracefiles but the data len @@ -1691,6 +1718,9 @@ ssize_t lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream, } break; case CONSUMER_CHANNEL_MMAP: + { + const char *subbuf_addr; + /* Get subbuffer size without padding */ err = kernctl_get_subbuf_size(infd, &subbuf_size); if (err != 0) { @@ -1710,13 +1740,20 @@ ssize_t lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream, goto error; } + ret = get_current_subbuf_addr(stream, &subbuf_addr); + if (ret) { + goto error_put_subbuf; + } + /* Make sure the tracer is not gone mad on us! */ assert(len >= subbuf_size); padding = len - subbuf_size; /* write the subbuffer to the tracefile */ - ret = lttng_consumer_on_read_subbuffer_mmap(ctx, stream, subbuf_size, + ret = lttng_consumer_on_read_subbuffer_mmap(ctx, stream, + subbuf_addr, + subbuf_size, padding, &index); /* * The mmap operation should write subbuf_size amount of data when @@ -1736,11 +1773,12 @@ ssize_t lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream, write_index = 0; } break; + } default: ERR("Unknown output method"); ret = -EPERM; } - +error_put_subbuf: err = kernctl_put_next_subbuf(infd); if (err != 0) { if (err == -EFAULT) { diff --git a/src/common/ust-consumer/ust-consumer.c b/src/common/ust-consumer/ust-consumer.c index 77a9670e7..9055d0cf8 100644 --- a/src/common/ust-consumer/ust-consumer.c +++ b/src/common/ust-consumer/ust-consumer.c @@ -7,6 +7,7 @@ * */ +#include #define _LGPL_SOURCE #include #include @@ -1078,6 +1079,35 @@ error: return ret; } +static +int get_current_subbuf_addr(struct lttng_consumer_stream *stream, + const char **addr) +{ + int ret; + unsigned long mmap_offset; + const char *mmap_base; + + mmap_base = ustctl_get_mmap_base(stream->ustream); + if (!mmap_base) { + ERR("Failed to get mmap base for stream `%s`", + stream->name); + ret = -EPERM; + goto error; + } + + ret = ustctl_get_mmap_read_offset(stream->ustream, &mmap_offset); + if (ret != 0) { + ERR("Failed to get mmap offset for stream `%s`", stream->name); + ret = -EINVAL; + goto error; + } + + *addr = mmap_base + mmap_offset; +error: + return ret; + +} + /* * Take a snapshot of all the stream of a channel. * RCU read-side lock and the channel lock must be held by the caller. @@ -1180,6 +1210,7 @@ static int snapshot_channel(struct lttng_consumer_channel *channel, while ((long) (consumed_pos - produced_pos) < 0) { ssize_t read_len; unsigned long len, padded_len; + const char *subbuf_addr; health_code_update(); @@ -1209,7 +1240,13 @@ static int snapshot_channel(struct lttng_consumer_channel *channel, goto error_put_subbuf; } - read_len = lttng_consumer_on_read_subbuffer_mmap(ctx, stream, len, + ret = get_current_subbuf_addr(stream, &subbuf_addr); + if (ret) { + goto error_put_subbuf; + } + + read_len = lttng_consumer_on_read_subbuffer_mmap(ctx, + stream, subbuf_addr, len, padded_len - len, NULL); if (use_relayd) { if (read_len != len) { @@ -2205,31 +2242,6 @@ end: return ret; } -/* - * Wrapper over the mmap() read offset from ust-ctl library. Since this can be - * compiled out, we isolate it in this library. - */ -int lttng_ustctl_get_mmap_read_offset(struct lttng_consumer_stream *stream, - unsigned long *off) -{ - assert(stream); - assert(stream->ustream); - - return ustctl_get_mmap_read_offset(stream->ustream, off); -} - -/* - * Wrapper over the mmap() read offset from ust-ctl library. Since this can be - * compiled out, we isolate it in this library. - */ -void *lttng_ustctl_get_mmap_base(struct lttng_consumer_stream *stream) -{ - assert(stream); - assert(stream->ustream); - - return ustctl_get_mmap_base(stream->ustream); -} - void lttng_ustctl_flush_buffer(struct lttng_consumer_stream *stream, int producer_active) { @@ -2795,6 +2807,7 @@ int lttng_ustconsumer_read_subbuffer(struct lttng_consumer_stream *stream, long ret = 0; struct ustctl_consumer_stream *ustream; struct ctf_packet_index index; + const char *subbuf_addr; assert(stream); assert(stream->ustream); @@ -2904,11 +2917,19 @@ retry: padding = len - subbuf_size; + ret = get_current_subbuf_addr(stream, &subbuf_addr); + if (ret) { + write_index = 0; + goto error_put_subbuf; + } + /* write the subbuffer to the tracefile */ - ret = lttng_consumer_on_read_subbuffer_mmap(ctx, stream, subbuf_size, padding, &index); + ret = lttng_consumer_on_read_subbuffer_mmap( + ctx, stream, subbuf_addr, subbuf_size, padding, &index); /* - * The mmap operation should write subbuf_size amount of data when network - * streaming or the full padding (len) size when we are _not_ streaming. + * The mmap operation should write subbuf_size amount of data when + * network streaming or the full padding (len) size when we are _not_ + * streaming. */ if ((ret != subbuf_size && stream->net_seq_idx != (uint64_t) -1ULL) || (ret != len && stream->net_seq_idx == (uint64_t) -1ULL)) { @@ -2925,6 +2946,7 @@ retry: ret, len, subbuf_size); write_index = 0; } +error_put_subbuf: err = ustctl_put_next_subbuf(ustream); assert(err == 0); diff --git a/src/common/ust-consumer/ust-consumer.h b/src/common/ust-consumer/ust-consumer.h index 406846896..b0a1df7f3 100644 --- a/src/common/ust-consumer/ust-consumer.h +++ b/src/common/ust-consumer/ust-consumer.h @@ -40,9 +40,6 @@ int lttng_ustconsumer_on_recv_stream(struct lttng_consumer_stream *stream); void lttng_ustconsumer_on_stream_hangup(struct lttng_consumer_stream *stream); -int lttng_ustctl_get_mmap_read_offset(struct lttng_consumer_stream *stream, - unsigned long *off); -void *lttng_ustctl_get_mmap_base(struct lttng_consumer_stream *stream); void lttng_ustctl_flush_buffer(struct lttng_consumer_stream *stream, int producer_active); int lttng_ustconsumer_get_stream_id(struct lttng_consumer_stream *stream,