Loading drivers/gpu/drm/msm/msm_drv.h +1 −0 Original line number Diff line number Diff line Loading @@ -437,6 +437,7 @@ struct msm_gem_address_space * msm_gem_smmu_address_space_create(struct device *dev, struct msm_mmu *mmu, const char *name); void msm_gem_submit_free(struct msm_gem_submit *submit); int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file); Loading drivers/gpu/drm/msm/msm_gem.c +9 −1 Original line number Diff line number Diff line Loading @@ -653,7 +653,15 @@ void *msm_gem_vaddr(struct drm_gem_object *obj) struct msm_gem_object *msm_obj = to_msm_bo(obj); mutex_lock(&msm_obj->lock); if (!msm_obj->vaddr) { if (msm_obj->vaddr) { mutex_unlock(&msm_obj->lock); return msm_obj->vaddr; } if (obj->import_attach) { msm_obj->vaddr = dma_buf_vmap(obj->import_attach->dmabuf); } else { struct page **pages = get_pages(obj); if (IS_ERR(pages)) { mutex_unlock(&msm_obj->lock); Loading drivers/gpu/drm/msm/msm_gem_submit.c +20 −2 Original line number Diff line number Diff line Loading @@ -59,6 +59,11 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, submit->secure = false; /* * Initalize node so we can safely list_del() on it if * we fail in the submit path */ INIT_LIST_HEAD(&submit->node); INIT_LIST_HEAD(&submit->bo_list); ww_acquire_init(&submit->ticket, &reservation_ww_class); } Loading @@ -74,6 +79,15 @@ copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) return -EFAULT; } void msm_gem_submit_free(struct msm_gem_submit *submit) { if (!submit) return; list_del(&submit->node); kfree(submit); } static int submit_lookup_objects(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct drm_msm_gem_submit *args, struct drm_file *file) Loading Loading @@ -381,6 +395,9 @@ static void submit_cleanup(struct msm_gpu *gpu, struct msm_gem_submit *submit, { unsigned i; if (!submit) return; for (i = 0; i < submit->nr_bos; i++) { struct msm_gem_object *msm_obj = submit->bos[i].obj; submit_unlock_unpin_bo(gpu, submit, i); Loading Loading @@ -510,8 +527,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, args->fence = submit->fence; out: if (submit) submit_cleanup(gpu, submit, !!ret); if (ret) msm_gem_submit_free(submit); mutex_unlock(&dev->struct_mutex); return ret; } drivers/gpu/drm/msm/msm_gpu.c +1 −2 Original line number Diff line number Diff line Loading @@ -479,8 +479,7 @@ static void retire_submits(struct msm_gpu *gpu, uint32_t fence) list_for_each_entry_safe(submit, tmp, &gpu->submit_list, node) { if (COMPARE_FENCE_LTE(submit->fence, fence)) { list_del(&submit->node); kfree(submit); msm_gem_submit_free(submit); } } } Loading drivers/gpu/drm/msm/msm_rd.c +48 −13 Original line number Diff line number Diff line Loading @@ -27,6 +27,11 @@ * This bypasses drm_debugfs_create_files() mainly because we need to use * our own fops for a bit more control. In particular, we don't want to * do anything if userspace doesn't have the debugfs file open. * * The module-param "rd_full", which defaults to false, enables snapshotting * all (non-written) buffers in the submit, rather than just cmdstream bo's. * This is useful to capture the contents of (for example) vbo's or textures, * or shader programs (if not emitted inline in cmdstream). */ #ifdef CONFIG_DEBUG_FS Loading @@ -40,6 +45,10 @@ #include "msm_gpu.h" #include "msm_gem.h" static bool rd_full = false; MODULE_PARM_DESC(rd_full, "If true, $debugfs/.../rd will snapshot all buffer contents"); module_param_named(rd_full, rd_full, bool, 0600); enum rd_sect_type { RD_NONE, RD_TEST, /* ascii text */ Loading Loading @@ -277,6 +286,36 @@ void msm_rd_debugfs_cleanup(struct drm_minor *minor) kfree(rd); } static void snapshot_buf(struct msm_rd_state *rd, struct msm_gem_submit *submit, int idx, uint64_t iova, uint32_t size) { struct msm_gem_object *obj = submit->bos[idx].obj; uint64_t offset = 0; if (iova) { offset = iova - submit->bos[idx].iova; } else { iova = submit->bos[idx].iova; size = obj->base.size; } /* Always write the RD_GPUADDR so we know how big the buffer is */ rd_write_section(rd, RD_GPUADDR, (uint64_t[2]) { iova, size }, 16); /* But only dump contents for buffers marked as read and not secure */ if (submit->bos[idx].flags & MSM_SUBMIT_BO_READ && !(obj->flags & MSM_BO_SECURE)) { const char *buf = msm_gem_vaddr(&obj->base); if (IS_ERR_OR_NULL(buf)) return; rd_write_section(rd, RD_BUFFER_CONTENTS, buf + offset, size); } } /* called under struct_mutex */ void msm_rd_dump_submit(struct msm_gem_submit *submit) { Loading @@ -300,24 +339,20 @@ void msm_rd_dump_submit(struct msm_gem_submit *submit) rd_write_section(rd, RD_CMD, msg, ALIGN(n, 4)); /* could be nice to have an option (module-param?) to snapshot * all the bo's associated with the submit. Handy to see vtx * buffers, etc. For now just the cmdstream bo's is enough. */ if (rd_full) { for (i = 0; i < submit->nr_bos; i++) snapshot_buf(rd, submit, i, 0, 0); } for (i = 0; i < submit->nr_cmds; i++) { uint32_t idx = submit->cmd[i].idx; uint64_t iova = submit->cmd[i].iova; uint32_t szd = submit->cmd[i].size; /* in dwords */ struct msm_gem_object *obj = submit->bos[idx].obj; const char *buf = msm_gem_vaddr(&obj->base); buf += iova - submit->bos[idx].iova; rd_write_section(rd, RD_GPUADDR, (uint64_t[2]) { iova, szd * 4 }, 16); rd_write_section(rd, RD_BUFFER_CONTENTS, buf, szd * 4); /* snapshot cmdstream bo's (if we haven't already): */ if (!rd_full) { snapshot_buf(rd, submit, submit->cmd[i].idx, submit->cmd[i].iova, szd * 4); } switch (submit->cmd[i].type) { case MSM_SUBMIT_CMD_IB_TARGET_BUF: Loading Loading
drivers/gpu/drm/msm/msm_drv.h +1 −0 Original line number Diff line number Diff line Loading @@ -437,6 +437,7 @@ struct msm_gem_address_space * msm_gem_smmu_address_space_create(struct device *dev, struct msm_mmu *mmu, const char *name); void msm_gem_submit_free(struct msm_gem_submit *submit); int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file); Loading
drivers/gpu/drm/msm/msm_gem.c +9 −1 Original line number Diff line number Diff line Loading @@ -653,7 +653,15 @@ void *msm_gem_vaddr(struct drm_gem_object *obj) struct msm_gem_object *msm_obj = to_msm_bo(obj); mutex_lock(&msm_obj->lock); if (!msm_obj->vaddr) { if (msm_obj->vaddr) { mutex_unlock(&msm_obj->lock); return msm_obj->vaddr; } if (obj->import_attach) { msm_obj->vaddr = dma_buf_vmap(obj->import_attach->dmabuf); } else { struct page **pages = get_pages(obj); if (IS_ERR(pages)) { mutex_unlock(&msm_obj->lock); Loading
drivers/gpu/drm/msm/msm_gem_submit.c +20 −2 Original line number Diff line number Diff line Loading @@ -59,6 +59,11 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, submit->secure = false; /* * Initalize node so we can safely list_del() on it if * we fail in the submit path */ INIT_LIST_HEAD(&submit->node); INIT_LIST_HEAD(&submit->bo_list); ww_acquire_init(&submit->ticket, &reservation_ww_class); } Loading @@ -74,6 +79,15 @@ copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) return -EFAULT; } void msm_gem_submit_free(struct msm_gem_submit *submit) { if (!submit) return; list_del(&submit->node); kfree(submit); } static int submit_lookup_objects(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct drm_msm_gem_submit *args, struct drm_file *file) Loading Loading @@ -381,6 +395,9 @@ static void submit_cleanup(struct msm_gpu *gpu, struct msm_gem_submit *submit, { unsigned i; if (!submit) return; for (i = 0; i < submit->nr_bos; i++) { struct msm_gem_object *msm_obj = submit->bos[i].obj; submit_unlock_unpin_bo(gpu, submit, i); Loading Loading @@ -510,8 +527,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, args->fence = submit->fence; out: if (submit) submit_cleanup(gpu, submit, !!ret); if (ret) msm_gem_submit_free(submit); mutex_unlock(&dev->struct_mutex); return ret; }
drivers/gpu/drm/msm/msm_gpu.c +1 −2 Original line number Diff line number Diff line Loading @@ -479,8 +479,7 @@ static void retire_submits(struct msm_gpu *gpu, uint32_t fence) list_for_each_entry_safe(submit, tmp, &gpu->submit_list, node) { if (COMPARE_FENCE_LTE(submit->fence, fence)) { list_del(&submit->node); kfree(submit); msm_gem_submit_free(submit); } } } Loading
drivers/gpu/drm/msm/msm_rd.c +48 −13 Original line number Diff line number Diff line Loading @@ -27,6 +27,11 @@ * This bypasses drm_debugfs_create_files() mainly because we need to use * our own fops for a bit more control. In particular, we don't want to * do anything if userspace doesn't have the debugfs file open. * * The module-param "rd_full", which defaults to false, enables snapshotting * all (non-written) buffers in the submit, rather than just cmdstream bo's. * This is useful to capture the contents of (for example) vbo's or textures, * or shader programs (if not emitted inline in cmdstream). */ #ifdef CONFIG_DEBUG_FS Loading @@ -40,6 +45,10 @@ #include "msm_gpu.h" #include "msm_gem.h" static bool rd_full = false; MODULE_PARM_DESC(rd_full, "If true, $debugfs/.../rd will snapshot all buffer contents"); module_param_named(rd_full, rd_full, bool, 0600); enum rd_sect_type { RD_NONE, RD_TEST, /* ascii text */ Loading Loading @@ -277,6 +286,36 @@ void msm_rd_debugfs_cleanup(struct drm_minor *minor) kfree(rd); } static void snapshot_buf(struct msm_rd_state *rd, struct msm_gem_submit *submit, int idx, uint64_t iova, uint32_t size) { struct msm_gem_object *obj = submit->bos[idx].obj; uint64_t offset = 0; if (iova) { offset = iova - submit->bos[idx].iova; } else { iova = submit->bos[idx].iova; size = obj->base.size; } /* Always write the RD_GPUADDR so we know how big the buffer is */ rd_write_section(rd, RD_GPUADDR, (uint64_t[2]) { iova, size }, 16); /* But only dump contents for buffers marked as read and not secure */ if (submit->bos[idx].flags & MSM_SUBMIT_BO_READ && !(obj->flags & MSM_BO_SECURE)) { const char *buf = msm_gem_vaddr(&obj->base); if (IS_ERR_OR_NULL(buf)) return; rd_write_section(rd, RD_BUFFER_CONTENTS, buf + offset, size); } } /* called under struct_mutex */ void msm_rd_dump_submit(struct msm_gem_submit *submit) { Loading @@ -300,24 +339,20 @@ void msm_rd_dump_submit(struct msm_gem_submit *submit) rd_write_section(rd, RD_CMD, msg, ALIGN(n, 4)); /* could be nice to have an option (module-param?) to snapshot * all the bo's associated with the submit. Handy to see vtx * buffers, etc. For now just the cmdstream bo's is enough. */ if (rd_full) { for (i = 0; i < submit->nr_bos; i++) snapshot_buf(rd, submit, i, 0, 0); } for (i = 0; i < submit->nr_cmds; i++) { uint32_t idx = submit->cmd[i].idx; uint64_t iova = submit->cmd[i].iova; uint32_t szd = submit->cmd[i].size; /* in dwords */ struct msm_gem_object *obj = submit->bos[idx].obj; const char *buf = msm_gem_vaddr(&obj->base); buf += iova - submit->bos[idx].iova; rd_write_section(rd, RD_GPUADDR, (uint64_t[2]) { iova, szd * 4 }, 16); rd_write_section(rd, RD_BUFFER_CONTENTS, buf, szd * 4); /* snapshot cmdstream bo's (if we haven't already): */ if (!rd_full) { snapshot_buf(rd, submit, submit->cmd[i].idx, submit->cmd[i].iova, szd * 4); } switch (submit->cmd[i].type) { case MSM_SUBMIT_CMD_IB_TARGET_BUF: Loading