Received: by 2002:a25:824b:0:0:0:0:0 with SMTP id d11csp2676578ybn; Thu, 26 Sep 2019 15:58:18 -0700 (PDT) X-Google-Smtp-Source: APXvYqw7jCd6yIjg0c5rMr8fVrPLoEOHE+qDkFBSsCS+IaisEMb9HRvW1fyA5EdZ//MU2QFmWXxa X-Received: by 2002:a50:aa86:: with SMTP id q6mr1414570edc.288.1569538698293; Thu, 26 Sep 2019 15:58:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569538698; cv=none; d=google.com; s=arc-20160816; b=yA6wEHqIB2QmbUIUCQV/XuXAduE9xE1a3hRyo/VPwSgPEKeilB7hBZurjMmEAmI4tu bMnEYs7fiV5rNSsJwmf5UZSDSvYovGDsemFTiVtNUasEfmoM6kj7Pe1Hiqj0CSJYlOgo qlT3di8xLyTinncpTgiwyOLxatBRhqHBaa4mTGfQWjdHf9TMcUnlVvrYyRobqzmdN6mk ESyY2A3xXf0la9fnq5vtTlovpVtsO8qEKIlQC4e3B3JX+1aBBmw7Ei20b/g+BH3njuQ0 5uftod5Q+SzAVe9BrtZaoZoim5JMBsq/892bz7W2i761b43cQmCKYFE/vaTWzg21AYEc lW0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=pZouveFpafPrKN4WQmTJDYEkbA03/pWxtsVM4UwbyE4=; b=MKImz83aZPWHKVwQ6JnLGvYsu8ZzI3opNGsbcswj0m5emgJuYTRLwv+d3xINXqBDRk veom1WisYMfXKW5geWJ76KsC8dmLe7gpA73nnNwPBnCYrgDlNYn0qTK1hqNfoHDhGU2Z nvn/Bw5CGpG52UH1OLf/qyPH1QrgDXjVsf1RxfUjIn5KROulaHF8OwBtyAgBBnFD/pCj vOFELrH1L23zXtr+zd3OaGTD3XQ9ntBmGWlbURmrDRx4kXhVPC66oOGltM5cdYnw6agY NEo4W24zk85JMZmLqciQZ26zTff1RLLJpqloji41U8klVhsCd1aRJCQ/SU9HyJv/aDoe vSzQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k9si465121edb.56.2019.09.26.15.57.53; Thu, 26 Sep 2019 15:58:18 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728930AbfIZWwV (ORCPT + 99 others); Thu, 26 Sep 2019 18:52:21 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50692 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728564AbfIZWwU (ORCPT ); Thu, 26 Sep 2019 18:52:20 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BC6FF796ED; Thu, 26 Sep 2019 22:52:19 +0000 (UTC) Received: from malachite.bss.redhat.com (dhcp-10-20-1-34.bss.redhat.com [10.20.1.34]) by smtp.corp.redhat.com (Postfix) with ESMTP id C54DA600C1; Thu, 26 Sep 2019 22:52:18 +0000 (UTC) From: Lyude Paul To: amd-gfx@lists.freedesktop.org Cc: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Maarten Lankhorst , Maxime Ripard , Sean Paul , David Airlie , Daniel Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH 6/6] drm/encoder: WARN() when adding/removing encoders after device registration Date: Thu, 26 Sep 2019 18:51:08 -0400 Message-Id: <20190926225122.31455-7-lyude@redhat.com> In-Reply-To: <20190926225122.31455-1-lyude@redhat.com> References: <20190926225122.31455-1-lyude@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 26 Sep 2019 22:52:19 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Turns out that we don't actually check this anywhere, and additionally actually forget to even mention this in our documentation. Since we've had one driver making this mistake already, let's clarify this by mentioning this limitation in the kernel docs. Additionally, for drivers not using the legacy ->load/->unload() hooks (which make it impossible to create all encoders before registration): print a big warning when drm_encoder_init() is called after device registration, or when drm_encoder_cleanup() is called before device unregistration. Signed-off-by: Lyude Paul Cc: Ville Syrjälä --- drivers/gpu/drm/drm_encoder.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c index 80d88a55302e..5c5e40aafa4e 100644 --- a/drivers/gpu/drm/drm_encoder.c +++ b/drivers/gpu/drm/drm_encoder.c @@ -99,9 +99,12 @@ void drm_encoder_unregister_all(struct drm_device *dev) * @encoder_type: user visible type of the encoder * @name: printf style format string for the encoder name, or NULL for default name * - * Initialises a preallocated encoder. Encoder should be subclassed as part of - * driver encoder objects. At driver unload time drm_encoder_cleanup() should be - * called from the driver's &drm_encoder_funcs.destroy hook. + * Initialises a preallocated encoder. The encoder should be subclassed as + * part of driver encoder objects. This function may not be called after the + * device is registered with drm_dev_register(). + * + * At driver unload time drm_encoder_cleanup() must be called from the + * driver's &drm_encoder_funcs.destroy hook. * * Returns: * Zero on success, error code on failure. @@ -117,6 +120,14 @@ int drm_encoder_init(struct drm_device *dev, if (WARN_ON(dev->mode_config.num_encoder >= 32)) return -EINVAL; + /* + * Encoders should never be added after device registration, with the + * exception of drivers using the legacy load/unload callbacks where + * it's impossible to create encoders beforehand. Such drivers should + * convert to using drm_dev_register() and friends. + */ + WARN_ON(dev->registered && !dev->driver->load); + ret = drm_mode_object_add(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); if (ret) return ret; @@ -155,16 +166,22 @@ EXPORT_SYMBOL(drm_encoder_init); * drm_encoder_cleanup - cleans up an initialised encoder * @encoder: encoder to cleanup * - * Cleans up the encoder but doesn't free the object. + * Cleans up the encoder but doesn't free the object. This function may not be + * called until the respective &struct drm_device has been unregistered from + * userspace using drm_dev_unregister(). */ void drm_encoder_cleanup(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; - /* Note that the encoder_list is considered to be static; should we - * remove the drm_encoder at runtime we would have to decrement all - * the indices on the drm_encoder after us in the encoder_list. + /* + * Encoders should never be removed after device registration, with + * the exception of drivers using the legacy load/unload callbacks + * where it's impossible to remove encoders until after + * deregistration. Such drivers should convert to using + * drm_dev_register() and friends. */ + WARN_ON(dev->registered && !dev->driver->unload); if (encoder->bridge) { struct drm_bridge *bridge = encoder->bridge; -- 2.21.0