drm/tgm: tdm_pp: fix possible deadlock with ppdrv->cmd_lock 21/176921/1
authorSeung-Woo Kim <sw0312.kim@samsung.com>
Tue, 24 Apr 2018 07:02:17 +0000 (16:02 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Tue, 24 Apr 2018 07:29:47 +0000 (16:29 +0900)
When releasing tgm drm driver, there can be deadlock for
ppdrv->cmd_lock during call path of pp_put_mem_node()
because pp_find_drv_by_handle() has also ppdrv->cmd_lock.
Fix the possible deadlock with ppdrv->cmd_lock by storing ppdrv
in m_node.

Change-Id: Ibb94b4cca818d94ee02e672e8547c1a831388322
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/tgm/tdm_pp.c

index 92bdac475fa7435ab5ba28341d715438e21c8a59..2b17d97de61b70b86395a8b82e761fc4a41600c4 100644 (file)
@@ -55,7 +55,7 @@ struct tdm_pp_send_event {
  * @prop_id: id of property.
  * @buf_id: id of buffer.
  * @buf_info: gem objects and dma address, size.
- * @filp: a pointer to drm_file.
+ * @ppdrv: ppdrv for the memory.
  */
 struct tdm_pp_mem_node {
        struct list_head        list;
@@ -66,6 +66,7 @@ struct tdm_pp_mem_node {
 #ifdef CONFIG_DRM_DMA_SYNC
        struct fence *fence;
 #endif
+       struct tdm_ppdrv *ppdrv;
 };
 
 /*
@@ -559,7 +560,6 @@ static int pp_put_mem_node(struct drm_device *drm_dev,
                struct tdm_pp_cmd_node *c_node,
                struct tdm_pp_mem_node *m_node)
 {
-       struct tdm_ppdrv *ppdrv;
        int i;
 
        DRM_DEBUG_KMS("node[%p]\n", m_node);
@@ -569,12 +569,6 @@ static int pp_put_mem_node(struct drm_device *drm_dev,
                return -EFAULT;
        }
 
-       ppdrv = pp_find_drv_by_handle(m_node->prop_id);
-       if (IS_ERR(ppdrv)) {
-               DRM_ERROR("failed to get pp driver.\n");
-               return -EFAULT;
-       }
-
        DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id);
 
 #ifdef CONFIG_DRM_DMA_SYNC
@@ -589,7 +583,7 @@ static int pp_put_mem_node(struct drm_device *drm_dev,
                unsigned long handle = m_node->buf_info.handles[i];
 
                if (handle)
-                       tbm_gem_put_dma_addr(drm_dev, ppdrv->dev,
+                       tbm_gem_put_dma_addr(drm_dev, m_node->ppdrv->dev,
                                handle, c_node->filp);
        }
 
@@ -626,6 +620,7 @@ static struct tdm_pp_mem_node
        m_node->ops_id = qbuf->ops_id;
        m_node->prop_id = qbuf->prop_id;
        m_node->buf_id = qbuf->buf_id;
+       m_node->ppdrv = ppdrv;
        INIT_LIST_HEAD(&m_node->list);
 
        DRM_DEBUG_KMS("m_node[%p]ops_id[%d]\n", m_node, qbuf->ops_id);