Project

General

Profile

Bug #405 » 0001-Fix-locking-order-between-consumer-and-stream.patch

David Goulet, 12/04/2012 07:52 PM

View differences:

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);
break;
case LTTNG_CONSUMER32_UST:
case LTTNG_CONSUMER64_UST:
return lttng_ustconsumer_read_subbuffer(stream, ctx);
ret = lttng_ustconsumer_read_subbuffer(stream, ctx);
break;
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;
(4-4/4)