From: Ilija Hadzic <ihadzic@research.bell-labs.com> To: dri-devel@lists.freedesktop.org Subject: [PATCH 18/19] drm: keep track of which node holds which resource Date: Thu, 12 Apr 2012 14:19:43 -0400 [thread overview] Message-ID: <1334254784-3200-19-git-send-email-ihadzic@research.bell-labs.com> (raw) In-Reply-To: <1334254784-3200-1-git-send-email-ihadzic@research.bell-labs.com> Add fields to drm_crtc, drm_encoder, drm_connector, and drm_plane that keep track of which render node owns it. Assign ownership when resource is added and revoke it when resource is destroyed. Do not allow creation of a node that tries to claim resources that are already in use by another node. v2: - track planes too Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com> --- drivers/gpu/drm/drm_crtc.c | 4 ++ drivers/gpu/drm/drm_stub.c | 111 ++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 5 ++ 3 files changed, 120 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index cce3d25..45a2925 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -375,6 +375,7 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, crtc->dev = dev; crtc->funcs = funcs; + crtc->render_node_owner = -1; mutex_lock(&dev->mode_config.mutex); @@ -483,6 +484,7 @@ int drm_connector_init(struct drm_device *dev, connector->dev = dev; connector->funcs = funcs; + connector->render_node_owner = -1; connector->connector_type = connector_type; connector->connector_type_id = ++drm_connector_enum_list[connector_type].count; /* TODO */ @@ -553,6 +555,7 @@ int drm_encoder_init(struct drm_device *dev, if (ret) goto out; + encoder->render_node_owner = -1; encoder->dev = dev; encoder->encoder_type = encoder_type; encoder->funcs = funcs; @@ -594,6 +597,7 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, plane->dev = dev; plane->funcs = funcs; + plane->render_node_owner = -1; plane->format_types = kmalloc(sizeof(uint32_t) * format_count, GFP_KERNEL); if (!plane->format_types) { diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 340a7e4..13ff4c8 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -447,6 +447,95 @@ static int drm_get_render_node_resources(struct drm_device *dev, return 0; } +static int *drm_get_render_node_owner(struct drm_device *dev, + uint32_t id, uint32_t type) +{ + struct drm_mode_object *obj; + struct drm_crtc *crtc; + struct drm_encoder *encoder; + struct drm_connector *connector; + struct drm_plane *plane; + + obj = drm_mode_object_find(dev, id, type); + if (!obj) + return NULL; + switch (type) { + case DRM_MODE_OBJECT_CRTC: + crtc = container_of(obj, struct drm_crtc, base); + return &crtc->render_node_owner; + case DRM_MODE_OBJECT_ENCODER: + encoder = container_of(obj, struct drm_encoder, base); + return &encoder->render_node_owner; + case DRM_MODE_OBJECT_CONNECTOR: + connector = container_of(obj, struct drm_connector, base); + return &connector->render_node_owner; + case DRM_MODE_OBJECT_PLANE: + plane = container_of(obj, struct drm_plane, base); + return &plane->render_node_owner; + + default: + return NULL; + } +} + +static void drm_release_render_node_resources(struct drm_device *dev, + uint32_t *id_list, + int *resource_count, + int minor) +{ + int *render_node_owner; + int s, e, i, j; + + for (e = 0, j = 0; j < DRM_RN_NUM_EXP_TYPES; j++) { + s = e; + e += resource_count[j]; + for (i = s; i < e; i++) { + render_node_owner = + drm_get_render_node_owner(dev, id_list[i], + expected_type_list[j]); + if (render_node_owner && + *render_node_owner == minor) + *render_node_owner = -1; + } + } +} + +static int drm_claim_render_node_resources(struct drm_device *dev, + uint32_t *id_list, + int *resource_count, + int minor) +{ + int *render_node_owner; + int s, e, i, j; + int ret = 0; + + for (e = 0, j = 0; j < DRM_RN_NUM_EXP_TYPES; j++) { + s = e; + e += resource_count[j]; + for (i = s; i < e; i++) { + render_node_owner = + drm_get_render_node_owner(dev, id_list[i], + expected_type_list[j]); + if (!render_node_owner) { + /* list was validated, not supposed to fail */ + WARN_ON(1); + ret = -EFAULT; + goto out_release; + } + if (*render_node_owner != -1) { + ret = -EBUSY; + goto out_release; + } + *render_node_owner = minor; + } + } + return ret; + +out_release: + drm_release_render_node_resources(dev, id_list, resource_count, minor); + return ret; +} + int drm_create_render_node(struct drm_device *dev, struct drm_minor **minor_p) { int ret; @@ -475,10 +564,19 @@ int drm_destroy_render_node(struct drm_device *dev, int index) list_for_each_entry_safe(node, tmp, &dev->render_node_list, list) { if (node->minor->index == index) { struct drm_mode_group *group; + int resource_count[DRM_RN_NUM_EXP_TYPES]; + if (node->minor->open_count) return -EBUSY; group = &node->minor->mode_group; list_del(&node->list); + resource_count[0] = group->num_crtcs; + resource_count[1] = group->num_encoders; + resource_count[2] = group->num_connectors; + resource_count[3] = group->num_planes; + drm_release_render_node_resources(dev, group->id_list, + resource_count, + node->minor->index); drm_put_minor(&node->minor); drm_mode_group_fini(group); kfree(node); @@ -494,8 +592,17 @@ void drm_destroy_all_render_nodes(struct drm_device *dev) list_for_each_entry_safe(node, tmp, &dev->render_node_list, list) { struct drm_mode_group *group; + int resource_count[DRM_RN_NUM_EXP_TYPES]; + group = &node->minor->mode_group; list_del(&node->list); + resource_count[0] = group->num_crtcs; + resource_count[1] = group->num_encoders; + resource_count[2] = group->num_connectors; + resource_count[3] = group->num_planes; + drm_release_render_node_resources(dev, group->id_list, + resource_count, + node->minor->index); drm_put_minor(&node->minor); drm_mode_group_fini(group); kfree(node); @@ -652,6 +759,10 @@ int drm_render_node_create_ioctl(struct drm_device *dev, void *data, resource_count); if (ret) goto out_del; + ret = drm_claim_render_node_resources(dev, id_list, resource_count, + new_minor->index); + if (ret) + goto out_del; new_minor->mode_group.num_crtcs = args->num_crtc; new_minor->mode_group.num_encoders = args->num_encoder; new_minor->mode_group.num_connectors = args->num_connector; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 7c1227b..c38635d 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -374,6 +374,7 @@ struct drm_crtc { struct drm_framebuffer *fb; bool enabled; + int render_node_owner; /* Requested mode from modesetting. */ struct drm_display_mode mode; @@ -479,6 +480,8 @@ struct drm_encoder { uint32_t possible_crtcs; uint32_t possible_clones; + int render_node_owner; + struct drm_crtc *crtc; const struct drm_encoder_funcs *funcs; void *helper_private; @@ -556,6 +559,7 @@ struct drm_connector { struct list_head modes; /* list of modes on this connector */ enum drm_connector_status status; + int render_node_owner; /* these are modes added by probing with DDC or the BIOS */ struct list_head probed_modes; @@ -641,6 +645,7 @@ struct drm_plane { uint16_t *gamma_store; bool enabled; + int render_node_owner; const struct drm_plane_funcs *funcs; void *helper_private; -- 1.7.8.5
next prev parent reply other threads:[~2012-04-12 18:21 UTC|newest] Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top 2012-04-12 18:19 [RFC v2] Revive the work on render-nodes branch Ilija Hadzic 2012-04-12 18:19 ` [PATCH 01/19] drm: simplify dereferencing of node type Ilija Hadzic 2012-04-12 18:19 ` [PATCH 02/19] drm: track planes in drm_mode_group structure Ilija Hadzic 2012-04-12 18:19 ` [PATCH 03/19] drm: use drm_mode_group in drm_mode_getplane_res Ilija Hadzic 2012-04-12 18:19 ` [PATCH 04/19] drm: do not push inode down into drm_open_helper Ilija Hadzic 2012-04-12 18:19 ` [PATCH 05/19] drm: move dev_mapping to the minor node Ilija Hadzic 2012-04-20 10:04 ` Dave Airlie 2012-04-30 14:48 ` Ilija Hadzic 2012-04-30 16:39 ` Dave Airlie 2012-04-30 16:52 ` Ilija Hadzic 2012-04-30 17:53 ` Dave Airlie 2012-04-30 18:04 ` Dave Airlie 2012-05-15 20:48 ` Ilija Hadzic 2012-04-12 18:19 ` [PATCH 06/19] drm: add support for render nodes Ilija Hadzic 2012-04-12 18:19 ` [PATCH 07/19] drm: initial multiple nodes ioctl work Ilija Hadzic 2012-04-20 10:15 ` Dave Airlie 2012-04-12 18:19 ` [PATCH 08/19] drm: separate render node descriptor from minor Ilija Hadzic 2012-04-12 18:19 ` [PATCH 09/19] drm: cleanup render node ioctls Ilija Hadzic 2012-04-12 18:19 ` [PATCH 10/19] drm: only allow render node ioctls through control node Ilija Hadzic 2012-04-12 18:19 ` [PATCH 11/19] drm: do not remove a render node in use Ilija Hadzic 2012-04-12 18:19 ` [PATCH 12/19] drm: allocate correct id_list size for a render node Ilija Hadzic 2012-04-12 18:19 ` [PATCH 13/19] drm: add drm_mode_group_fini function Ilija Hadzic 2012-04-12 18:19 ` [PATCH 14/19] drm: properly free id_list when a render node is removed Ilija Hadzic 2012-04-12 18:19 ` [PATCH 15/19] drm: call drm_mode_group_fini on primary node Ilija Hadzic 2012-04-12 18:19 ` [PATCH 16/19] drm: more elaborate check for resource count Ilija Hadzic 2012-04-12 18:19 ` [PATCH 17/19] drm: validate id list when creating a render node Ilija Hadzic 2012-04-12 18:19 ` Ilija Hadzic [this message] 2012-04-12 18:19 ` [PATCH 19/19] drm: hold mutex in critical sections of render-node code Ilija Hadzic 2012-04-12 18:55 ` [RFC v2] Revive the work on render-nodes branch Ville Syrjälä 2012-04-12 19:09 ` Ilija Hadzic 2012-04-20 10:20 ` Dave Airlie 2012-04-20 13:46 ` Daniel Vetter 2012-04-30 15:16 ` Ilija Hadzic 2012-04-30 19:01 ` Kristian Høgsberg
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1334254784-3200-19-git-send-email-ihadzic@research.bell-labs.com \ --to=ihadzic@research.bell-labs.com \ --cc=dri-devel@lists.freedesktop.org \ --subject='Re: [PATCH 18/19] drm: keep track of which node holds which resource' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.