*
*/
-#include <common/pipe.hpp>
-#include <common/utils.hpp>
-
+#include "health-sessiond.hpp"
+#include "kernel-consumer.hpp"
+#include "kernel.hpp"
#include "manage-kernel.hpp"
#include "testpoint.hpp"
-#include "health-sessiond.hpp"
-#include "utils.hpp"
#include "thread.hpp"
-#include "kernel.hpp"
-#include "kernel-consumer.hpp"
+#include "utils.hpp"
+#include <common/pipe.hpp>
+#include <common/urcu.hpp>
+#include <common/utils.hpp>
+
+namespace {
struct thread_notifiers {
struct lttng_pipe *quit_pipe;
int kernel_poll_pipe_read_fd;
};
+} /* namespace */
/*
* Update the kernel poll set of all channel fd available over all tracing
DBG("Updating kernel poll set");
session_lock_list();
- cds_list_for_each_entry(session, &session_list->head, list) {
+ cds_list_for_each_entry (session, &session_list->head, list) {
if (!session_get(session)) {
continue;
}
session_lock(session);
- if (session->kernel_session == NULL) {
+ if (session->kernel_session == nullptr) {
session_unlock(session);
session_put(session);
continue;
}
- cds_list_for_each_entry(channel,
- &session->kernel_session->channel_list.head, list) {
+ cds_list_for_each_entry (
+ channel, &session->kernel_session->channel_list.head, list) {
/* Add channel fd to the kernel poll set */
ret = lttng_poll_add(events, channel->fd, LPOLLIN | LPOLLRDNORM);
if (ret < 0) {
DBG("Updating kernel streams for channel fd %d", fd);
session_lock_list();
- cds_list_for_each_entry(session, &session_list->head, list) {
+ cds_list_for_each_entry (session, &session_list->head, list) {
if (!session_get(session)) {
continue;
}
+
session_lock(session);
- if (session->kernel_session == NULL) {
+ if (session->kernel_session == nullptr) {
session_unlock(session);
session_put(session);
continue;
}
+
ksess = session->kernel_session;
- cds_list_for_each_entry(channel,
- &ksess->channel_list.head, list) {
+ cds_list_for_each_entry (channel, &ksess->channel_list.head, list) {
struct lttng_ht_iter iter;
struct consumer_socket *socket;
* means that tracing is started so it is safe to send
* our updated stream fds.
*/
- if (ksess->consumer_fds_sent != 1
- || ksess->consumer == NULL) {
+ if (ksess->consumer_fds_sent != 1 || ksess->consumer == nullptr) {
ret = -1;
goto error;
}
- rcu_read_lock();
- cds_lfht_for_each_entry(ksess->consumer->socks->ht,
- &iter.iter, socket, node.node) {
- pthread_mutex_lock(socket->lock);
- ret = kernel_consumer_send_channel_streams(socket,
- channel, ksess,
+ {
+ lttng::urcu::read_lock_guard read_lock;
+
+ cds_lfht_for_each_entry (
+ ksess->consumer->socks->ht, &iter.iter, socket, node.node) {
+ pthread_mutex_lock(socket->lock);
+ ret = kernel_consumer_send_channel_streams(
+ socket,
+ channel,
+ ksess,
session->output_traces ? 1 : 0);
- pthread_mutex_unlock(socket->lock);
- if (ret < 0) {
- rcu_read_unlock();
- goto error;
+ pthread_mutex_unlock(socket->lock);
+ if (ret < 0) {
+ goto error;
+ }
}
}
- rcu_read_unlock();
}
+
session_unlock(session);
session_put(session);
}
*/
static void *thread_kernel_management(void *data)
{
- int ret, i, pollfd, update_poll_flag = 1, err = -1;
- uint32_t revents, nb_fd;
+ int ret, i, update_poll_flag = 1, err = -1;
+ uint32_t nb_fd;
char tmp;
struct lttng_poll_event events;
struct thread_notifiers *notifiers = (thread_notifiers *) data;
- const int quit_pipe_read_fd = lttng_pipe_get_readfd(notifiers->quit_pipe);
+ const auto thread_quit_pipe_fd = lttng_pipe_get_readfd(notifiers->quit_pipe);
DBG("[thread] Thread manage kernel started");
goto error_testpoint;
}
- while (1) {
+ while (true) {
health_code_update();
if (update_poll_flag == 1) {
goto error_poll_create;
}
- ret = lttng_poll_add(&events,
- notifiers->kernel_poll_pipe_read_fd,
- LPOLLIN);
+ ret = lttng_poll_add(&events, notifiers->kernel_poll_pipe_read_fd, LPOLLIN);
if (ret < 0) {
goto error;
}
- ret = lttng_poll_add(&events,
- quit_pipe_read_fd,
- LPOLLIN);
+ ret = lttng_poll_add(&events, thread_quit_pipe_fd, LPOLLIN);
if (ret < 0) {
goto error;
}
restart:
health_poll_entry();
ret = lttng_poll_wait(&events, -1);
- DBG("Thread kernel return from poll on %d fds",
- LTTNG_POLL_GETNB(&events));
+ DBG("Thread kernel return from poll on %d fds", LTTNG_POLL_GETNB(&events));
health_poll_exit();
if (ret < 0) {
/*
} else if (ret == 0) {
/* Should not happen since timeout is infinite */
ERR("Return value of poll is 0 with an infinite timeout.\n"
- "This should not have happened! Continuing...");
+ "This should not have happened! Continuing...");
continue;
}
for (i = 0; i < nb_fd; i++) {
/* Fetch once the poll data */
- revents = LTTNG_POLL_GETEV(&events, i);
- pollfd = LTTNG_POLL_GETFD(&events, i);
+ const auto revents = LTTNG_POLL_GETEV(&events, i);
+ const auto pollfd = LTTNG_POLL_GETFD(&events, i);
health_code_update();
- if (pollfd == quit_pipe_read_fd) {
+ /* Activity on thread quit pipe, exiting. */
+ if (pollfd == thread_quit_pipe_fd) {
+ DBG("Activity on thread quit pipe");
err = 0;
goto exit;
}
/* Check for data on kernel pipe */
if (revents & LPOLLIN) {
if (pollfd == notifiers->kernel_poll_pipe_read_fd) {
- (void) lttng_read(notifiers->kernel_poll_pipe_read_fd,
- &tmp, 1);
+ (void) lttng_read(
+ notifiers->kernel_poll_pipe_read_fd, &tmp, 1);
/*
- * Ret value is useless here, if this pipe gets any actions an
- * update is required anyway.
+ * Ret value is useless here, if this pipe gets any actions
+ * an update is required anyway.
*/
update_poll_flag = 1;
continue;
health_error();
ERR("Health error occurred in %s", __func__);
WARN("Kernel thread died unexpectedly. "
- "Kernel tracing can continue but CPU hotplug is disabled.");
+ "Kernel tracing can continue but CPU hotplug is disabled.");
}
health_unregister(the_health_sessiond);
DBG("Kernel thread dying");
- return NULL;
+ return nullptr;
}
static bool shutdown_kernel_management_thread(void *data)
bool launch_kernel_management_thread(int kernel_poll_pipe_read_fd)
{
struct lttng_pipe *quit_pipe;
- struct thread_notifiers *notifiers = NULL;
+ struct thread_notifiers *notifiers = nullptr;
struct lttng_thread *thread;
- notifiers = (thread_notifiers *) zmalloc(sizeof(*notifiers));
+ notifiers = zmalloc<thread_notifiers>();
if (!notifiers) {
goto error_alloc;
}
notifiers->kernel_poll_pipe_read_fd = kernel_poll_pipe_read_fd;
thread = lttng_thread_create("Kernel management",
- thread_kernel_management,
- shutdown_kernel_management_thread,
- cleanup_kernel_management_thread,
- notifiers);
+ thread_kernel_management,
+ shutdown_kernel_management_thread,
+ cleanup_kernel_management_thread,
+ notifiers);
if (!thread) {
goto error;
}