fs: Improve eventpoll logging to stop indicting timerfd
timerfd doesn't create any wakelocks; eventpoll can, and is creating the wakelocks we see called "[timerfd]". eventpoll creates two kinds of wakelocks: a single top-level lock associated with the eventpoll fd itself, and one additional lock for each fd it is polling that needs such a lock (e.g. those using EPOLLWAKEUP). Current code names the per-fd locks using the undecorated names of the fds' associated files (hence "[timerfd]"), and is naming the top-level lock after the PID of the caller and the name of the file behind the first fd for which a per-fd lock is created. To make things clearer, the top-level lock is now named using the caller PID and an "epollfd" designation, while the per-fd locks are also named with the caller's PID (to associate them with the top-level lock) and their respective fds' file names. Port of fix already applied to previous 2 generations. Note that this set of changes does not fully solve the problem of eventpoll/timerfd wakelock attribution to the original process, since most activity is relayed through system_server, but it does at least ensure that different eventpoll wakelocks - and their stats - are properly disambiguated. Test: Ran on device and observed new wakelock naming in /d/wakeup_sources and (file naming in) lsof output. Bug: 116363986 Change-Id: I34bada5ddab04cf3830762c745f46bfcd1549cb8 Signed-off-by: John Dias <joaodias@google.com> Signed-off-by: Kelly Rossmoyer <krossmo@google.com> Signed-off-by: Miguel de Dios <migueldedios@google.com> Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
This commit is contained in:
@@ -1392,15 +1392,23 @@ static int ep_create_wakeup_source(struct epitem *epi)
|
||||
{
|
||||
struct name_snapshot n;
|
||||
struct wakeup_source *ws;
|
||||
char task_comm_buf[TASK_COMM_LEN];
|
||||
char buf[64];
|
||||
|
||||
get_task_comm(task_comm_buf, current);
|
||||
|
||||
if (!epi->ep->ws) {
|
||||
epi->ep->ws = wakeup_source_register(NULL, "eventpoll");
|
||||
snprintf(buf, sizeof(buf), "epoll_%.*s_epollfd",
|
||||
(int)sizeof(task_comm_buf), task_comm_buf);
|
||||
epi->ep->ws = wakeup_source_register(NULL, buf);
|
||||
if (!epi->ep->ws)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
take_dentry_name_snapshot(&n, epi->ffd.file->f_path.dentry);
|
||||
ws = wakeup_source_register(NULL, n.name);
|
||||
snprintf(buf, sizeof(buf), "epoll_%.*s_file:%s",
|
||||
(int)sizeof(task_comm_buf), task_comm_buf, n.name);
|
||||
ws = wakeup_source_register(NULL, buf);
|
||||
release_dentry_name_snapshot(&n);
|
||||
|
||||
if (!ws)
|
||||
|
||||
12
fs/timerfd.c
12
fs/timerfd.c
@@ -45,6 +45,8 @@ struct timerfd_ctx {
|
||||
bool might_cancel;
|
||||
};
|
||||
|
||||
static atomic_t instance_count = ATOMIC_INIT(0);
|
||||
|
||||
static LIST_HEAD(cancel_list);
|
||||
static DEFINE_SPINLOCK(cancel_lock);
|
||||
|
||||
@@ -388,6 +390,9 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
|
||||
{
|
||||
int ufd;
|
||||
struct timerfd_ctx *ctx;
|
||||
char task_comm_buf[TASK_COMM_LEN];
|
||||
char file_name_buf[32];
|
||||
int instance;
|
||||
|
||||
/* Check the TFD_* constants for consistency. */
|
||||
BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC);
|
||||
@@ -424,7 +429,12 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
|
||||
|
||||
ctx->moffs = ktime_mono_to_real(0);
|
||||
|
||||
ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx,
|
||||
instance = atomic_inc_return(&instance_count);
|
||||
get_task_comm(task_comm_buf, current);
|
||||
snprintf(file_name_buf, sizeof(file_name_buf), "[timerfd%d_%.*s]",
|
||||
instance, (int)sizeof(task_comm_buf), task_comm_buf);
|
||||
|
||||
ufd = anon_inode_getfd(file_name_buf, &timerfd_fops, ctx,
|
||||
O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS));
|
||||
if (ufd < 0)
|
||||
kfree(ctx);
|
||||
|
||||
Reference in New Issue
Block a user