if (flags & KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM)
                        size >>= 1;
-               WRITE_ONCE(pdd->vram_usage, pdd->vram_usage + PAGE_ALIGN(size));
+               atomic64_add(PAGE_ALIGN(size), &pdd->vram_usage);
        }
 
        mutex_unlock(&p->mutex);
                kfd_process_device_remove_obj_handle(
                        pdd, GET_IDR_HANDLE(args->handle));
 
-       WRITE_ONCE(pdd->vram_usage, pdd->vram_usage - size);
+       atomic64_sub(size, &pdd->vram_usage);
 
 err_unlock:
 err_pdd:
        } else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
                bo_bucket->restored_offset = offset;
                /* Update the VRAM usage count */
-               WRITE_ONCE(pdd->vram_usage, pdd->vram_usage + bo_bucket->size);
+               atomic64_add(bo_bucket->size, &pdd->vram_usage);
        }
        return 0;
 }
 
        enum kfd_pdd_bound bound;
 
        /* VRAM usage */
-       uint64_t vram_usage;
+       atomic64_t vram_usage;
        struct attribute attr_vram;
        char vram_filename[MAX_SYSFS_FILENAME_LEN];
 
 
        } else if (strncmp(attr->name, "vram_", 5) == 0) {
                struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device,
                                                              attr_vram);
-               return snprintf(buffer, PAGE_SIZE, "%llu\n", READ_ONCE(pdd->vram_usage));
+               return snprintf(buffer, PAGE_SIZE, "%llu\n", atomic64_read(&pdd->vram_usage));
        } else if (strncmp(attr->name, "sdma_", 5) == 0) {
                struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device,
                                                              attr_sdma);
        pdd->bound = PDD_UNBOUND;
        pdd->already_dequeued = false;
        pdd->runtime_inuse = false;
-       pdd->vram_usage = 0;
+       atomic64_set(&pdd->vram_usage, 0);
        pdd->sdma_past_activity_counter = 0;
        pdd->user_gpu_id = dev->id;
        atomic64_set(&pdd->evict_duration_counter, 0);
 
                spin_lock(&svm_bo->list_lock);
        }
        spin_unlock(&svm_bo->list_lock);
+
+       if (mmget_not_zero(svm_bo->eviction_fence->mm)) {
+               struct kfd_process_device *pdd;
+               struct kfd_process *p;
+               struct mm_struct *mm;
+
+               mm = svm_bo->eviction_fence->mm;
+               /*
+                * The forked child process takes svm_bo device pages ref, svm_bo could be
+                * released after parent process is gone.
+                */
+               p = kfd_lookup_process_by_mm(mm);
+               if (p) {
+                       pdd = kfd_get_process_device_data(svm_bo->node, p);
+                       if (pdd)
+                               atomic64_sub(amdgpu_bo_size(svm_bo->bo), &pdd->vram_usage);
+                       kfd_unref_process(p);
+               }
+               mmput(mm);
+       }
+
        if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base))
                /* We're not in the eviction worker. Signal the fence. */
                dma_fence_signal(&svm_bo->eviction_fence->base);
 svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
                        bool clear)
 {
+       struct kfd_process_device *pdd;
        struct amdgpu_bo_param bp;
        struct svm_range_bo *svm_bo;
        struct amdgpu_bo_user *ubo;
        list_add(&prange->svm_bo_list, &svm_bo->range_list);
        spin_unlock(&svm_bo->list_lock);
 
+       pdd = svm_range_get_pdd_by_node(prange, node);
+       if (pdd)
+               atomic64_add(amdgpu_bo_size(bo), &pdd->vram_usage);
+
        return 0;
 
 reserve_bo_failed: