linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Petr Mladek <pmladek@suse.com>
To: Miroslav Benes <mbenes@suse.cz>
Cc: Jiri Kosina <jikos@kernel.org>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	Jason Baron <jbaron@akamai.com>,
	Joe Lawrence <joe.lawrence@redhat.com>,
	Jessica Yu <jeyu@kernel.org>,
	Evgenii Shatokhin <eshatokhin@virtuozzo.com>,
	live-patching@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v12 04/12] livepatch: Consolidate klp_free functions
Date: Fri, 12 Oct 2018 13:43:05 +0200	[thread overview]
Message-ID: <20181012114305.tj72zxridkyayyq3@pathway.suse.cz> (raw)
In-Reply-To: <alpine.LSU.2.21.1808311232050.4783@pobox.suse.cz>

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

  reply	other threads:[~2018-10-12 11:43 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-28 14:35 [PATCH v12 00/12] Petr Mladek
2018-08-28 14:35 ` [PATCH v12 01/12] livepatch: Change void *new_func -> unsigned long new_addr in struct klp_func Petr Mladek
2018-08-31  8:37   ` Miroslav Benes
2018-08-28 14:35 ` [PATCH v12 02/12] livepatch: Helper macros to define livepatch structures Petr Mladek
2018-08-28 14:35 ` [PATCH v12 03/12] livepatch: Shuffle klp_enable_patch()/klp_disable_patch() code Petr Mladek
2018-08-31  8:38   ` Miroslav Benes
2018-08-28 14:35 ` [PATCH v12 04/12] livepatch: Consolidate klp_free functions Petr Mladek
2018-08-31 10:39   ` Miroslav Benes
2018-10-12 11:43     ` Petr Mladek [this message]
2018-08-28 14:35 ` [PATCH v12 05/12] livepatch: Refuse to unload only livepatches available during a forced transition Petr Mladek
2018-08-28 14:35 ` [PATCH v12 06/12] livepatch: Simplify API by removing registration step Petr Mladek
2018-09-05  9:34   ` Miroslav Benes
2018-10-12 13:01     ` Petr Mladek
2018-10-15 16:01       ` Miroslav Benes
2018-10-18 14:54         ` Petr Mladek
2018-10-18 15:30           ` Josh Poimboeuf
2018-10-19 12:16             ` Miroslav Benes
2018-10-19 14:36               ` Josh Poimboeuf
2018-10-22 13:25                 ` Petr Mladek
2018-10-23 16:39                   ` Josh Poimboeuf
2018-10-24  2:55                     ` Josh Poimboeuf
2018-10-24 11:14                     ` Petr Mladek
2018-08-28 14:35 ` [PATCH v12 07/12] livepatch: Use lists to manage patches, objects and functions Petr Mladek
2018-09-03 16:00   ` Miroslav Benes
2018-10-12 12:12     ` Petr Mladek
2018-08-28 14:35 ` [PATCH v12 08/12] livepatch: Add atomic replace Petr Mladek
2018-08-28 14:36 ` [PATCH v12 09/12] livepatch: Remove Nop structures when unused Petr Mladek
2018-09-04 14:50   ` Miroslav Benes
2018-08-28 14:36 ` [PATCH v12 10/12] livepatch: Atomic replace and cumulative patches documentation Petr Mladek
2018-09-04 15:15   ` Miroslav Benes
2018-08-28 14:36 ` [PATCH v12 11/12] livepatch: Remove ordering and refuse loading conflicting patches Petr Mladek
2018-08-28 14:36 ` [PATCH v12 12/12] selftests/livepatch: introduce tests Petr Mladek
2018-08-30 11:58 ` [PATCH v12 00/12] Miroslav Benes
2018-10-11 12:48   ` Petr Mladek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181012114305.tj72zxridkyayyq3@pathway.suse.cz \
    --to=pmladek@suse.com \
    --cc=eshatokhin@virtuozzo.com \
    --cc=jbaron@akamai.com \
    --cc=jeyu@kernel.org \
    --cc=jikos@kernel.org \
    --cc=joe.lawrence@redhat.com \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mbenes@suse.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).