X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=libringbuffer%2Ffrontend_internal.h;h=00b9508d4df54768767fbe0aaff401cb0f965b0d;hb=358b7b742dd749ca68218c82daa31dd9cc91fb51;hp=77a431295a71b495d72fff3de74c31b8aff761eb;hpb=34a91bdb42a2a3b01b687ab5e1ba7638401e6dfc;p=lttng-ust.git diff --git a/libringbuffer/frontend_internal.h b/libringbuffer/frontend_internal.h index 77a43129..00b9508d 100644 --- a/libringbuffer/frontend_internal.h +++ b/libringbuffer/frontend_internal.h @@ -365,6 +365,13 @@ void lib_ring_buffer_wakeup(struct lttng_ust_lib_ring_buffer *buf, } } +/* + * Receive end of subbuffer TSC as parameter. It has been read in the + * space reservation loop of either reserve or switch, which ensures it + * progresses monotonically with event records in the buffer. Therefore, + * it ensures that the end timestamp of a subbuffer is <= begin + * timestamp of the following subbuffers. + */ static inline void lib_ring_buffer_check_deliver(const struct lttng_ust_lib_ring_buffer_config *config, struct lttng_ust_lib_ring_buffer *buf, @@ -372,11 +379,11 @@ void lib_ring_buffer_check_deliver(const struct lttng_ust_lib_ring_buffer_config unsigned long offset, unsigned long commit_count, unsigned long idx, - struct lttng_ust_shm_handle *handle) + struct lttng_ust_shm_handle *handle, + uint64_t tsc) { unsigned long old_commit_count = commit_count - chan->backend.subbuf_size; - uint64_t tsc; /* Check if all commits have been done */ if (caa_unlikely((buf_trunc(offset, chan) >> chan->backend.num_subbuf_order) @@ -407,6 +414,12 @@ void lib_ring_buffer_check_deliver(const struct lttng_ust_lib_ring_buffer_config * The subbuffer size is least 2 bytes (minimum size: 1 page). * This guarantees that old_commit_count + 1 != commit_count. */ + + /* + * Order prior updates to reserve count prior to the + * commit_cold cc_sb update. + */ + cmm_smp_wmb(); if (caa_likely(v_cmpxchg(config, &shmp_index(handle, buf->commit_cold, idx)->cc_sb, old_commit_count, old_commit_count + 1) == old_commit_count)) { @@ -416,7 +429,6 @@ void lib_ring_buffer_check_deliver(const struct lttng_ust_lib_ring_buffer_config * and any other writer trying to access this subbuffer * in this state is required to drop records. */ - tsc = config->cb.ring_buffer_clock_read(chan); v_add(config, subbuffer_get_records_count(config, &buf->backend, @@ -434,6 +446,12 @@ void lib_ring_buffer_check_deliver(const struct lttng_ust_lib_ring_buffer_config handle), handle); + /* + * Increment the packet counter while we have exclusive + * access. + */ + subbuffer_inc_packet_count(config, &buf->backend, idx, handle); + /* * Set noref flag and offset for this subbuffer id. * Contains a memory barrier that ensures counter stores @@ -452,6 +470,11 @@ void lib_ring_buffer_check_deliver(const struct lttng_ust_lib_ring_buffer_config /* End of exclusive subbuffer access */ v_set(config, &shmp_index(handle, buf->commit_cold, idx)->cc_sb, commit_count); + /* + * Order later updates to reserve count after + * the commit cold cc_sb update. + */ + cmm_smp_wmb(); lib_ring_buffer_vmcore_check_deliver(config, buf, commit_count, idx, handle); @@ -482,23 +505,20 @@ void lib_ring_buffer_write_commit_counter(const struct lttng_ust_lib_ring_buffer unsigned long idx, unsigned long buf_offset, unsigned long commit_count, - size_t slot_size, struct lttng_ust_shm_handle *handle) { - unsigned long offset, commit_seq_old; + unsigned long commit_seq_old; if (config->oops != RING_BUFFER_OOPS_CONSISTENCY) return; - offset = buf_offset + slot_size; - /* * subbuf_offset includes commit_count_mask. We can simply * compare the offsets within the subbuffer without caring about * buffer full/empty mismatch because offset is never zero here * (subbuffer header and record headers have non-zero length). */ - if (caa_unlikely(subbuf_offset(offset - commit_count, chan))) + if (caa_unlikely(subbuf_offset(buf_offset - commit_count, chan))) return; commit_seq_old = v_read(config, &shmp_index(handle, buf->commit_hot, idx)->seq);