consumerd: move address computation from on_read_subbuffer_mmap
[lttng-tools.git] / src / common / kernel-consumer / kernel-consumer.c
index 29a27134f0e372c8c8295114048537a07dcc6453..2878355a563623eefad9dc0fb56af89d86cbebc7 100644 (file)
@@ -17,6 +17,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include <stdint.h>
 #define _LGPL_SOURCE
 #include <assert.h>
 #include <poll.h>
@@ -123,6 +124,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
@@ -238,6 +258,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();
 
@@ -267,7 +288,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
@@ -1327,66 +1354,62 @@ end:
 static int get_index_values(struct ctf_packet_index *index, int infd)
 {
        int ret;
+       uint64_t packet_size, content_size, timestamp_begin, timestamp_end,
+                       events_discarded, stream_id, stream_instance_id,
+                       packet_seq_num;
 
-       ret = kernctl_get_timestamp_begin(infd, &index->timestamp_begin);
+       ret = kernctl_get_timestamp_begin(infd, &timestamp_begin);
        if (ret < 0) {
                PERROR("kernctl_get_timestamp_begin");
                goto error;
        }
-       index->timestamp_begin = htobe64(index->timestamp_begin);
 
-       ret = kernctl_get_timestamp_end(infd, &index->timestamp_end);
+       ret = kernctl_get_timestamp_end(infd, &timestamp_end);
        if (ret < 0) {
                PERROR("kernctl_get_timestamp_end");
                goto error;
        }
-       index->timestamp_end = htobe64(index->timestamp_end);
 
-       ret = kernctl_get_events_discarded(infd, &index->events_discarded);
+       ret = kernctl_get_events_discarded(infd, &events_discarded);
        if (ret < 0) {
                PERROR("kernctl_get_events_discarded");
                goto error;
        }
-       index->events_discarded = htobe64(index->events_discarded);
 
-       ret = kernctl_get_content_size(infd, &index->content_size);
+       ret = kernctl_get_content_size(infd, &content_size);
        if (ret < 0) {
                PERROR("kernctl_get_content_size");
                goto error;
        }
-       index->content_size = htobe64(index->content_size);
 
-       ret = kernctl_get_packet_size(infd, &index->packet_size);
+       ret = kernctl_get_packet_size(infd, &packet_size);
        if (ret < 0) {
                PERROR("kernctl_get_packet_size");
                goto error;
        }
-       index->packet_size = htobe64(index->packet_size);
 
-       ret = kernctl_get_stream_id(infd, &index->stream_id);
+       ret = kernctl_get_stream_id(infd, &stream_id);
        if (ret < 0) {
                PERROR("kernctl_get_stream_id");
                goto error;
        }
-       index->stream_id = htobe64(index->stream_id);
 
-       ret = kernctl_get_instance_id(infd, &index->stream_instance_id);
+       ret = kernctl_get_instance_id(infd, &stream_instance_id);
        if (ret < 0) {
                if (ret == -ENOTTY) {
                        /* Command not implemented by lttng-modules. */
-                       index->stream_instance_id = -1ULL;
+                       stream_instance_id = -1ULL;
                } else {
                        PERROR("kernctl_get_instance_id");
                        goto error;
                }
        }
-       index->stream_instance_id = htobe64(index->stream_instance_id);
 
-       ret = kernctl_get_sequence_number(infd, &index->packet_seq_num);
+       ret = kernctl_get_sequence_number(infd, &packet_seq_num);
        if (ret < 0) {
                if (ret == -ENOTTY) {
                        /* Command not implemented by lttng-modules. */
-                       index->packet_seq_num = -1ULL;
+                       packet_seq_num = -1ULL;
                        ret = 0;
                } else {
                        PERROR("kernctl_get_sequence_number");
@@ -1395,6 +1418,18 @@ static int get_index_values(struct ctf_packet_index *index, int infd)
        }
        index->packet_seq_num = htobe64(index->packet_seq_num);
 
+       *index = (typeof(*index)) {
+               .offset = index->offset,
+               .packet_size = htobe64(packet_size),
+               .content_size = htobe64(content_size),
+               .timestamp_begin = htobe64(timestamp_begin),
+               .timestamp_end = htobe64(timestamp_end),
+               .events_discarded = htobe64(events_discarded),
+               .stream_id = htobe64(stream_id),
+               .stream_instance_id = htobe64(stream_instance_id),
+               .packet_seq_num = htobe64(packet_seq_num),
+       };
+
 error:
        return ret;
 }
@@ -1446,6 +1481,7 @@ int update_stream_stats(struct lttng_consumer_stream *stream)
                if (ret == -ENOTTY) {
                        /* Command not implemented by lttng-modules. */
                        seq = -1ULL;
+                       stream->sequence_number_unavailable = true;
                } else {
                        PERROR("kernctl_get_sequence_number");
                        goto end;
@@ -1545,7 +1581,7 @@ ssize_t lttng_kconsumer_read_subbuffer(struct lttng_consumer_stream *stream,
        int err, write_index = 1, rotation_ret;
        ssize_t ret = 0;
        int infd = stream->wait_fd;
-       struct ctf_packet_index index;
+       struct ctf_packet_index index = {};
 
        DBG("In read_subbuffer (infd : %d)", infd);
 
@@ -1675,6 +1711,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) {
@@ -1694,13 +1733,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
@@ -1720,11 +1766,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) {
This page took 0.026696 seconds and 4 git commands to generate.