~ubuntu-branches/ubuntu/wily/ust/wily-proposed

« back to all changes in this revision

Viewing changes to libringbuffer/ring_buffer_frontend.c

  • Committer: Package Import Robot
  • Author(s): Artur Rona
  • Date: 2015-06-24 14:18:03 UTC
  • mfrom: (11.2.11 sid)
  • Revision ID: package-import@ubuntu.com-20150624141803-zfj6xzpr7dlxiysg
Tags: 2.6.2-1ubuntu1
* Merge from Debian unstable. (LP: #1468345) Remaining changes:
  - debian/control, debian/patches/use-python3.patch:
    + Switch to use python3. (Closes: #789790)
* Drop following changes, fixed in Debian / upstream:
  - debian/patches/0001-Add-aarch64-host-cpu-in-configure.ac.patch:
    + Add arm64 host_cpu stanzas in configure.ac
  - debian/liblttng-ust0.symbols:
    + Update symbols file.
  - debian/control:
    + Enable builds on arm64 and ppc64el.

Show diffs side-by-side

added added

removed removed

Lines of Context:
62
62
#include <urcu/compiler.h>
63
63
#include <urcu/ref.h>
64
64
#include <urcu/tls-compat.h>
 
65
#include <poll.h>
65
66
#include <helper.h>
66
67
 
67
68
#include "smp.h"
84
85
#define LTTNG_UST_RB_SIG_READ           SIGRTMIN + 1
85
86
#define LTTNG_UST_RB_SIG_TEARDOWN       SIGRTMIN + 2
86
87
#define CLOCKID         CLOCK_MONOTONIC
 
88
#define LTTNG_UST_RING_BUFFER_GET_RETRY         10
 
89
#define LTTNG_UST_RING_BUFFER_RETRY_DELAY_MS    10
87
90
 
88
91
/*
89
92
 * Use POSIX SHM: shm_open(3) and shm_unlink(3).
1067
1070
        struct channel *chan = shmp(handle, buf->backend.chan);
1068
1071
        const struct lttng_ust_lib_ring_buffer_config *config = &chan->backend.config;
1069
1072
        unsigned long consumed_cur, consumed_idx, commit_count, write_offset;
1070
 
        int ret;
1071
 
        int finalized;
 
1073
        int ret, finalized, nr_retry = LTTNG_UST_RING_BUFFER_GET_RETRY;
1072
1074
 
1073
1075
retry:
1074
1076
        finalized = CMM_ACCESS_ONCE(buf->finalized);
1103
1105
 
1104
1106
        /*
1105
1107
         * Check that the subbuffer we are trying to consume has been
1106
 
         * already fully committed.
 
1108
         * already fully committed. There are a few causes that can make
 
1109
         * this unavailability situation occur:
 
1110
         *
 
1111
         * Temporary (short-term) situation:
 
1112
         * - Application is running on a different CPU, between reserve
 
1113
         *   and commit ring buffer operations,
 
1114
         * - Application is preempted between reserve and commit ring
 
1115
         *   buffer operations,
 
1116
         *
 
1117
         * Long-term situation:
 
1118
         * - Application is stopped (SIGSTOP) between reserve and commit
 
1119
         *   ring buffer operations. Could eventually be resumed by
 
1120
         *   SIGCONT.
 
1121
         * - Application is killed (SIGTERM, SIGINT, SIGKILL) between
 
1122
         *   reserve and commit ring buffer operation.
 
1123
         *
 
1124
         * From a consumer perspective, handling short-term
 
1125
         * unavailability situations is performed by retrying a few
 
1126
         * times after a delay. Handling long-term unavailability
 
1127
         * situations is handled by failing to get the sub-buffer.
 
1128
         *
 
1129
         * In all of those situations, if the application is taking a
 
1130
         * long time to perform its commit after ring buffer space
 
1131
         * reservation, we can end up in a situation where the producer
 
1132
         * will fill the ring buffer and try to write into the same
 
1133
         * sub-buffer again (which has a missing commit). This is
 
1134
         * handled by the producer in the sub-buffer switch handling
 
1135
         * code of the reserve routine by detecting unbalanced
 
1136
         * reserve/commit counters and discarding all further events
 
1137
         * until the situation is resolved in those situations. Two
 
1138
         * scenarios can occur:
 
1139
         *
 
1140
         * 1) The application causing the reserve/commit counters to be
 
1141
         *    unbalanced has been terminated. In this situation, all
 
1142
         *    further events will be discarded in the buffers, and no
 
1143
         *    further buffer data will be readable by the consumer
 
1144
         *    daemon. Tearing down the UST tracing session and starting
 
1145
         *    anew is a work-around for those situations. Note that this
 
1146
         *    only affects per-UID tracing. In per-PID tracing, the
 
1147
         *    application vanishes with the termination, and therefore
 
1148
         *    no more data needs to be written to the buffers.
 
1149
         * 2) The application causing the unbalance has been delayed for
 
1150
         *    a long time, but will eventually try to increment the
 
1151
         *    commit counter after eventually writing to the sub-buffer.
 
1152
         *    This situation can cause events to be discarded until the
 
1153
         *    application resumes its operations.
1107
1154
         */
1108
1155
        if (((commit_count - chan->backend.subbuf_size)
1109
1156
             & chan->commit_count_mask)
1110
1157
            - (buf_trunc(consumed, chan)
1111
1158
               >> chan->backend.num_subbuf_order)
1112
 
            != 0)
1113
 
                goto nodata;
 
1159
            != 0) {
 
1160
                if (nr_retry-- > 0) {
 
1161
                        if (nr_retry <= (LTTNG_UST_RING_BUFFER_GET_RETRY >> 1))
 
1162
                                (void) poll(NULL, 0, LTTNG_UST_RING_BUFFER_RETRY_DELAY_MS);
 
1163
                        goto retry;
 
1164
                } else {
 
1165
                        goto nodata;
 
1166
                }
 
1167
        }
1114
1168
 
1115
1169
        /*
1116
1170
         * Check that we are not about to read the same subbuffer in
1126
1180
         * the writer is getting access to a subbuffer we were trying to get
1127
1181
         * access to. Also checks that the "consumed" buffer count we are
1128
1182
         * looking for matches the one contained in the subbuffer id.
 
1183
         *
 
1184
         * The short-lived race window described here can be affected by
 
1185
         * application signals and preemption, thus requiring to bound
 
1186
         * the loop to a maximum number of retry.
1129
1187
         */
1130
1188
        ret = update_read_sb_index(config, &buf->backend, &chan->backend,
1131
1189
                                   consumed_idx, buf_trunc_val(consumed, chan),
1132
1190
                                   handle);
1133
 
        if (ret)
1134
 
                goto retry;
 
1191
        if (ret) {
 
1192
                if (nr_retry-- > 0) {
 
1193
                        if (nr_retry <= (LTTNG_UST_RING_BUFFER_GET_RETRY >> 1))
 
1194
                                (void) poll(NULL, 0, LTTNG_UST_RING_BUFFER_RETRY_DELAY_MS);
 
1195
                        goto retry;
 
1196
                } else {
 
1197
                        goto nodata;
 
1198
                }
 
1199
        }
1135
1200
        subbuffer_id_clear_noref(config, &buf->backend.buf_rsb.id);
1136
1201
 
1137
1202
        buf->get_subbuf_consumed = consumed;