Project

General

Profile

Bug #1183 » 0001-Fix-timestamp_end-field-should-include-all-events-wi.patch

modules - Mathieu Desnoyers, 04/30/2019 12:07 PM

View differences:

lib/ringbuffer/frontend_types.h
120 120

  
121 121
	struct commit_counters_cold *commit_cold;
122 122
					/* Commit count per sub-buffer */
123
	u64 *ts_end;			/*
124
					 * timestamp_end per sub-buffer.
125
					 * Time is sampled by the
126
					 * switch_*_end() callbacks which
127
					 * are the last space reservation
128
					 * performed in the sub-buffer
129
					 * before it can be fully
130
					 * committed and delivered. This
131
					 * time value is then read by
132
					 * the deliver callback,
133
					 * performed by the last commit
134
					 * before the buffer becomes
135
					 * readable.
136
					 */
123 137
	atomic_long_t active_readers;	/*
124 138
					 * Active readers count
125 139
					 * standard atomic access (shared)
lib/ringbuffer/ring_buffer_frontend.c
136 136
	lib_ring_buffer_print_errors(chan, buf, buf->backend.cpu);
137 137
	lttng_kvfree(buf->commit_hot);
138 138
	lttng_kvfree(buf->commit_cold);
139
	lttng_kvfree(buf->ts_end);
139 140

  
140 141
	lib_ring_buffer_backend_free(&buf->backend);
141 142
}
......
165 166
		v_set(config, &buf->commit_hot[i].cc, 0);
166 167
		v_set(config, &buf->commit_hot[i].seq, 0);
167 168
		v_set(config, &buf->commit_cold[i].cc_sb, 0);
169
		buf->ts_end[i] = 0;
168 170
	}
169 171
	atomic_long_set(&buf->consumed, 0);
170 172
	atomic_set(&buf->record_disabled, 0);
......
253 255
		goto free_commit;
254 256
	}
255 257

  
258
	buf->ts_end =
259
		lttng_kvzalloc_node(ALIGN(sizeof(*buf->ts_end)
260
				   * chan->backend.num_subbuf,
261
				   1 << INTERNODE_CACHE_SHIFT),
262
			GFP_KERNEL | __GFP_NOWARN,
263
			cpu_to_node(max(cpu, 0)));
264
	if (!buf->ts_end) {
265
		ret = -ENOMEM;
266
		goto free_commit_cold;
267
	}
268

  
256 269
	init_waitqueue_head(&buf->read_wait);
257 270
	init_waitqueue_head(&buf->write_wait);
258 271
	raw_spin_lock_init(&buf->raw_tick_nohz_spinlock);
......
292 305

  
293 306
	/* Error handling */
294 307
free_init:
308
	lttng_kvfree(buf->ts_end);
309
free_commit_cold:
295 310
	lttng_kvfree(buf->commit_cold);
296 311
free_commit:
297 312
	lttng_kvfree(buf->commit_hot);
......
1582 1597
	unsigned long oldidx = subbuf_index(offsets->old - 1, chan);
1583 1598
	unsigned long commit_count, padding_size, data_size;
1584 1599
	struct commit_counters_hot *cc_hot;
1600
	u64 *ts_end;
1585 1601

  
1586 1602
	data_size = subbuf_offset(offsets->old - 1, chan) + 1;
1587 1603
	padding_size = chan->backend.subbuf_size - data_size;
1588 1604
	subbuffer_set_data_size(config, &buf->backend, oldidx, data_size);
1589 1605

  
1606
	ts_end = &buf->ts_end[oldidx];
1590 1607
	/*
1591
	 * Order all writes to buffer before the commit count update that will
1592
	 * determine that the subbuffer is full.
1608
	 * This is the last space reservation in that sub-buffer before
1609
	 * it gets delivered. This provides exclusive access to write to
1610
	 * this sub-buffer's ts_end. There are also no concurrent
1611
	 * readers of that ts_end because delivery of that sub-buffer is
1612
	 * postponed until the commit counter is incremented for the
1613
	 * current space reservation.
1614
	 */
1615
	*ts_end = tsc;
1616

  
1617
	/*
1618
	 * Order all writes to buffer and store to ts_end before the commit
1619
	 * count update that will determine that the subbuffer is full.
1593 1620
	 */
1594 1621
	if (config->ipi == RING_BUFFER_IPI_BARRIER) {
1595 1622
		/*
......
1670 1697
{
1671 1698
	const struct lib_ring_buffer_config *config = &chan->backend.config;
1672 1699
	unsigned long endidx, data_size;
1700
	u64 *ts_end;
1673 1701

  
1674 1702
	endidx = subbuf_index(offsets->end - 1, chan);
1675 1703
	data_size = subbuf_offset(offsets->end - 1, chan) + 1;
1676 1704
	subbuffer_set_data_size(config, &buf->backend, endidx, data_size);
1705
	ts_end = &buf->ts_end[endidx];
1706
	/*
1707
	 * This is the last space reservation in that sub-buffer before
1708
	 * it gets delivered. This provides exclusive access to write to
1709
	 * this sub-buffer's ts_end. There are also no concurrent
1710
	 * readers of that ts_end because delivery of that sub-buffer is
1711
	 * postponed until the commit counter is incremented for the
1712
	 * current space reservation.
1713
	 */
1714
	*ts_end = tsc;
1677 1715
}
1678 1716

  
1679 1717
/*
......
2237 2275
	if (likely(v_cmpxchg(config, &buf->commit_cold[idx].cc_sb,
2238 2276
				 old_commit_count, old_commit_count + 1)
2239 2277
		   == old_commit_count)) {
2278
		u64 *ts_end;
2279

  
2240 2280
		/*
2241 2281
		 * Start of exclusive subbuffer access. We are
2242 2282
		 * guaranteed to be the last writer in this subbuffer
2243 2283
		 * and any other writer trying to access this subbuffer
2244 2284
		 * in this state is required to drop records.
2285
		 *
2286
		 * We can read the ts_end for the current sub-buffer
2287
		 * which has been saved by the very last space
2288
		 * reservation for the current sub-buffer.
2289
		 *
2290
		 * Order increment of commit counter before reading ts_end.
2245 2291
		 */
2292
		smp_mb();
2293
		ts_end = &buf->ts_end[idx];
2246 2294
		deliver_count_events(config, buf, idx);
2247
		config->cb.buffer_end(buf, tsc, idx,
2295
		config->cb.buffer_end(buf, *ts_end, idx,
2248 2296
				      lib_ring_buffer_get_data_size(config,
2249 2297
								buf,
2250 2298
								idx));
2251
- 
(1-1/2)