From patchwork Tue Oct 17 09:06:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 116031 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp4636397qgn; Tue, 17 Oct 2017 02:06:42 -0700 (PDT) X-Google-Smtp-Source: AOwi7QAZ5HUv20ye5cREccPiMv2Rr8GdEuz4JLHzo8CQ07MQBG8kWfIiQlw4pUFlKQCJy4VXJXKN X-Received: by 10.99.98.70 with SMTP id w67mr10618928pgb.9.1508231202517; Tue, 17 Oct 2017 02:06:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1508231202; cv=none; d=google.com; s=arc-20160816; b=YHSF49keVw9mDd5NVXqUA1s719265T50UpInpgw3cAv31Fk+gHP1ddj2pmwm5MNWjq 5KldGk+2iU2cLnasN78s7l+EFZ4vIYvWHqg5hqr7zqWCjMmoUEla9e1O11R4VdEktNVo ysEcV9JPnCPCAxYwgSefjc2GaNfbtoPyHc+DfQcSn2PSb4EIDwIeBpUZpKi7pdZtsz6W pB9fGEKN7/eXyrcjGMLxwVN+4DXom0Zk/gtR/qavuR+3KQrT91MVdr98akgAP2EKP1JU 41CZAeTwKPt00eJwu88tdt+kAUxjut5cJKx5b8vY8w7kzr6CShltRcyrxv39q0Z3XDHB kOSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:cc:references:in-reply-to:references:in-reply-to :message-id:date:subject:to:from:delivered-to :arc-authentication-results; bh=sQhJy6p4V4fPMeCFBERc9W8BrSV0mMlTDcj+RGu4+04=; b=uBKQssMs22u1ZN+xJhHOT0JtvuxveW59fLpeY2ICqeaivHnRFMSofVIKlazqIbr6Sh NMO5fj0dUFRhGCKXl1+8d5W1+nfyI0drNlN0xwZikHScK5deW62KFuAkB4qwHVkDLGFz gWtGI9+EN5us+hKwzN3gQAfs9YH+tHEJry/6J8PKoBEeGwUdSKZSx5tgJI5pVMaMsqCi ufONBPFEEpMaqwSrn09Mbv6WoqnxsCEecFF4p2C41ALfPw4e6FyGSbgNl9vCKl2wMUnH YKeNTvQCSakrrxE0+BoS4RvMPl8QR1BLE4AZKpzUgLCe6EZMxPQsWW/hBtdqpqodJW9s Odrg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTPS id y17si5233692pge.61.2017.10.17.02.06.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 17 Oct 2017 02:06:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3B9876E601; Tue, 17 Oct 2017 09:06:41 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail.free-electrons.com (mail.free-electrons.com [62.4.15.54]) by gabe.freedesktop.org (Postfix) with ESMTP id 59A316E601 for ; Tue, 17 Oct 2017 09:06:40 +0000 (UTC) Received: by mail.free-electrons.com (Postfix, from userid 110) id 76FAC20880; Tue, 17 Oct 2017 11:06:38 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 48D1C207B6; Tue, 17 Oct 2017 11:06:38 +0200 (CEST) From: Maxime Ripard To: Daniel Vetter , David Airlie , Chen-Yu Tsai , Maxime Ripard Subject: [PATCH 01/23] drm/sun4i: Implement endpoint parsing using kfifo Date: Tue, 17 Oct 2017 11:06:08 +0200 Message-Id: <4ecb323e787918208f6a5d9f0ebba12c62583c98.1508231063.git-series.maxime.ripard@free-electrons.com> X-Mailer: git-send-email 2.14.2 In-Reply-To: References: In-Reply-To: References: Cc: Mark Rutland , Thomas Petazzoni , plaes@plaes.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Quentin Schulz , Rob Herring , Mylene Josserand , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org, icenowy@aosc.io 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" The commit da82b8785eeb ("drm/sun4i: add components in breadth first traversal order") implemented a breadth first traversal of our device tree nodes graph. However, it was relying on the kernel linked lists, and those are not really safe for addition. Indeed, in a single pipeline stage, your first stage (ie, the mixer or fronted) will be queued, and it will be the final iteration of that list as far as list_for_each_entry_safe is concerned. Then, during that final iteration, we'll queue another element (the TCON or the backend) that list_for_each_entry_safe will not account for, and we will leave the loop without having iterated over all the elements. And since we won't have built our components list properly, the DRM driver will be left non-functional. We can instead use a kfifo to queue and enqueue components in-order, as was the original intention. This also has the benefit of removing any dynamic allocation, making the error handling path simpler too. The only thing we're losing is the ability to tell whether an element has already been queued, but that was only needed to remove spurious logs, and therefore purely cosmetic. This means that this commit effectively reverses e8afb7b67fba ("drm/sun4i: don't add components that are already in the queue"). Fixes: da82b8785eeb ("drm/sun4i: add components in breadth first traversal order") Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_drv.c | 71 +++++--------------------------- 1 file changed, 13 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index b5879d4620d8..a27efad9bc76 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -11,6 +11,7 @@ */ #include +#include #include #include @@ -222,29 +223,15 @@ static int compare_of(struct device *dev, void *data) * matching system handles this for us. */ struct endpoint_list { - struct device_node *node; - struct list_head list; + DECLARE_KFIFO(fifo, struct device_node *, 16); }; -static bool node_is_in_list(struct list_head *endpoints, - struct device_node *node) -{ - struct endpoint_list *endpoint; - - list_for_each_entry(endpoint, endpoints, list) - if (endpoint->node == node) - return true; - - return false; -} - static int sun4i_drv_add_endpoints(struct device *dev, - struct list_head *endpoints, + struct endpoint_list *list, struct component_match **match, struct device_node *node) { struct device_node *port, *ep, *remote; - struct endpoint_list *endpoint; int count = 0; /* @@ -304,19 +291,7 @@ static int sun4i_drv_add_endpoints(struct device *dev, } } - /* skip downstream node if it is already in the queue */ - if (node_is_in_list(endpoints, remote)) - continue; - - /* Add downstream nodes to the queue */ - endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL); - if (!endpoint) { - of_node_put(remote); - return -ENOMEM; - } - - endpoint->node = remote; - list_add_tail(&endpoint->list, endpoints); + kfifo_put(&list->fifo, remote); } return count; @@ -325,10 +300,11 @@ static int sun4i_drv_add_endpoints(struct device *dev, static int sun4i_drv_probe(struct platform_device *pdev) { struct component_match *match = NULL; - struct device_node *np = pdev->dev.of_node; - struct endpoint_list *endpoint, *endpoint_temp; + struct device_node *np = pdev->dev.of_node, *endpoint; + struct endpoint_list list; int i, ret, count = 0; - LIST_HEAD(endpoints); + + INIT_KFIFO(list.fifo); for (i = 0;; i++) { struct device_node *pipeline = of_parse_phandle(np, @@ -337,31 +313,19 @@ static int sun4i_drv_probe(struct platform_device *pdev) if (!pipeline) break; - endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL); - if (!endpoint) { - ret = -ENOMEM; - goto err_free_endpoints; - } - - endpoint->node = pipeline; - list_add_tail(&endpoint->list, &endpoints); + kfifo_put(&list.fifo, pipeline); } - list_for_each_entry_safe(endpoint, endpoint_temp, &endpoints, list) { + while (kfifo_get(&list.fifo, &endpoint)) { /* process this endpoint */ - ret = sun4i_drv_add_endpoints(&pdev->dev, &endpoints, &match, - endpoint->node); + ret = sun4i_drv_add_endpoints(&pdev->dev, &list, &match, + endpoint); /* sun4i_drv_add_endpoints can fail to allocate memory */ if (ret < 0) - goto err_free_endpoints; + return ret; count += ret; - - /* delete and cleanup the current entry */ - list_del(&endpoint->list); - of_node_put(endpoint->node); - kfree(endpoint); } if (count) @@ -370,15 +334,6 @@ static int sun4i_drv_probe(struct platform_device *pdev) match); else return 0; - -err_free_endpoints: - list_for_each_entry_safe(endpoint, endpoint_temp, &endpoints, list) { - list_del(&endpoint->list); - of_node_put(endpoint->node); - kfree(endpoint); - } - - return ret; } static int sun4i_drv_remove(struct platform_device *pdev)