drm_minor structure had a list_head pointer that was used only for render nodes. control and primary nodes do not live in the list and had this list pointer unused. Create a separate drm_render_node structure that is used to build the render node list and that points to the coresponding minor. This avoids having fields that are used only in some cases and also to allows adding render node specific fields that primary and control minor may not care about. Also fix a few minor things: * change the names of functions that create and delete render nodes to more logical ones. * make create_render_node actually populate minor_p pointer passed to it so that the ioctl has some chance of working Signed-off-by: Ilija Hadzic <ihadzic@xxxxxxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/drm_stub.c | 45 +++++++++++++++++++++++++------------------ drivers/gpu/drm/drm_vm.c | 9 ++++--- include/drm/drmP.h | 9 ++++++- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 5ef0e46..c6a0e71 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -269,7 +269,7 @@ int drm_fill_in_dev(struct drm_device *dev, INIT_LIST_HEAD(&dev->vmalist); INIT_LIST_HEAD(&dev->maplist); INIT_LIST_HEAD(&dev->vblank_event_list); - INIT_LIST_HEAD(&dev->render_minor_list); + INIT_LIST_HEAD(&dev->render_node_list); spin_lock_init(&dev->count_lock); spin_lock_init(&dev->event_lock); @@ -356,7 +356,6 @@ int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) new_minor->dev = dev; new_minor->index = minor_id; INIT_LIST_HEAD(&new_minor->master_list); - INIT_LIST_HEAD(&new_minor->render_node_list); idr_replace(&drm_minors_idr, new_minor, minor_id); @@ -400,25 +399,36 @@ err_idr: return ret; } -int drm_create_minor_render(struct drm_device *dev, struct drm_minor **minor_p) +int drm_create_render_node(struct drm_device *dev, struct drm_minor **minor_p) { int ret; struct drm_minor *minor; + struct drm_render_node *render_node; + + render_node = kmalloc(sizeof(struct drm_render_node), GFP_KERNEL); + if (!render_node) + return -ENOMEM; ret = drm_get_minor(dev, &minor, DRM_MINOR_RENDER); - if (ret) + if (ret) { + kfree(render_node); return ret; - - list_add_tail(&minor->render_node_list, &dev->render_minor_list); + } + render_node->minor = minor; + *minor_p = minor; + list_add_tail(&render_node->list, &dev->render_node_list); return 0; } -int drm_destroy_minor_render(struct drm_device *dev) +int drm_destroy_all_render_nodes(struct drm_device *dev) { - struct drm_minor *minor, *tmp; + struct drm_render_node *render_node, *tmp; - list_for_each_entry_safe(minor, tmp, &dev->render_minor_list, render_node_list) { - drm_put_minor(&minor); + list_for_each_entry_safe(render_node, tmp, + &dev->render_node_list, list) { + list_del(&render_node->list); + drm_put_minor(&render_node->minor); + kfree(render_node); } return 0; } @@ -439,8 +449,6 @@ int drm_put_minor(struct drm_minor **minor_p) DRM_DEBUG("release secondary minor %d\n", minor->index); - list_del(&minor->render_node_list); - if (minor->type == DRM_MINOR_LEGACY) drm_proc_cleanup(minor, drm_proc_root); #if defined(CONFIG_DEBUG_FS) @@ -505,8 +513,7 @@ void drm_put_dev(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) { drm_put_minor(&dev->control); - - drm_destroy_minor_render(dev); + drm_destroy_all_render_nodes(dev); } if (driver->driver_features & DRIVER_GEM) @@ -531,7 +538,7 @@ int drm_render_node_create_ioctl(struct drm_device *dev, void *data, struct drm_minor *new_minor; int total_ids, i; uint32_t __user *ids_ptr; - ret = drm_create_minor_render(dev, &new_minor); + ret = drm_create_render_node(dev, &new_minor); if (ret) goto out; @@ -570,11 +577,11 @@ int drm_render_node_remove_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_render_node_remove *args = data; - struct drm_minor *del_minor, *tmp; + struct drm_render_node *del_node, *tmp; - list_for_each_entry_safe(del_minor, tmp, &dev->render_minor_list, render_node_list) { - if (del_minor->index == args->node_minor_id) - drm_put_minor(&del_minor); + list_for_each_entry_safe(del_node, tmp, &dev->render_node_list, list) { + if (del_node->minor->index == args->node_minor_id) + drm_put_minor(&del_node->minor); } return 0; } diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 7cf67dd..73146e3 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c @@ -691,14 +691,15 @@ EXPORT_SYMBOL(drm_mmap); void drm_unmap_mapping(struct drm_device *dev, loff_t const holebegin, loff_t const holelen) { - struct drm_minor *minor; + struct drm_render_node *render_node; + if (dev->primary->dev_mapping) unmap_mapping_range(dev->primary->dev_mapping, holebegin, holelen, 1); - list_for_each_entry(minor, &dev->render_minor_list, render_node_list) { - if (minor->dev_mapping) - unmap_mapping_range(minor->dev_mapping, + list_for_each_entry(render_node, &dev->render_node_list, list) { + if (render_node->minor->dev_mapping) + unmap_mapping_range(render_node->minor->dev_mapping, holebegin, holelen, 1); } } diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 3bc5c71..1131fd4 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -999,8 +999,13 @@ struct drm_minor { struct drm_mode_group mode_group; struct address_space *dev_mapping; +}; - struct list_head render_node_list; + +/* render node descriptor */ +struct drm_render_node { + struct list_head list; + struct drm_minor *minor; }; /* mode specified on the command line */ @@ -1164,7 +1169,7 @@ struct drm_device { unsigned int agp_buffer_token; struct drm_minor *control; /**< Control node for card */ struct drm_minor *primary; /**< render type primary screen head */ - struct list_head render_minor_list; + struct list_head render_node_list; struct drm_mode_config mode_config; /**< Current mode config */ /** \name GEM information */ -- 1.7.8.5 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel