Bug #405 » 0001-Fix-locking-order-between-consumer-and-stream.patch
src/common/consumer.c | ||
---|---|---|
goto free_stream;
|
||
}
|
||
pthread_mutex_lock(&stream->lock);
|
||
pthread_mutex_lock(&consumer_data.lock);
|
||
pthread_mutex_lock(&stream->lock);
|
||
switch (consumer_data.type) {
|
||
case LTTNG_CONSUMER_KERNEL:
|
||
... | ... | |
end:
|
||
consumer_data.need_update = 1;
|
||
pthread_mutex_unlock(&consumer_data.lock);
|
||
pthread_mutex_unlock(&stream->lock);
|
||
pthread_mutex_unlock(&consumer_data.lock);
|
||
if (free_chan) {
|
||
consumer_del_channel(free_chan);
|
||
... | ... | |
/* RCU lock for the relayd pointer */
|
||
rcu_read_lock();
|
||
pthread_mutex_lock(&stream->lock);
|
||
/* Flag that the current stream if set for network streaming. */
|
||
if (stream->net_seq_idx != -1) {
|
||
relayd = consumer_find_relayd(stream->net_seq_idx);
|
||
... | ... | |
if (relayd && stream->metadata_flag) {
|
||
pthread_mutex_unlock(&relayd->ctrl_sock_mutex);
|
||
}
|
||
pthread_mutex_unlock(&stream->lock);
|
||
rcu_read_unlock();
|
||
return written;
|
||
... | ... | |
/* RCU lock for the relayd pointer */
|
||
rcu_read_lock();
|
||
pthread_mutex_lock(&stream->lock);
|
||
/* Flag that the current stream if set for network streaming. */
|
||
if (stream->net_seq_idx != -1) {
|
||
relayd = consumer_find_relayd(stream->net_seq_idx);
|
||
... | ... | |
if (relayd && stream->metadata_flag) {
|
||
pthread_mutex_unlock(&relayd->ctrl_sock_mutex);
|
||
}
|
||
pthread_mutex_unlock(&stream->lock);
|
||
rcu_read_unlock();
|
||
return written;
|
||
... | ... | |
goto free_stream;
|
||
}
|
||
pthread_mutex_lock(&consumer_data.lock);
|
||
pthread_mutex_lock(&stream->lock);
|
||
pthread_mutex_lock(&consumer_data.lock);
|
||
switch (consumer_data.type) {
|
||
case LTTNG_CONSUMER_KERNEL:
|
||
if (stream->mmap_base != NULL) {
|
||
... | ... | |
}
|
||
end:
|
||
pthread_mutex_unlock(&consumer_data.lock);
|
||
pthread_mutex_unlock(&stream->lock);
|
||
pthread_mutex_unlock(&consumer_data.lock);
|
||
if (free_chan) {
|
||
consumer_del_channel(free_chan);
|
||
... | ... | |
ssize_t lttng_consumer_read_subbuffer(struct lttng_consumer_stream *stream,
|
||
struct lttng_consumer_local_data *ctx)
|
||
{
|
||
int ret;
|
||
pthread_mutex_lock(&stream->lock);
|
||
switch (consumer_data.type) {
|
||
case LTTNG_CONSUMER_KERNEL:
|
||
return lttng_kconsumer_read_subbuffer(stream, ctx);
|
||
ret = lttng_kconsumer_read_subbuffer(stream, ctx);
|
||
case LTTNG_CONSUMER32_UST:
|
||
case LTTNG_CONSUMER64_UST:
|
||
return lttng_ustconsumer_read_subbuffer(stream, ctx);
|
||
ret = lttng_ustconsumer_read_subbuffer(stream, ctx);
|
||
default:
|
||
ERR("Unknown consumer_data type");
|
||
assert(0);
|
||
return -ENOSYS;
|
||
ret = -ENOSYS;
|
||
}
|
||
pthread_mutex_unlock(&stream->lock);
|
||
return ret;
|
||
}
|
||
int lttng_consumer_on_recv_stream(struct lttng_consumer_stream *stream)
|
src/common/consumer.h | ||
---|---|---|
/* Next sequence number to use for trace packet */
|
||
uint64_t next_net_seq_num;
|
||
/*
|
||
* Lock to use the stream FDs since they are used between threads. Using
|
||
* this lock with network streaming, when using the control mutex of a
|
||
* consumer_relayd_sock_pair, make sure to acquire this lock BEFORE locking
|
||
* it and releasing it AFTER the control mutex unlock.
|
||
* Lock to use the stream FDs since they are used between threads.
|
||
*
|
||
* This is nested INSIDE the consumer_data lock.
|
||
* This is nested OUTSIDE consumer_relayd_sock_pair lock.
|
||
*/
|
||
pthread_mutex_t lock;
|
||
/* Tracing session id */
|
||
... | ... | |
* between threads sending data to the relayd. Since metadata data is sent
|
||
* over that socket, at least two sendmsg() are needed (header + data)
|
||
* creating a race for packets to overlap between threads using it.
|
||
*
|
||
* This is nested INSIDE the consumer_data lock.
|
||
* This is nested INSIDE the stream lock.
|
||
*/
|
||
pthread_mutex_t ctrl_sock_mutex;
|
||
... | ... | |
* and number of element in the hash table. It's also a protection for
|
||
* concurrent read/write between threads.
|
||
*
|
||
* XXX: We need to see if this lock is still needed with the lockless RCU
|
||
* hash tables.
|
||
* This is nested OUTSIDE the stream lock.
|
||
* This is nested OUTSIDE the consumer_relayd_sock_pair lock.
|
||
*/
|
||
pthread_mutex_t lock;
|
||