]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blobdiff - drivers/video/tegra/nvmap/nvmap_dev.c
tegra: nvmap: fix the possible dead lock
[sojka/nv-tegra/linux-3.10.git] / drivers / video / tegra / nvmap / nvmap_dev.c
index 717276e4c1a0b2d2db77314784894f75b33a4e17..8799e26bc6205b0e8f81692fe22da7b6287d06d0 100644 (file)
@@ -1319,11 +1319,17 @@ static void nvmap_iovmm_get_client_mss(struct nvmap_client *client, u64 *pss,
                .private = &mss,
        };
        struct mm_struct *mm;
-       bool is_mm_accessed = false;
 
        memset(&mss, 0, sizeof(mss));
        *pss = *total = 0;
 
+       mm = mm_access(client->task,
+                       PTRACE_MODE_READ);
+       if (!mm || IS_ERR(mm)) return;
+
+       down_read(&mm->mmap_sem);
+       procrank_walk.mm = mm;
+
        nvmap_ref_lock(client);
        n = rb_first(&client->handle_refs);
        for (; n != NULL; n = rb_next(n)) {
@@ -1337,20 +1343,6 @@ static void nvmap_iovmm_get_client_mss(struct nvmap_client *client, u64 *pss,
                mutex_lock(&h->lock);
                list_for_each_entry(tmp, &h->vmas, list) {
                        if (client->task->pid == tmp->pid) {
-
-                               if (!is_mm_accessed) {
-                                       is_mm_accessed = true;
-                                       mm = mm_access(client->task,
-                                                       PTRACE_MODE_READ);
-                                       if (!mm || IS_ERR(mm)) {
-                                               mutex_unlock(&h->lock);
-                                               nvmap_ref_unlock(client);
-                                               return;
-                                       }
-                                       down_read(&mm->mmap_sem);
-                                       procrank_walk.mm = tmp->vma->vm_mm;
-                               }
-
                                mss.vma = tmp->vma;
                                walk_page_range(tmp->vma->vm_start,
                                                tmp->vma->vm_end,
@@ -1358,15 +1350,12 @@ static void nvmap_iovmm_get_client_mss(struct nvmap_client *client, u64 *pss,
                        }
                }
                mutex_unlock(&h->lock);
-
                *total += h->size / atomic_read(&h->share_count);
        }
 
-       if (is_mm_accessed) {
-               up_read(&mm->mmap_sem);
-               mmput(mm);
-               *pss = (mss.pss >> PSS_SHIFT);
-       }
+       up_read(&mm->mmap_sem);
+       mmput(mm);
+       *pss = (mss.pss >> PSS_SHIFT);
        nvmap_ref_unlock(client);
 }