From patchwork Sun Dec 11 19:20:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 9469855 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6DF8960231 for ; Sun, 11 Dec 2016 19:20:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5EBA027F85 for ; Sun, 11 Dec 2016 19:20:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 521EA280D0; Sun, 11 Dec 2016 19:20:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A171327F85 for ; Sun, 11 Dec 2016 19:20:24 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D97A06E137; Sun, 11 Dec 2016 19:20:16 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x244.google.com (mail-wm0-x244.google.com [IPv6:2a00:1450:400c:c09::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5DB6E6E13B for ; Sun, 11 Dec 2016 19:20:15 +0000 (UTC) Received: by mail-wm0-x244.google.com with SMTP id u144so6599957wmu.0 for ; Sun, 11 Dec 2016 11:20:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=8AU8Rukm+5uehqIgtB71Bar2X+Mkc8hZ4SS6Z8HuDt4=; b=U6AblxXamItLZ47z9VkX3MjAonBOcmgKlR1hpmxv1OLIJrm1zR/5mDndE7gXJv16bo xlC5jEu3Sv3oT690sXXadz33Zl7Evx/6zJIQ6x9VNE8QeE+hBuOTjvILsr+yoYConVdj ZeuEA+rTxryBWi2bhP3RcJs2UwizwpipMMth4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8AU8Rukm+5uehqIgtB71Bar2X+Mkc8hZ4SS6Z8HuDt4=; b=WSj9hL/EiauJ0zkHf7Whils6zwMiSZWJ/whtHf0/AKXvwn6H5OyiHpzLGoEnqpbgQ7 bdJeHjkeBY9UI5PaQ3kIc9Tzakl0DDGysYUJtC8WhkK72FQh8EoiJDoAa2d1ROfsVGIp 50MqgF3rraRgEuK47p8cP4Ji0xOJwj81mt3wLCqpXy5P1cK1kdnshmAupwmOJ5GF0NjW Ugk7C+LZbNjwdxQeGId157mwkcNVoit8rnjHW8cCGFtTlgaec0adcS/+M+DXn945xG8B 9FOSDM95/MeSimSFtrB/htv5uzwDNZoyjuHXh/e5FVQ8HoUGWPfj8/Gt6IdKfNju9o8K 835A== X-Gm-Message-State: AKaTC01fGNqdT5o+Tyn8BnWRSjzRcjwJtC/E/g9RL6pw5H9CmMKYszhvrXf3OyMapx9ATw== X-Received: by 10.28.149.135 with SMTP id x129mr6941246wmd.71.1481484013613; Sun, 11 Dec 2016 11:20:13 -0800 (PST) Received: from phenom.ffwll.local ([2a02:168:56b5:0:ac27:b86c:7764:9429]) by smtp.gmail.com with ESMTPSA id ia7sm53401739wjb.23.2016.12.11.11.20.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 11 Dec 2016 11:20:12 -0800 (PST) From: Daniel Vetter To: DRI Development Subject: [PATCH] drm: Simplify GETRESOURCES ioctl Date: Sun, 11 Dec 2016 20:20:19 +0100 Message-Id: <20161211192019.29603-1-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20161211123915.9699-1-daniel.vetter@ffwll.ch> References: <20161211123915.9699-1-daniel.vetter@ffwll.ch> Cc: Daniel Vetter , Daniel Vetter , Intel Graphics Development X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Looping twice when we can do it once is silly. Also use a consistent style. Note that there's a good race with the connector list walking, since that is no longer protected by mode_config.mutex. But that's for a later patch to fix. v2: Actually try to not blow up, somehow I lost the hunk that checks we don't copy too much. Noticed by Chris. v3: - squash all drm_mode_getresources cleanups into one - use consistent style for walking objects (Chris) v4: - Use u64_to_user_ptr (Chris) - Don't forget to copy the last connector (Chris) v5: Chris was right ... Cc: Chris Wilson Signed-off-by: Daniel Vetter Reviewed-by: Chris Wilson --- drivers/gpu/drm/drm_mode_config.c | 111 ++++++++++++++------------------------ 1 file changed, 39 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 2735a5847ffa..b1e8bbceaf39 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -84,17 +84,11 @@ int drm_mode_getresources(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_mode_card_res *card_res = data; - struct list_head *lh; struct drm_framebuffer *fb; struct drm_connector *connector; struct drm_crtc *crtc; struct drm_encoder *encoder; - int ret = 0; - int connector_count = 0; - int crtc_count = 0; - int fb_count = 0; - int encoder_count = 0; - int copied = 0; + int count, ret = 0; uint32_t __user *fb_id; uint32_t __user *crtc_id; uint32_t __user *connector_id; @@ -105,89 +99,62 @@ int drm_mode_getresources(struct drm_device *dev, void *data, mutex_lock(&file_priv->fbs_lock); - /* - * For the non-control nodes we need to limit the list of resources - * by IDs in the group list for this node - */ - list_for_each(lh, &file_priv->fbs) - fb_count++; - - /* handle this in 4 parts */ - /* FBs */ - if (card_res->count_fbs >= fb_count) { - copied = 0; - fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr; - list_for_each_entry(fb, &file_priv->fbs, filp_head) { - if (put_user(fb->base.id, fb_id + copied)) { - mutex_unlock(&file_priv->fbs_lock); - return -EFAULT; - } - copied++; + count = 0; + fb_id = u64_to_user_ptr(card_res->fb_id_ptr); + list_for_each_entry(fb, &file_priv->fbs, filp_head) { + if (count < card_res->count_fbs && + put_user(fb->base.id, fb_id + count)) { + mutex_unlock(&file_priv->fbs_lock); + return -EFAULT; } + count++; } - card_res->count_fbs = fb_count; + card_res->count_fbs = count; mutex_unlock(&file_priv->fbs_lock); /* mode_config.mutex protects the connector list against e.g. DP MST * connector hot-adding. CRTC/Plane lists are invariant. */ mutex_lock(&dev->mode_config.mutex); - drm_for_each_crtc(crtc, dev) - crtc_count++; - - drm_for_each_connector(connector, dev) - connector_count++; - - drm_for_each_encoder(encoder, dev) - encoder_count++; - card_res->max_height = dev->mode_config.max_height; card_res->min_height = dev->mode_config.min_height; card_res->max_width = dev->mode_config.max_width; card_res->min_width = dev->mode_config.min_width; - /* CRTCs */ - if (card_res->count_crtcs >= crtc_count) { - copied = 0; - crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr; - drm_for_each_crtc(crtc, dev) { - if (put_user(crtc->base.id, crtc_id + copied)) { - ret = -EFAULT; - goto out; - } - copied++; + count = 0; + crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr); + drm_for_each_crtc(crtc, dev) { + if (count < card_res->count_crtcs && + put_user(crtc->base.id, crtc_id + count)) { + ret = -EFAULT; + goto out; } + count++; } - card_res->count_crtcs = crtc_count; - - /* Encoders */ - if (card_res->count_encoders >= encoder_count) { - copied = 0; - encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr; - drm_for_each_encoder(encoder, dev) { - if (put_user(encoder->base.id, encoder_id + - copied)) { - ret = -EFAULT; - goto out; - } - copied++; + card_res->count_crtcs = count; + + count = 0; + encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr); + drm_for_each_encoder(encoder, dev) { + if (count < card_res->count_encoders && + put_user(encoder->base.id, encoder_id + count)) { + ret = -EFAULT; + goto out; } + count++; } - card_res->count_encoders = encoder_count; - - /* Connectors */ - if (card_res->count_connectors >= connector_count) { - copied = 0; - connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr; - drm_for_each_connector(connector, dev) { - if (put_user(connector->base.id, - connector_id + copied)) { - ret = -EFAULT; - goto out; - } - copied++; + card_res->count_encoders = count; + + count = 0; + connector_id = u64_to_user_ptr(card_res->connector_id_ptr); + drm_for_each_connector(connector, dev) { + if (count < card_res->count_connectors && + put_user(connector->base.id, connector_id + count)) { + ret = -EFAULT; + goto out; } + count++; } - card_res->count_connectors = connector_count; + card_res->count_connectors = count; out: mutex_unlock(&dev->mode_config.mutex);