Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp1560468yba; Thu, 9 May 2019 19:37:38 -0700 (PDT) X-Google-Smtp-Source: APXvYqwY1tDntEjom0wy1eF5lg27G7x9t9gZKYX65l5eu9gKyNzWrB5rolGg4FatTcskv2otsovw X-Received: by 2002:a63:8149:: with SMTP id t70mr10512603pgd.134.1557455858722; Thu, 09 May 2019 19:37:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1557455858; cv=none; d=google.com; s=arc-20160816; b=w8CqdoVYt7iTzhaty2LwPY8P8SX92/wLwzX1hHl0/1ekedIEbLAo2xv6b+kHoNMFmH MFvED1gIIeJ+PoEHrk3XSj+hNkIfwQrdoX+KnjTfoddOIYIt5UjzJSV8rE9nX2ikMELB x+yadY1p23gF8oAJCET8A5y86Rhvkt1Uyz5jnzx+/9P7iCMllNy4RheFXd1Dod/yOlPn zE59bVdjwnW6Tt12q4gwArUchGC6mhewG9cwocPUwh0VurjvcPHhfhY9yACGj4SA/RMc c3X1EPqQHnUj9dJzXJKY+Sk295T21+Wz6PjvbZh8RtQrG8KU9Y6bnnueSBMH50McmGR0 x7kQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature:dkim-signature; bh=oq0fGdbH5xzNc9jhnh1krS5EBRxWNU/NUMrL0ejnGQ4=; b=Jj+bTUHF0azahxYFHnE3tMETM1BoMrqy4sIGOXGwZgDvopcnvja96JxwP1UtRlSxDw ty86p5ATMIrVGYPRfdBR0Hgxdj2U8s3cq2y88p2tAQlHn5iKV+MUlByF/guLG6uOceTq h9NHKVqDaULqWNCLEI4iRfQM/afdkoI6KrYudv1mC96n0V0RbegwJf0RZScCt8KBEypP pwSqY2592AKDnjxGqW5mu5Zaf4J5a0kEKgD7IVVisHqkCE937ZU3lYk3mwrkLHOOJhi0 wfRzjPr9gKo1VK4965MNSxLOuEHILTVn474mFsFuO4VN6+n/jArqAO/5k5txjRhs5Yrx ap7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@tobin.cc header.s=fm3 header.b=LyeO9kBX; dkim=pass header.i=@messagingengine.com header.s=fm2 header.b=5NKlvlAE; 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 4si5583130pfp.185.2019.05.09.19.37.20; Thu, 09 May 2019 19:37:38 -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; dkim=pass header.i=@tobin.cc header.s=fm3 header.b=LyeO9kBX; dkim=pass header.i=@messagingengine.com header.s=fm2 header.b=5NKlvlAE; 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 S1726952AbfEJCgP (ORCPT + 99 others); Thu, 9 May 2019 22:36:15 -0400 Received: from out4-smtp.messagingengine.com ([66.111.4.28]:45393 "EHLO out4-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726806AbfEJCgO (ORCPT ); Thu, 9 May 2019 22:36:14 -0400 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 5C10021ED6; Thu, 9 May 2019 22:36:13 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Thu, 09 May 2019 22:36:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tobin.cc; h=date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm3; bh=oq0fGdbH5xzNc9jhnh1krS5EBRx WNU/NUMrL0ejnGQ4=; b=LyeO9kBXfKWlmWNoBQv/HNF1JjCi18fLjEnpfyDvJs6 /ICE59LQQnKoVkFHkWI0EpBxlibxrDjtvT2qqZYeQrRIOVBeDn7Dm3IolKUy7fKx KCAcpfueNQQb0kDQ7zyVH10q7pAtyXz87ol7bHMY0r7PVeFNHwBdWESfRwVOcbpE XcK87RJb4p6MMVgUS8l2DBguTN4QdjxH1Bqhuq94PHvZFqv45oAgjMrRX33bK7/P waI6pqXj+xBi1iEdgOkbIhhpAXeWV86tvRN8473Pjtv4+oaMAnTJ5gQnjUjf3mo7 5PS7cnfO/HTCxhNiTu/eJd8+o8KIx5O7AthHC0ARGEg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=oq0fGd bH5xzNc9jhnh1krS5EBRxWNU/NUMrL0ejnGQ4=; b=5NKlvlAE4PXYeoGja1WKki TH7yJ/iCwT8wJRa5FvXSU3xCMqr70A3kRDj/KtFhUjrZ+nVcJPeZF9kwq8bOSMf/ iLZKq+K1o7hMirnLfDnd0jFuApuzWhB9Irfi/da6uNF0++4MiZPO+9W+nV/Lq+7N NH3gGVEsbrV3OgbSn6zNe0NHfALUN4TYLRz3JUEnPpuWiuH9jcX93J8tAjeRw4Do X8NNDY1dc2jK38ONHzSuue2CICy+EXzk1nmI9DUf3uu4uZXuBTU1BIRUSE711Urh aOgxnykqcNnjiRyLBILoHlnmWzq0PLKrcSk3goGFq3uaiHVKFpzZHStdBVa0+U8A == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduuddrkeeigdduieehucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne gfrhhlucfvnfffucdlfedtmdenucfjughrpeffhffvuffkfhggtggujgfofgesthdtredt ofervdenucfhrhhomhepfdfvohgsihhnucevrdcujfgrrhguihhnghdfuceomhgvsehtoh gsihhnrdgttgeqnecukfhppeduvdegrddujedurddvuddrhedvnecurfgrrhgrmhepmhgr ihhlfhhrohhmpehmvgesthhosghinhdrtggtnecuvehluhhsthgvrhfuihiivgeptd X-ME-Proxy: Received: from localhost (124-171-21-52.dyn.iinet.net.au [124.171.21.52]) by mail.messagingengine.com (Postfix) with ESMTPA id CBD0C103D1; Thu, 9 May 2019 22:36:11 -0400 (EDT) Date: Fri, 10 May 2019 12:35:38 +1000 From: "Tobin C. Harding" To: "Rafael J. Wysocki" Cc: Greg Kroah-Hartman , Tyrel Datwyler , Andy Shevchenko , Petr Mladek , Miroslav Benes , Viresh Kumar , Linux Kernel Mailing List Subject: Re: kobject_init_and_add() confusion Message-ID: <20190510023538.GA10356@eros.localdomain> References: <20190430233803.GB10777@eros.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Mailer: Mutt 1.11.4 (2019-03-13) User-Agent: Mutt/1.11.4 (2019-03-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, May 01, 2019 at 09:54:16AM +0200, Rafael J. Wysocki wrote: > On Wed, May 1, 2019 at 1:38 AM Tobin C. Harding wrote: > > > > Hi, > > > > Looks like I've created a bit of confusion trying to fix memleaks in > > calls to kobject_init_and_add(). Its spread over various patches and > > mailing lists so I'm starting a new thread and CC'ing anyone that > > commented on one of those patches. > > > > If there is a better way to go about this discussion please do tell me. > > > > The problem > > ----------- > > > > Calls to kobject_init_and_add() are leaking memory throughout the kernel > > because of how the error paths are handled. > > > > The solution > > ------------ > > > > Write the error path code correctly. > > > > Example > > ------- > > > > We have samples/kobject/kobject-example.c but it uses > > kobject_create_and_add(). I thought of adding another example file here > > but could not think of how to do it off the top of my head without being > > super contrived. Can add this to the TODO list if it will help. > > > > Here is an attempted canonical usage of kobject_init_and_add() typical > > of the code that currently is getting it wrong. This is the second time > > I've written this and the first time it was wrong even after review (you > > know who you are, you are definitely buying the next round of drinks :) > > > > > > Assumes we have an object in memory already that has the kobject > > embedded in it. Variable 'kobj' below would typically be &ptr->kobj > > > > > > void fn(void) > > { > > int ret; > > > > ret = kobject_init_and_add(kobj, ktype, NULL, "foo"); > > if (ret) { > > /* > > * This means kobject_init() has succeeded > > * but kobject_add() failed. > > */ > > goto err_put; > > } > > > > ret = some_init_fn(); > > if (ret) { > > /* > > * We need to wind back kobject_add() AND kobject_put(). > > kobject_add() and kobject_init() I suppose? > > > * kobject_add() incremented the refcount in > > * kobj->parent, that needs to be decremented THEN we need > > * the call to kobject_put() to decrement the refcount of kobj. > > */ > > So actually, if you look at kobject_cleanup(), it calls kobject_del() > if kobj->state_in_sysfs is set. > > Now, if you look at kobject_add_internal(), it sets > kobj->state_in_sysfs when about to return 0 (success). > > Therefore calling kobject_put() without the preceding kobject_del() is > not a bug technically, even though it will trigger the "auto cleanup > kobject_del" message with debug enabled. > > > goto err_del; > > } > > > > ret = some_other_init_fn(); > > if (ret) > > goto other_err; > > > > kobject_uevent(kobj, KOBJ_ADD); > > return 0; > > > > other_err: > > other_clean_up_fn(); > > err_del: > > kobject_del(kobj); > > err_put: > > kobject_put(kobj); > > > > return ret; > > } > > > > > > Have I got this correct? > > > > TODO > > ---- > > > > - Fix all the callsites to kobject_init_and_add() > > - Further clarify the function docstring for kobject_init_and_add() [perhaps] > > - Add a section to Documentation/kobject.txt [optional] > > - Add a sample usage file under samples/kobject [optional] > > The plan sounds good to me, but there is one thing to note IMO: > kobject_cleanup() invokes the ->release() callback for the ktype, so > these callbacks need to be able to cope with kobjects after a failing > kobject_add() which may not be entirely obvious to developers > introducing them ATM. It has taken a while for this to soak in. This is actually quite an insidious issue. If I give an example and perhaps we can come to a solution. This example is based on the code (and assumptions) in mm/slub.c If a developer has an object that they wish to add to sysfs they go ahead and embed a kobject in it. Correctly set up a ktype including release function that just frees the object (using container of). Now assume that the object is already set up and in use when we go to set up the sysfs entry. If kobject_init_and_add() fails and we correctly call kobject_put() the containing object will be free'd. Yet the calling code may not be done with the object, more to the point just because sysfs setup fails the object is now unusable. Besides the interesting theoretical discussion this means we cannot just go and willy-nilly add calls to kobject_put() in the error path of kobject_init_and_add() if the original code was not written under the assumption that the release method could be called during the error path (I have found 2 places at least where behaviour of calling the release method is non-trivial to ascertain). I guess, as Greg said, its just a matter that reference counting within the kernel is a hard problem. So we fix the easy ones and then look a bit harder at the hard ones ... Any better suggestion? thanks, Tobin.