[FIX] Preload: move dentry lookup out of uprobe handler 58/43758/4
authorVasiliy Ulyanov <v.ulyanov@samsung.com>
Mon, 13 Jul 2015 14:40:21 +0000 (17:40 +0300)
committerVasiliy Ulyanov <v.ulyanov@samsung.com>
Mon, 13 Jul 2015 15:45:13 +0000 (18:45 +0300)
It was causing a lot of 'scheduling while in atomic' BUGs (and a
deadlock at the end) which were masked by oops_in_progress (set in
kprobe_trap_handler).

Change-Id: I2f0c5f5f3ca58ba07c785ca2b3f73e3e2d04c32c
Signed-off-by: Vasiliy Ulyanov <v.ulyanov@samsung.com>
preload/preload_module.c
preload/preload_storage.c
preload/preload_storage.h

index ddd9cfa..0e02a08 100644 (file)
@@ -273,19 +273,25 @@ static struct vm_area_struct *__get_linker_vma(struct task_struct *task)
 static struct vm_area_struct *__get_libc_vma(struct task_struct *task)
 {
        struct vm_area_struct *vma = NULL;
-       struct dentry *libc_dentry;
+       struct bin_info *libc_info;
 
-       libc_dentry = get_dentry("/lib/libc.so.6");
+       libc_info = preload_storage_get_libc_info();
+
+       if (!libc_info) {
+               printk(PRELOAD_PREFIX "Cannot get libc info [%u %u %s]!\n",
+                      task->tgid, task->pid, task->comm);
+               return NULL;
+       }
 
        for (vma = task->mm->mmap; vma; vma = vma->vm_next) {
                if (vma->vm_file && vma->vm_flags & VM_EXEC
-                   && vma->vm_file->f_dentry == libc_dentry) {
-                               put_dentry(libc_dentry);
-                               return vma;
+                   && vma->vm_file->f_dentry == libc_info->dentry) {
+                       preload_storage_put_libc_info(libc_info);
+                       return vma;
                }
        }
 
-       put_dentry(libc_dentry);
+       preload_storage_put_libc_info(libc_info);
        return NULL;
 }
 
index c19853b..524232b 100644 (file)
@@ -9,6 +9,7 @@
 
 static struct bin_info __handlers_info = { NULL, NULL };
 static struct bin_info __linker_info = { NULL, NULL };
+static struct bin_info __libc_info;
 
 static inline struct bin_info *__get_handlers_info(void)
 {
@@ -149,17 +150,42 @@ struct bin_info *preload_storage_get_linker_info(void)
        return NULL;
 }
 
+static inline void __drop_libc_info(void)
+{
+       if (__libc_info.dentry)
+               put_dentry(__libc_info.dentry);
+
+       __libc_info.path = NULL;
+       __libc_info.dentry = NULL;
+}
+
 void preload_storage_put_linker_info(struct bin_info *info)
 {
 }
 
+struct bin_info *preload_storage_get_libc_info(void)
+{
+       return &__libc_info;
+}
+
+void preload_storage_put_libc_info(struct bin_info *info)
+{
+}
+
 int preload_storage_init(void)
 {
+       __libc_info.path = "/lib/libc.so.6";
+       __libc_info.dentry = get_dentry(__libc_info.path);
+
+       if (!__libc_info.dentry)
+               return -ENOENT;
+
        return 0;
 }
 
 void preload_storage_exit(void)
 {
+       __drop_libc_info();
        __drop_handlers_info();
        __drop_linker_info();
 }
index 86c7919..faa9ff6 100644 (file)
@@ -15,6 +15,9 @@ int preload_storage_set_linker_info(char *path);
 struct bin_info *preload_storage_get_linker_info(void);
 void preload_storage_put_linker_info(struct bin_info *info);
 
+struct bin_info *preload_storage_get_libc_info(void);
+void preload_storage_put_libc_info(struct bin_info *info);
+
 int preload_storage_init(void);
 void preload_storage_exit(void);