From 93ee09d508e10d054465c63553b30539d70e0c4b Mon Sep 17 00:00:00 2001 From: David Smith Date: Thu, 27 Oct 2011 10:24:45 -0500 Subject: [PATCH] More PR13083 fixes to avoid sleeping in the task_finder. * runtime/task_finder.c (__stp_get_mm_path): Call down_read_trylock() instead of down_read() to avoid the possibility of sleeping. (stap_start_task_finder): Call task_lock() to make sure a task's mm doesn't go away while we're looking at it. --- runtime/task_finder.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/runtime/task_finder.c b/runtime/task_finder.c index 70d5ba108..2d9ec7fd0 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -436,7 +436,14 @@ __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen) struct vm_area_struct *vma; char *rc = NULL; - down_read(&mm->mmap_sem); + // The down_read() function can sleep, so we'll call + // down_read_trylock() instead, which can fail. If if fails, + // we'll just pretend this task didn't have a path. + if (!mm || ! down_read_trylock(&mm->mmap_sem)) { + *buf = '\0'; + return ERR_PTR(-ENOENT); + } + vma = mm->mmap; while (vma) { if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) @@ -1602,17 +1609,20 @@ stap_start_task_finder(void) // Grab the path associated with this task. // - // Note we *are* calling get_task_mm()/mmput() here. - // We're not in the context of tsk, so we need to make - // sure the mm sticks around (if it exists). - mm = get_task_mm(tsk); - if (! mm) { + // Note we aren't calling get_task_mm()/mmput() here. + // Instead we're calling task_lock()/task_unlock(). + // We really only need to lock the mm, but mmput() can + // sleep so we can't call it. Also note that + // __stp_get_mm_path() grabs the mmap semaphore, which + // should also keep us safe. + task_lock(tsk); + if (! tsk->mm) { /* If the thread doesn't have a mm_struct, it is * a kernel thread which we need to skip. */ continue; } - mmpath = __stp_get_mm_path(mm, mmpath_buf, PATH_MAX); - mmput(mm); /* We're done with mm */ + mmpath = __stp_get_mm_path(tsk->mm, mmpath_buf, PATH_MAX); + task_unlock(tsk); if (mmpath == NULL || IS_ERR(mmpath)) { rc = -PTR_ERR(mmpath); if (rc == ENOENT) { -- 2.43.5