From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ilija Hadzic Subject: [PATCH 15/16] drm: keep track of which node holds which resource Date: Thu, 29 Mar 2012 12:41:37 -0400 Message-ID: <1333039298-2520-16-git-send-email-ihadzic@research.bell-labs.com> References: <1333039298-2520-1-git-send-email-ihadzic@research.bell-labs.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from ihemail2.lucent.com (ihemail2.lucent.com [135.245.0.35]) by gabe.freedesktop.org (Postfix) with ESMTP id 139919F4FC for ; Thu, 29 Mar 2012 09:42:18 -0700 (PDT) Received: from usnavsmail4.ndc.alcatel-lucent.com (usnavsmail4.ndc.alcatel-lucent.com [135.3.39.12]) by ihemail2.lucent.com (8.13.8/IER-o) with ESMTP id q2TGg9Ys000737 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 29 Mar 2012 11:42:09 -0500 (CDT) Received: from umail.lucent.com (umail-ce2.ndc.lucent.com [135.3.40.63]) by usnavsmail4.ndc.alcatel-lucent.com (8.14.3/8.14.3/GMO) with ESMTP id q2TGg9di006369 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Thu, 29 Mar 2012 11:42:09 -0500 In-Reply-To: <1333039298-2520-1-git-send-email-ihadzic@research.bell-labs.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org Errors-To: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org To: dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org Add fields to drm_crtc, drm_encoder and drm_connector 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. Signed-off-by: Ilija Hadzic --- drivers/gpu/drm/drm_crtc.c | 3 + drivers/gpu/drm/drm_stub.c | 104 ++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 4 ++ 3 files changed, 111 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 9af822b..199ef94 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; diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 5b6459f..b025ad8 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -446,6 +446,90 @@ 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; + + 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; + 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; @@ -474,10 +558,18 @@ 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; + 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); @@ -493,8 +585,16 @@ 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; + 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); @@ -649,6 +749,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 86f4d9a..d4e6a8e 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; -- 1.7.8.5