Commit bf215eab authored by Yixuan Cao's avatar Yixuan Cao Committed by Linus Torvalds

mm/page_owner.c: record tgid

In a single-threaded process, the pid in kernel task_struct is the same
as the tgid, which can mark the process of page allocation.  But in a
multithreaded process, only the task_struct of the thread leader has the
same pid as tgid, and the pids of other threads are different from tgid.
Therefore, tgid is recorded to provide effective information for
debugging and data statistics of multithreaded programs.

This can also be achieved by observing the task name (executable file
name) for a specific process.  However, when the same program is started
multiple times, the task name is the same and the tgid is different.
Therefore, in the debugging of multi-threaded programs, combined with
the task name and tgid, more accurate runtime information of a certain
run of the program can be obtained.

Link: https://lkml.kernel.org/r/20220219180450.2399-1-caoyixuan2019@email.szu.edu.cnSigned-off-by: default avatarYixuan Cao <caoyixuan2019@email.szu.edu.cn>
Cc: Waiman Long <longman@redhat.com>
Cc: Rafael Aquini <aquini@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 865ed6a3
...@@ -31,6 +31,7 @@ struct page_owner { ...@@ -31,6 +31,7 @@ struct page_owner {
u64 free_ts_nsec; u64 free_ts_nsec;
char comm[TASK_COMM_LEN]; char comm[TASK_COMM_LEN];
pid_t pid; pid_t pid;
pid_t tgid;
}; };
static bool page_owner_enabled = false; static bool page_owner_enabled = false;
...@@ -165,6 +166,7 @@ static inline void __set_page_owner_handle(struct page_ext *page_ext, ...@@ -165,6 +166,7 @@ static inline void __set_page_owner_handle(struct page_ext *page_ext,
page_owner->gfp_mask = gfp_mask; page_owner->gfp_mask = gfp_mask;
page_owner->last_migrate_reason = -1; page_owner->last_migrate_reason = -1;
page_owner->pid = current->pid; page_owner->pid = current->pid;
page_owner->tgid = current->tgid;
page_owner->ts_nsec = local_clock(); page_owner->ts_nsec = local_clock();
strlcpy(page_owner->comm, current->comm, strlcpy(page_owner->comm, current->comm,
sizeof(page_owner->comm)); sizeof(page_owner->comm));
...@@ -233,6 +235,7 @@ void __folio_copy_owner(struct folio *newfolio, struct folio *old) ...@@ -233,6 +235,7 @@ void __folio_copy_owner(struct folio *newfolio, struct folio *old)
old_page_owner->last_migrate_reason; old_page_owner->last_migrate_reason;
new_page_owner->handle = old_page_owner->handle; new_page_owner->handle = old_page_owner->handle;
new_page_owner->pid = old_page_owner->pid; new_page_owner->pid = old_page_owner->pid;
new_page_owner->tgid = old_page_owner->tgid;
new_page_owner->ts_nsec = old_page_owner->ts_nsec; new_page_owner->ts_nsec = old_page_owner->ts_nsec;
new_page_owner->free_ts_nsec = old_page_owner->ts_nsec; new_page_owner->free_ts_nsec = old_page_owner->ts_nsec;
strcpy(new_page_owner->comm, old_page_owner->comm); strcpy(new_page_owner->comm, old_page_owner->comm);
...@@ -383,11 +386,11 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn, ...@@ -383,11 +386,11 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,
return -ENOMEM; return -ENOMEM;
ret = scnprintf(kbuf, count, ret = scnprintf(kbuf, count,
"Page allocated via order %u, mask %#x(%pGg), pid %d (%s), ts %llu ns, free_ts %llu ns\n", "Page allocated via order %u, mask %#x(%pGg), pid %d, tgid %d (%s), ts %llu ns, free_ts %llu ns\n",
page_owner->order, page_owner->gfp_mask, page_owner->order, page_owner->gfp_mask,
&page_owner->gfp_mask, page_owner->pid, &page_owner->gfp_mask, page_owner->pid,
page_owner->comm, page_owner->ts_nsec, page_owner->tgid, page_owner->comm,
page_owner->free_ts_nsec); page_owner->ts_nsec, page_owner->free_ts_nsec);
/* Print information relevant to grouping pages by mobility */ /* Print information relevant to grouping pages by mobility */
pageblock_mt = get_pageblock_migratetype(page); pageblock_mt = get_pageblock_migratetype(page);
...@@ -454,10 +457,10 @@ void __dump_page_owner(const struct page *page) ...@@ -454,10 +457,10 @@ void __dump_page_owner(const struct page *page)
else else
pr_alert("page_owner tracks the page as freed\n"); pr_alert("page_owner tracks the page as freed\n");
pr_alert("page last allocated via order %u, migratetype %s, gfp_mask %#x(%pGg), pid %d (%s), ts %llu, free_ts %llu\n", pr_alert("page last allocated via order %u, migratetype %s, gfp_mask %#x(%pGg), pid %d, tgid %d (%s), ts %llu, free_ts %llu\n",
page_owner->order, migratetype_names[mt], gfp_mask, &gfp_mask, page_owner->order, migratetype_names[mt], gfp_mask, &gfp_mask,
page_owner->pid, page_owner->comm, page_owner->ts_nsec, page_owner->pid, page_owner->tgid, page_owner->comm,
page_owner->free_ts_nsec); page_owner->ts_nsec, page_owner->free_ts_nsec);
handle = READ_ONCE(page_owner->handle); handle = READ_ONCE(page_owner->handle);
if (!handle) if (!handle)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment