qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@siemens.com>
To: Avi Kivity <avi@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Liu Ping Fan <pingfank@linux.vnet.ibm.com>,
	liu ping fan <qemulist@gmail.com>,
	Anthony Liguori <anthony@codemonkey.ws>,
	"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [PATCH 10/10] qdev: fix create in place obj's life cycle problem
Date: Wed, 29 Aug 2012 19:49:43 +0200	[thread overview]
Message-ID: <503E5637.4040701@siemens.com> (raw)
In-Reply-To: <503E5422.5050805@redhat.com>

On 2012-08-29 19:40, Avi Kivity wrote:
> On 08/29/2012 10:30 AM, Jan Kiszka wrote:
>> On 2012-08-29 19:23, Avi Kivity wrote:
>>> On 08/28/2012 02:42 AM, Jan Kiszka wrote:
>>>>
>>>> Let's not talk about devices or MMIO dispatching. I think the problem is
>>>> way more generic, and we will face it multiple times in QEMU. 
>>>
>>> The problem exists outside qemu as well.  It is one of the reasons for
>>> the popularity of garbage collection IMO, and the use of reference
>>> counting when GC is not available.
>>>
>>> This pattern is even documented in
>>> Documentation/DocBook/kernel-locking.tmpl:
>>>
>>> @@ -104,12 +114,11 @@
>>>  struct object *cache_find(int id)
>>>  {
>>>          struct object *obj;
>>> -        unsigned long flags;
>>>
>>> -        spin_lock_irqsave(&amp;cache_lock, flags);
>>> +        rcu_read_lock();
>>>          obj = __cache_find(id);
>>>          if (obj)
>>>                  object_get(obj);
>>> -        spin_unlock_irqrestore(&amp;cache_lock, flags);
>>> +        rcu_read_unlock();
>>>   
>>>
>>> Of course that doesn't mean we should use it, but at least it indicates
>>> that it is a standard pattern.  With MemoryRegion the pattern is
>>> changed, since MemoryRegion is a thunk, not the object we're really
>>> dispatching to.
>>
>> We are dispatching according to the memory region (parameters, op
>> handlers, opaques). If we end up in device object is not decided at this
>> level. A memory region describes a dispatchable area - not to confuse
>> with a device that may only partially be able to receive such requests.
> 
> Correct.
> 
> Let's experiment with refcounting MemoryRegion.  We can move the entire
> contents of MemoryRegion to MemoryRegionImpl, add a reference count (to
> MemoryRegionImpl), and change MemoryRegion to contain a pointer to the
> refcounted MemoryRegionImpl:
> 
> struct MemoryRegion {
>     struct MemoryRegionImpl *impl;
> };
> 
> struct MemoryRegionImpl {
>     atomic int refs;
>     ...
> };
> 
> The memory core can then store MemoryRegion copies (with elevated
> refcounts) instead of pointers.  Devices can destroy MemoryRegions at
> any time, the implementation will not go away.  However, what of the
> opaque stored in MemoryRegionImpl?  It becomes a dangling pointer.
> 
> One way out is to add a lock to MemoryRegionImpl.  Dispatch takes the
> lock, examines the ->enabled member, and bails out if it is cleared. 
> The (MemoryRegion, not MemoryRegionImpl) destructor also takes the lock,
> clears ->enabled,  releases the lock, and drops the reference.

That means holding the MemoryRegionImpl lock across the handler call?

> 
> The advantage to this scheme is that all changes are localized to the
> memory core, no need for a full sweep.  It is a little complicated, but
> we may be able to simplify it (or find another one).

May work. We just need to detect if memory region tries to delete itself
from its handler to prevent the deadlock.

> 
>>
>>>
>>>> Besides
>>>> MMIO and PIO dispatching, it will haunt us for file or event handlers,
>>>> any kind of callbacks etc.
>>>>
>>>> Context A                               Context B
>>>> ---------                               ---------
>>>>                                         object = lookup()
>>>> deregister(object)
>>>> modify(object) -> invalid state
>>>> ...                                     use(object)
>>>> modify(object) -> valid state
>>>> register(object)
>>>>
>>>> And with "object" I'm not talking about QOM but any data structure.
>>>>
>>>
>>>
>>> Context B
>>> ---------
>>> rcu_read_lock()
>>> object = lookup()
>>> if (object) {
>>>     ref(object)
>>> }
>>> rcu_read_unlock()
>>>
>>> use(object)
>>>
>>> unref(object)
>>>
>>> (substitute locking scheme to conform to taste and/or dietary
>>> restrictions)   
>>>
>>
>> + wait for refcount(object) == 0 in deregister(object). That's what I'm
>> proposing.
> 
> Consider timer_del() called from a timer callback.  It's often not doable.

This is inherently synchronous already (when working against the same
alarm timer backend). We can detect this in timer_del and skip waiting,
as in the above scenario.

Jan

-- 
Siemens AG, Corporate Technology, CT RTC ITP SDP-DE
Corporate Competence Center Embedded Linux

  reply	other threads:[~2012-08-29 17:49 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-24  9:49 [Qemu-devel] [PATCH 0/10] rework on hot unplug Liu Ping Fan
2012-08-24  9:49 ` [Qemu-devel] [PATCH 01/10] qom: add, remove of link property need to ref, unref its target Liu Ping Fan
2012-08-24 14:52   ` Paolo Bonzini
2012-08-24  9:49 ` [Qemu-devel] [PATCH 02/10] qdev: change iterator callback seq Liu Ping Fan
2012-08-24  9:49 ` [Qemu-devel] [PATCH 03/10] qom: export object_property_is_child, object_property_is_link Liu Ping Fan
2012-08-24 14:51   ` Paolo Bonzini
2012-08-25  7:43     ` liu ping fan
2012-08-25  8:04   ` Blue Swirl
2012-08-24  9:49 ` [Qemu-devel] [PATCH 04/10] qdev: introduce new interface to remove composite sub-tree Liu Ping Fan
2012-08-24  9:49 ` [Qemu-devel] [PATCH 05/10] qdev: finalize of qbus, qdev will not the right place to free children Liu Ping Fan
2012-08-24 14:50   ` Paolo Bonzini
2012-08-24  9:49 ` [Qemu-devel] [PATCH 06/10] qom: expose object_property_del_child Liu Ping Fan
2012-08-24 14:44   ` Paolo Bonzini
2012-08-24  9:49 ` [Qemu-devel] [PATCH 07/10] unplug: using new intf qdev_delete_subtree in acpi_piix_eject_slot Liu Ping Fan
2012-08-24 10:24   ` Paolo Bonzini
2012-08-25  7:05     ` liu ping fan
2012-08-24  9:49 ` [Qemu-devel] [PATCH 08/10] qdev: rename qdev_unplug to qdev_unplug_req Liu Ping Fan
2012-08-24 14:48   ` Paolo Bonzini
2012-08-24  9:49 ` [Qemu-devel] [PATCH 09/10] mon: release dev's ref hold by qdev_get_peripheral Liu Ping Fan
2012-08-24  9:49 ` [Qemu-devel] [PATCH 10/10] qdev: fix create in place obj's life cycle problem Liu Ping Fan
2012-08-24 14:42   ` Paolo Bonzini
2012-08-25  7:42     ` liu ping fan
2012-08-27  7:01       ` Paolo Bonzini
2012-08-27  7:47         ` Jan Kiszka
2012-08-27  8:17           ` liu ping fan
2012-08-27  8:27             ` Jan Kiszka
2012-08-27 17:09           ` Avi Kivity
2012-08-27 17:14             ` Jan Kiszka
2012-08-27 18:09               ` Avi Kivity
2012-08-27 18:17                 ` Jan Kiszka
2012-08-27 18:20                   ` Avi Kivity
2012-08-27 18:39                     ` Jan Kiszka
2012-08-27 18:52                       ` Avi Kivity
2012-08-27 19:38                         ` Jan Kiszka
2012-08-27 20:53                           ` Avi Kivity
2012-08-28  1:01                             ` Jan Kiszka
2012-08-29 17:13                               ` Avi Kivity
2012-08-29 17:21                                 ` Jan Kiszka
2012-08-29 17:27                                   ` Avi Kivity
2012-08-29 17:41                                     ` Jan Kiszka
2012-09-03  9:09                                       ` Avi Kivity
2012-08-28  3:09                           ` liu ping fan
2012-08-28  3:38                             ` liu ping fan
2012-08-28  9:42                               ` Jan Kiszka
2012-08-28 10:05                                 ` Paolo Bonzini
2012-08-29 17:23                                 ` Avi Kivity
2012-08-29 17:30                                   ` Jan Kiszka
2012-08-29 17:40                                     ` Avi Kivity
2012-08-29 17:49                                       ` Jan Kiszka [this message]
2012-09-01  8:31                                         ` Avi Kivity
2012-09-01  8:57                                           ` Jan Kiszka
2012-09-01  9:30                                             ` Avi Kivity
2012-08-30  5:54                                       ` liu ping fan
2012-08-30  7:08                                         ` Jan Kiszka
2012-08-30  7:47                                           ` liu ping fan
2012-09-01  8:46                                           ` Avi Kivity
2012-09-03  7:44                                             ` liu ping fan
2012-09-03  8:52                                               ` Avi Kivity
2012-09-03 10:06                                                 ` liu ping fan
2012-09-03 10:16                                                   ` Avi Kivity
2012-09-04  2:33                                                     ` liu ping fan
2012-09-04  2:34                                                   ` liu ping fan
2012-09-05  8:19                                                     ` liu ping fan
2012-09-05  9:52                                                       ` Avi Kivity
2012-09-05 10:36                                                         ` Jan Kiszka
2012-09-05 10:53                                                           ` Avi Kivity
2012-09-05 11:11                                                             ` Jan Kiszka
2012-09-05 11:25                                                               ` Avi Kivity
2012-09-05 12:02                                                                 ` Jan Kiszka
2012-09-05 12:17                                                                   ` Avi Kivity
2012-08-27 13:19   ` Anthony Liguori
2012-08-27 15:02     ` Jan Kiszka
2012-08-27 15:14       ` Anthony Liguori
2012-08-27 15:26         ` Jan Kiszka
2012-08-27 16:24           ` Anthony Liguori
2012-08-27 16:59             ` Jan Kiszka
2012-08-27 18:35             ` Avi Kivity
2012-08-27 19:17               ` Anthony Liguori
2012-08-27 19:22                 ` Jan Kiszka
2012-08-27 20:58                 ` Avi Kivity
2012-08-27 21:34                   ` Paolo Bonzini
2012-08-27 18:27     ` Avi Kivity

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=503E5637.4040701@siemens.com \
    --to=jan.kiszka@siemens.com \
    --cc=anthony@codemonkey.ws \
    --cc=avi@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=pingfank@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemulist@gmail.com \
    /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).