Received: by 10.192.165.148 with SMTP id m20csp1904457imm; Thu, 26 Apr 2018 04:02:23 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/VDrLY++7NkazEbVzSgoPWUUB9e5YFrqbCB6fOsDDUSqJYvmtIzh3ArKH4tqsVzCM117pu X-Received: by 2002:a17:902:6086:: with SMTP id s6-v6mr32973497plj.307.1524740543471; Thu, 26 Apr 2018 04:02:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524740543; cv=none; d=google.com; s=arc-20160816; b=ER0WSRSfl2ggaARyzPr8RVNxSIy6G5bdZ9fnskLDL26lXah156SkcWifhkJMKjBck9 oh1uizq+QLGnNseASRuhUjOtw+OaikhhmBj8Pm+d81hEoVCx2L0jNkyKIOm7vmKAQ4vQ 4pluFLol2G/5nn03kuX4QFTL5RXRSeoUIlapsk+YMtBe8A50ehC71zeb7CUm9j+p+0FF jauWTawMuEsy0a9Eci1YpJZ/Q7bD/dB5ALx/HmfZwqOgGxMNfN1dm3sMynXqxmukR7Oc EzwWROkH2PM7fT6L3LSfJ3YTv49o4t6wtNgao4ftLpKyyCRQOF30K1WyWFZXNVSuSZBg mndQ== 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 :content-language:mime-version:user-agent:date:message-id:cc:to :subject:from:arc-authentication-results; bh=SGJ/EfgM5bLUSlRMYQ/0fyqL7FMLapPT8ys+egjHZD8=; b=ubDLqs1HsNBecZdbpxfmA3mqpWdsik0qqUyVxiEb1spuPbLudX7WsjyM7wnAEfpYCs mtv1YdvYI7IsJZ07lU1sDq7ih9Ozh5ospvo2aHksyKqtj0VnLxI7mzXNPY/B85RIBAgP AtA56kdqCbnTtXZe2W8KOdJYgliZjiykYsi+XwYdW2KwNZVPAbdQIux3FWR77iYpW6jo NDsaP/veNqwNJ3u3TCKeRBHn1VrZY1OZOxOfZVKjpHhi92wt+Lpws4IYntHM2WFpZMtN tCEZRjxCT7/egnHKCjSOvsRHC/sUeuhJre+x9E2V7iDl941nEJwZPXq/3RHyikCIjSof FWaw== 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q7si15197755pgt.242.2018.04.26.04.02.08; Thu, 26 Apr 2018 04:02:23 -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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755328AbeDZLAr (ORCPT + 99 others); Thu, 26 Apr 2018 07:00:47 -0400 Received: from david.siemens.de ([192.35.17.14]:46816 "EHLO david.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754663AbeDZLAn (ORCPT ); Thu, 26 Apr 2018 07:00:43 -0400 Received: from mail1.siemens.de (mail1.siemens.de [139.23.33.14]) by david.siemens.de (8.15.2/8.15.2) with ESMTPS id w3QB0VCL002976 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 26 Apr 2018 13:00:31 +0200 Received: from [139.25.68.37] (md1q0hnc.ad001.siemens.net [139.25.68.37] (may be forged)) by mail1.siemens.de (8.15.2/8.15.2) with ESMTP id w3QB0VYi023704; Thu, 26 Apr 2018 13:00:31 +0200 From: Jan Kiszka Subject: [PATCH v2] of: overlay: Stop leaking resources on overlay removal To: Pantelis Antoniou , Rob Herring , Frank Rowand , devicetree Cc: Linux Kernel Mailing List , Alan Tull , Geert Uytterhoeven X-Mozilla-News-Host: news://news://news.gmane.org:119 Message-ID: Date: Thu, 26 Apr 2018 13:00:30 +0200 User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Only the overlay notifier callbacks have a chance to potentially get hold of references to those two resources, but they are not supposed to store them beyond OF_OVERLAY_POST_REMOVE. Document the overlay notifier API, its constraint regarding pointer lifetime, and then remove intentional leaks of ovcs->overlay_tree and ovcs->fdt from free_overlay_changeset. See also https://lkml.org/lkml/2018/4/23/1063 and following. Signed-off-by: Jan Kiszka --- Documentation/devicetree/overlay-notes.txt | 8 ++++++++ drivers/of/overlay.c | 30 +++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/overlay-notes.txt b/Documentation/devicetree/overlay-notes.txt index a4feb6dde8cd..725fb8d255c1 100644 --- a/Documentation/devicetree/overlay-notes.txt +++ b/Documentation/devicetree/overlay-notes.txt @@ -98,6 +98,14 @@ Finally, if you need to remove all overlays in one-go, just call of_overlay_remove_all() which will remove every single one in the correct order. +In addition, there is the option to register notifiers that get called on +overlay operations. See of_overlay_notifier_register/unregister and +enum of_overlay_notify_action for details. + +Note that a notifier callback is not supposed to store pointers to a device +tree node or its content beyond OF_OVERLAY_POST_REMOVE corresponding to the +respective node it received. + Overlay DTS Format ------------------ diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index b35fe88f1851..7baa53e5b1d7 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -102,12 +102,28 @@ static DEFINE_IDR(ovcs_idr); static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain); +/** + * of_overlay_notifier_register() - Register notifier for overlay operations + * @nb: Notifier block to register + * + * Register for notification on overlay operations on device tree nodes. The + * reported actions definied by @of_reconfig_change. The notifier callback + * furthermore receives a pointer to the affected device tree node. + * + * Note that a notifier callback is not supposed to store pointers to a device + * tree node or its content beyond @OF_OVERLAY_POST_REMOVE corresponding to the + * respective node it received. + */ int of_overlay_notifier_register(struct notifier_block *nb) { return blocking_notifier_chain_register(&overlay_notify_chain, nb); } EXPORT_SYMBOL_GPL(of_overlay_notifier_register); +/** + * of_overlay_notifier_register() - Unregister notifier for overlay operations + * @nb: Notifier block to unregister + */ int of_overlay_notifier_unregister(struct notifier_block *nb) { return blocking_notifier_chain_unregister(&overlay_notify_chain, nb); @@ -671,17 +687,13 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) of_node_put(ovcs->fragments[i].overlay); } kfree(ovcs->fragments); - /* - * TODO - * - * would like to: kfree(ovcs->overlay_tree); - * but can not since drivers may have pointers into this data - * - * would like to: kfree(ovcs->fdt); - * but can not since drivers may have pointers into this data + * There should be no live pointers into ovcs->overlay_tree and + * ovcs->fdt due to the policy that overlay notifiers are not allowed + * to retain pointers into the overlay devicetree. */ - + kfree(ovcs->overlay_tree); + kfree(ovcs->fdt); kfree(ovcs); } -- 2.13.6