Skip to content

Commit e7a0ca7

Browse files
committed
statedump: introduce file_table_address
Currently the LTTng-modules statedump simply iterates over all processes in the system and assumes all threads share the same file descriptor table, which is only true if threads were created with clone CLONE_FILES. Directly invoking clone without the CLONE_FILES creates threads which belong to the same process, but have their own file descriptor table. Therefore, model-wise, we cannot assume that all threads in a process have the same fd table content. Add a new "file_table_address" field to the lttng_statedump_process_state event, which dumps the address of the thread's struct files_struct pointer. This pointer is guaranteed to never be re-used while we hold the RCU read-side lock (so for the entire iteration over processes/threads). For the lttng_statedump_file_descriptor event, remove the "pid" field (which is semantically inaccurate) and add a "file_table_address" field, which contains the struct files_struct address of the file table containing the file descriptor. An optimization is performed to eliminate most duplcated file table content by skipping file table dump if the same file table address is encountered consecutively while iterating over a process' threads. This introduces a semantic change to the statedump fields, and will therefore be introduced in lttng-modules 2.12 onwards, not backported as a fix. Fixes: #1245 Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
1 parent 6314c2d commit e7a0ca7

File tree

2 files changed

+42
-44
lines changed

2 files changed

+42
-44
lines changed

instrumentation/events/lttng-module/lttng-statedump.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ LTTNG_TRACEPOINT_EVENT(lttng_statedump_end,
4040
LTTNG_TRACEPOINT_EVENT(lttng_statedump_process_state,
4141
TP_PROTO(struct lttng_session *session,
4242
struct task_struct *p,
43-
int type, int mode, int submode, int status),
44-
TP_ARGS(session, p, type, mode, submode, status),
43+
int type, int mode, int submode, int status,
44+
struct files_struct *files),
45+
TP_ARGS(session, p, type, mode, submode, status, files),
4546
TP_FIELDS(
4647
ctf_integer(pid_t, tid, p->pid)
4748
ctf_integer(pid_t, pid, p->tgid)
@@ -60,6 +61,7 @@ LTTNG_TRACEPOINT_EVENT(lttng_statedump_process_state,
6061
ctf_integer(int, submode, submode)
6162
ctf_integer(int, status, status)
6263
ctf_integer(unsigned int, cpu, task_cpu(p))
64+
ctf_integer_hex(struct files_struct *, file_table_address, files)
6365
)
6466
)
6567

@@ -179,11 +181,12 @@ LTTNG_TRACEPOINT_EVENT(lttng_statedump_process_uts_ns,
179181

180182
LTTNG_TRACEPOINT_EVENT(lttng_statedump_file_descriptor,
181183
TP_PROTO(struct lttng_session *session,
182-
struct task_struct *p, int fd, const char *filename,
184+
struct files_struct *files,
185+
int fd, const char *filename,
183186
unsigned int flags, fmode_t fmode),
184-
TP_ARGS(session, p, fd, filename, flags, fmode),
187+
TP_ARGS(session, files, fd, filename, flags, fmode),
185188
TP_FIELDS(
186-
ctf_integer(pid_t, pid, p->tgid)
189+
ctf_integer_hex(struct files_struct *, file_table_address, files)
187190
ctf_integer(int, fd, fd)
188191
ctf_integer_oct(unsigned int, flags, flags)
189192
ctf_integer_hex(fmode_t, fmode, fmode)

lttng-statedump-impl.c

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ DEFINE_TRACE(lttng_statedump_cpu_topology);
8080
struct lttng_fd_ctx {
8181
char *page;
8282
struct lttng_session *session;
83-
struct task_struct *p;
8483
struct files_struct *files;
8584
};
8685

@@ -245,51 +244,27 @@ int lttng_dump_one_fd(const void *p, struct file *file, unsigned int fd)
245244

246245
/* Make sure we give at least some info */
247246
spin_lock(&dentry->d_lock);
248-
trace_lttng_statedump_file_descriptor(ctx->session, ctx->p, fd,
249-
dentry->d_name.name, flags, file->f_mode);
247+
trace_lttng_statedump_file_descriptor(ctx->session,
248+
ctx->files, fd, dentry->d_name.name, flags,
249+
file->f_mode);
250250
spin_unlock(&dentry->d_lock);
251251
goto end;
252252
}
253-
trace_lttng_statedump_file_descriptor(ctx->session, ctx->p, fd, s,
254-
flags, file->f_mode);
253+
trace_lttng_statedump_file_descriptor(ctx->session,
254+
ctx->files, fd, s, flags, file->f_mode);
255255
end:
256256
return 0;
257257
}
258258

259+
/* Called with task lock held. */
259260
static
260-
void lttng_enumerate_task_fd(struct lttng_session *session,
261-
struct task_struct *p, char *tmp)
261+
void lttng_enumerate_files(struct lttng_session *session,
262+
struct files_struct *files,
263+
char *tmp)
262264
{
263-
struct lttng_fd_ctx ctx = { .page = tmp, .session = session, .p = p };
264-
struct files_struct *files;
265+
struct lttng_fd_ctx ctx = { .page = tmp, .session = session, .files = files, };
265266

266-
task_lock(p);
267-
files = p->files;
268-
if (!files)
269-
goto end;
270-
ctx.files = files;
271267
lttng_iterate_fd(files, 0, lttng_dump_one_fd, &ctx);
272-
end:
273-
task_unlock(p);
274-
}
275-
276-
static
277-
int lttng_enumerate_file_descriptors(struct lttng_session *session)
278-
{
279-
struct task_struct *p;
280-
char *tmp;
281-
282-
tmp = (char *) __get_free_page(GFP_KERNEL);
283-
if (!tmp)
284-
return -ENOMEM;
285-
286-
/* Enumerate active file descriptors */
287-
rcu_read_lock();
288-
for_each_process(p)
289-
lttng_enumerate_task_fd(session, p, tmp);
290-
rcu_read_unlock();
291-
free_page((unsigned long) tmp);
292-
return 0;
293268
}
294269

295270
#ifdef LTTNG_HAVE_STATEDUMP_CPU_TOPOLOGY
@@ -484,9 +459,16 @@ static
484459
int lttng_enumerate_process_states(struct lttng_session *session)
485460
{
486461
struct task_struct *g, *p;
462+
char *tmp;
463+
464+
tmp = (char *) __get_free_page(GFP_KERNEL);
465+
if (!tmp)
466+
return -ENOMEM;
487467

488468
rcu_read_lock();
489469
for_each_process(g) {
470+
struct files_struct *prev_files = NULL;
471+
490472
p = g;
491473
do {
492474
enum lttng_execution_mode mode =
@@ -495,6 +477,7 @@ int lttng_enumerate_process_states(struct lttng_session *session)
495477
LTTNG_UNKNOWN;
496478
enum lttng_process_status status;
497479
enum lttng_thread_type type;
480+
struct files_struct *files;
498481

499482
task_lock(p);
500483
if (p->exit_state == EXIT_ZOMBIE)
@@ -529,16 +512,31 @@ int lttng_enumerate_process_states(struct lttng_session *session)
529512
type = LTTNG_USER_THREAD;
530513
else
531514
type = LTTNG_KERNEL_THREAD;
515+
files = p->files;
532516

533517
trace_lttng_statedump_process_state(session,
534-
p, type, mode, submode, status);
518+
p, type, mode, submode, status, files);
535519
lttng_statedump_process_ns(session,
536520
p, type, mode, submode, status);
521+
/*
522+
* As an optimisation for the common case, do not
523+
* repeat information for the same files_struct in
524+
* two consecutive threads. This is the common case
525+
* for threads sharing the same fd table. RCU guarantees
526+
* that the same files_struct pointer is not re-used
527+
* throughout processes/threads iteration.
528+
*/
529+
if (files && files != prev_files) {
530+
lttng_enumerate_files(session, files, tmp);
531+
prev_files = files;
532+
}
537533
task_unlock(p);
538534
} while_each_thread(g, p);
539535
}
540536
rcu_read_unlock();
541537

538+
free_page((unsigned long) tmp);
539+
542540
return 0;
543541
}
544542

@@ -557,9 +555,6 @@ int do_lttng_statedump(struct lttng_session *session)
557555

558556
trace_lttng_statedump_start(session);
559557
ret = lttng_enumerate_process_states(session);
560-
if (ret)
561-
return ret;
562-
ret = lttng_enumerate_file_descriptors(session);
563558
if (ret)
564559
return ret;
565560
/*

0 commit comments

Comments
 (0)