Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp657438imm; Fri, 12 Oct 2018 04:43:44 -0700 (PDT) X-Google-Smtp-Source: ACcGV63EhZ3n2eLH6UreDzGEuqJ1RRciw19e++VMF7pRtFsbuSbHrfNDX/WYe7YjCe7U+I/8CAsB X-Received: by 2002:a62:968a:: with SMTP id s10-v6mr5676281pfk.191.1539344624635; Fri, 12 Oct 2018 04:43:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539344624; cv=none; d=google.com; s=arc-20160816; b=OPzCpcJ2cYRTslt6Xgw9whH2eK54AEVqpjqbnBHHlPG56DH8TKx5f5O6r8HpVOo+Xe PvNLjoe+6X9IoqS2fFruMfrpi85kKZdhbC3dqQyNx2eL/H0fmn3q+qZPst6LWMkqnv7K C7wMRcBkFEu2OpBlrIdZDqmEkPtJab74XAqhJbyJCMDGKXl1fxIA2i2K+QT7rSGOYd3Z bvvdGLd+i8PK6PL6GsO0CKkfa6KxvXIFUgTfWIEN2m70OfPwZiWQpbbsNuv259EI1F4a u2mFjtqF6bZ9H4M+mHTIX27qj+4cV5bLPpD8I0DQnu8+czJpsSmfTGzOSJxxi7r1rOjg dHjw== 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; bh=6lM3b7mDhBSUDeV1ijLEi3rM3ANksEBTiViax241/a8=; b=oZDbFlK+2+vc3Fn/cRa6z4LbxYDsRiV1uk+4RFVyVOzvuu4bvQGRpDOBeUPnJc7j78 yIygo/kQDIIpCDB69q28p21NIja4Iowg69p/GK1giWC/IifTPoDIDaeVRW33Ihq7Xlww e3ASE3lGSOUaPK6cyC9mU03QEjw/VZFSwpFQCBnszIBZzYXW16qWM9FZVTUC/LBtsovS aH7/QRJT0MNubQtMKi1MfROV0h8kauSoYIhokeslKeNBOiVXMP3kM8pwU+sQuYqBVtG5 tJWXRXV/B7p6MuvfAskOmoJD1Rr+88fDWI7wVyYLDgScCr/+lVHhiFoGy53IFxVk7ZiS LMuQ== 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 ca4-v6si1160514plb.406.2018.10.12.04.43.29; Fri, 12 Oct 2018 04:43:44 -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 S1728213AbeJLTPL (ORCPT + 99 others); Fri, 12 Oct 2018 15:15:11 -0400 Received: from mx2.suse.de ([195.135.220.15]:60472 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726917AbeJLTPL (ORCPT ); Fri, 12 Oct 2018 15:15:11 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 476E1AE17; Fri, 12 Oct 2018 11:43:06 +0000 (UTC) Date: Fri, 12 Oct 2018 13:43:05 +0200 From: Petr Mladek To: Miroslav Benes Cc: Jiri Kosina , Josh Poimboeuf , Jason Baron , Joe Lawrence , Jessica Yu , Evgenii Shatokhin , live-patching@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v12 04/12] livepatch: Consolidate klp_free functions Message-ID: <20181012114305.tj72zxridkyayyq3@pathway.suse.cz> References: <20180828143603.4442-1-pmladek@suse.com> <20180828143603.4442-5-pmladek@suse.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20170421 (1.8.2) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri 2018-08-31 12:39:23, Miroslav Benes wrote: > On Tue, 28 Aug 2018, Petr Mladek wrote: > > > The code for freeing livepatch structures is a bit scattered and tricky: > > > > + direct calls to klp_free_*_limited() and kobject_put() are > > used to release partially initialized objects > > > > + klp_free_patch() removes the patch from the public list > > and releases all objects except for patch->kobj > > > > + object_put(&patch->kobj) and the related wait_for_completion() > > are called directly outside klp_mutex; this code is duplicated; > > > > Now, we are going to remove the registration stage to simplify the API > > and the code. This would require handling more situations in > > klp_enable_patch() error paths. > > > > More importantly, we are going to add a feature called atomic replace. > > It will need to dynamically create func and object structures. We will > > want to reuse the existing init() and free() functions. This would > > create even more error path scenarios. > > > > This patch implements a more clever free functions: > > > > + checks kobj.state_initialized instead of @limit > > > > + initializes patch->list early so that the check for empty list > > always works > > > > + The action(s) that has to be done outside klp_mutex are done > > in separate klp_free_patch_end() function. It waits only > > when patch->kobj was really released via the _begin() part. > > > > Note that it is safe to put patch->kobj under klp_mutex. It calls > > the release callback only when the reference count reaches zero. > > Therefore it does not block any related sysfs operation that took > > a reference and might eventually wait for klp_mutex. > > This seems to be the reason of the issue which lockdep reported. The patch > moved kobject_put(&patch->kobj) under klp_mutex. Perhaps I cannot read > kernfs code properly today, but I fail to understand why it is supposed to > be safe. My expectation was that any read/write operation on the related sysfs interface took reference of the kobject. Then kobject_put() would just decrement a reference counter and postpone the real removal until all other operations were finished. But it seems that the read/write operations take reference on another (kernfs_node) object and do not block releasing the kobject by kobject_put(). > > diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c > > index b3956cce239e..3ca404545150 100644 > > --- a/kernel/livepatch/core.c > > +++ b/kernel/livepatch/core.c > > @@ -465,17 +465,15 @@ static struct kobj_type klp_ktype_func = { > > .sysfs_ops = &kobj_sysfs_ops, > > }; > > > > -/* > > - * Free all functions' kobjects in the array up to some limit. When limit is > > - * NULL, all kobjects are freed. > > - */ > > -static void klp_free_funcs_limited(struct klp_object *obj, > > - struct klp_func *limit) > > +static void klp_free_funcs(struct klp_object *obj) > > { > > struct klp_func *func; > > > > - for (func = obj->funcs; func->old_name && func != limit; func++) > > - kobject_put(&func->kobj); > > + klp_for_each_func(obj, func) { > > + /* Might be called from klp_init_patch() error path. */ > > + if (func->kobj.state_initialized) > > + kobject_put(&func->kobj); > > + } > > } > > Just for the record, it is a slightly suboptimal because now we iterate > through the whole list. We could add break to else branch, I think, but > it's not necessary. Interesting optimization. It would keep the limit and work at this stage. But it would stop working once we add the dynamically allocated structures. They are allocated and initialized in two separate cycles. We need to free all allocated structures when any initialization fails. Best Regards, Petr