This patch removes the ht_del of sessions from the delete_ust_app RCU
call and puts it in the unregister app function just before the call_rcu
is done.
To be able to free the sessions in the call rcu, a list is added for
which, when in tearing down an application or session, this list is used
to get the session reference for deletion.
Note that when in the RCU call, we are assured that the list is
exclusively accessed thus no need for any locking.
Acked-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: David Goulet <dgoulet@efficios.com>
void delete_ust_app(struct ust_app *app)
{
int ret, sock;
void delete_ust_app(struct ust_app *app)
{
int ret, sock;
- struct lttng_ht_iter iter;
- struct ust_app_session *ua_sess;
+ struct ust_app_session *ua_sess, *tmp_ua_sess;
sock = app->sock;
app->sock = -1;
sock = app->sock;
app->sock = -1;
+ lttng_ht_destroy(app->sessions);
+
- cds_lfht_for_each_entry(app->sessions->ht, &iter.iter, ua_sess,
- node.node) {
- ret = lttng_ht_del(app->sessions, &iter);
- if (ret) {
- /* The session is already scheduled for teardown. */
- continue;
- }
- delete_ust_app_session(app->sock, ua_sess);
+ cds_list_for_each_entry_safe(ua_sess, tmp_ua_sess, &app->teardown_head,
+ teardown_node) {
+ /* Free every object in the session and the session. */
+ delete_ust_app_session(sock, ua_sess);
- lttng_ht_destroy(app->sessions);
/*
* Wait until we have deleted the application from the sock hash table
/*
* Wait until we have deleted the application from the sock hash table
lta->sock = sock;
lttng_ht_node_init_ulong(<a->sock_n, (unsigned long)lta->sock);
lta->sock = sock;
lttng_ht_node_init_ulong(<a->sock_n, (unsigned long)lta->sock);
+ CDS_INIT_LIST_HEAD(<a->teardown_head);
+
struct ust_app *lta;
struct lttng_ht_node_ulong *node;
struct lttng_ht_iter iter;
struct ust_app *lta;
struct lttng_ht_node_ulong *node;
struct lttng_ht_iter iter;
+ struct ust_app_session *ua_sess;
int ret;
rcu_read_lock();
int ret;
rcu_read_lock();
+ /* Remove sessions so they are not visible during deletion.*/
+ cds_lfht_for_each_entry(lta->sessions->ht, &iter.iter, ua_sess,
+ node.node) {
+ ret = lttng_ht_del(lta->sessions, &iter);
+ if (ret) {
+ /* The session was already removed so scheduled for teardown. */
+ continue;
+ }
+
+ /*
+ * Add session to list for teardown. This is safe since at this point we
+ * are the only one using this list.
+ */
+ cds_list_add(&ua_sess->teardown_node, <a->teardown_head);
+ }
+
/* Free memory */
call_rcu(<a->pid_n.head, delete_ust_app_rcu);
/* Free memory */
call_rcu(<a->pid_n.head, delete_ust_app_rcu);
ua_sess = lookup_session_by_app(usess, app);
if (ua_sess == NULL) {
ua_sess = lookup_session_by_app(usess, app);
if (ua_sess == NULL) {
+ /* The session is in teardown process. Ignore and continue. */
+ goto end;
}
/* Upon restart, we skip the setup, already done */
}
/* Upon restart, we skip the setup, already done */
ua_sess = lookup_session_by_app(usess, app);
if (ua_sess == NULL) {
ua_sess = lookup_session_by_app(usess, app);
if (ua_sess == NULL) {
- /* Only malloc can failed so something is really wrong */
- goto error_rcu_unlock;
__lookup_session_by_app(usess, app, &iter);
node = lttng_ht_iter_get_node_ulong(&iter);
if (node == NULL) {
__lookup_session_by_app(usess, app, &iter);
node = lttng_ht_iter_get_node_ulong(&iter);
if (node == NULL) {
- /* Only malloc can failed so something is really wrong */
- goto error_rcu_unlock;
+ /* Session is being or is deleted. */
+ goto end;
}
ua_sess = caa_container_of(node, struct ust_app_session, node);
ret = lttng_ht_del(app->sessions, &iter);
}
ua_sess = caa_container_of(node, struct ust_app_session, node);
ret = lttng_ht_del(app->sessions, &iter);
rcu_read_unlock();
health_code_update(&health_thread_cmd);
return 0;
rcu_read_unlock();
health_code_update(&health_thread_cmd);
return 0;
-
-error_rcu_unlock:
- rcu_read_unlock();
- health_code_update(&health_thread_cmd);
- return -1;
/* UID/GID of the user owning the session */
uid_t uid;
gid_t gid;
/* UID/GID of the user owning the session */
uid_t uid;
gid_t gid;
+ struct cds_list_head teardown_node;
struct lttng_ht *sessions;
struct lttng_ht_node_ulong pid_n;
struct lttng_ht_node_ulong sock_n;
struct lttng_ht *sessions;
struct lttng_ht_node_ulong pid_n;
struct lttng_ht_node_ulong sock_n;
+ /*
+ * This is a list of ust app session that, once the app is going into
+ * teardown mode, in the RCU call, each node in this list is removed and
+ * deleted.
+ *
+ * Element of the list are added when an application unregisters after each
+ * ht_del of ust_app_session associated to this app. This list is NOT used
+ * when a session is destroyed.
+ */
+ struct cds_list_head teardown_head;
};
#ifdef HAVE_LIBLTTNG_UST_CTL
};
#ifdef HAVE_LIBLTTNG_UST_CTL