[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH]Fix a restored domain cannot use mouse and keyboard



SUZUKI Kazuhiro <kaz@xxxxxxxxxxxxxx> writes:

> Hi,
>
> Sorry for my late reply.
>
> Qemu generates(produces) events to the event channel but no event on
> it are processed during save.
>
> When a domain is restored, pending events and selectors are cleared
> as follows in tools/libxc/xc_domain_restore.c.
>
>   1125            /* clear any pending events and the selector */
>   1126            MEMSET_ARRAY_FIELD(new_shared_info, evtchn_pending, 0);
>   1127            for ( i = 0; i < MAX_VIRT_CPUS; i++ )
>   1128                    SET_FIELD(new_shared_info, 
> vcpu_info[i].evtchn_pending_sel, 0);
>
> So it processes(consumes) no pending event on the event channel and
> page->in_cons doesn't increase.
>
> Qemu has the following code in tools/ioemu/hw/xenfb.c.
>
>    568                prod = page->in_prod;
>    569                if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
>    570                        errno = EAGAIN;
>    571                        return -1;
>    572                }
>
> If the ring buffer fills up to (prod - page->in_cons ==
> XENKBD_IN_RING_LEN), then no event notifications go to the event
> channel.
>
> Thanks.
> KAZ

Let me paraphrase to make sure I understand:

* Backend (qemu) produces events into xenkbd in ring and signals
  frontend through the event channel.

* Frontend (vkbd driver) consumes events from xenkbd ring when it gets
  signalled through the event channel.

* At some time, the frontend stops doing that, and the ring starts
  filling up.  The event is pending to signal the ring is not empty.

* The frontend's domain is restored, and any pending events are
  cleared.

  If the event was pending, we're now in an unhealthy state: the ring
  buffer is not empty, but the event doesn't signal that.

  The event remains clear until the backend produces or consumes
  another event.  Since the frontend never produces events, the latter
  can't happen.  If the ring buffer is completely full when the event
  gets cleared, the former can't happen until the frontend consumes an
  event.

* The frontend resumes.

  It consumes events from xenkbd ring when it gets signalled through
  the event channel.

  If the ring buffer was completely full when the event got cleared on
  restore, we're deadlocked: the backend can't produce until the
  frontend consumed, and the frontend doesn't consume until the
  backend produced.

Is this correct?


I'm not sure your fix is completely safe.  Once the frontend exposed
the shared page to the backend, it is not supposed to touch in_prod
and out_cons, and it may only increase in_cons and out_prod.  I think
you better do

        xenkbd_disconnect_backend(info);
+       info->page->in_cons = info->page->in_prod;
        return xenkbd_connect_backend(dev, info);

Instead of discarding in events, you could perhaps run input_handler()
to consume them.  Not sure that makes sense.

You simply can't discard out events here safely.  Academic, since the
xenkbd frontend never produces any.


Note that xenfb.c has exactly the same problems.  But there, the in
event bug doesn't bite, because the backend never produces any.  It
should be fixed anyway.  And the out event issue is not academic, as
xenfb frontend does produce them.

It's an issue only if the event signalling ring buffer not empty to
the *backend* gets cleared on restore.  Does it?

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.