WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [PATCH 2/2] PV framebuffer

To: Steven Smith <sos22@xxxxxxxxx>
Subject: Re: [Xen-devel] [PATCH 2/2] PV framebuffer
From: Markus Armbruster <armbru@xxxxxxxxxx>
Date: Thu, 16 Nov 2006 17:13:53 +0100
Cc: xen-devel@xxxxxxxxxxxxxxxxxxx, sos22@xxxxxxxxxxxxx
Delivery-date: Thu, 16 Nov 2006 08:14:03 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <87lkmciowj.fsf@xxxxxxxxxxxxxxxxx> (Markus Armbruster's message of "Wed, 15 Nov 2006 18:46:20 +0100")
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <87lkmjptqq.fsf@xxxxxxxxxxxxxxxxx> <20061112142045.GC2014@xxxxxxxxx> <87velijfet.fsf@xxxxxxxxxxxxxxxxx> <20061115121839.GB2001@xxxxxxxxx> <87lkmciowj.fsf@xxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)
Markus Armbruster <armbru@xxxxxxxxxx> writes:

> Steven Smith <sos22@xxxxxxxxx> writes:
>
> [...]
>>> >> +        if (xenfb_hotplug(xsh, vfb_backdir) < 0)
>>> >> +                goto error;
>>> >> +        if (xenfb_hotplug(xsh, vkbd_backdir) < 0)
>>> >> +                goto error;
>>> >> +
>>> >> +        if (xenfb_xs_printf(xsh, vkbd_backdir, "feature-abs-pointer", 
>>> >> "1"))
>>> >> +                goto error;
>>> >> +        if (xenfb_xs_printf(xsh, vfb_backdir, "state", "%d",
>>> >> +                            XenbusStateInitWait))
>>> >> +                goto error;
>>> >> +        if (xenfb_xs_printf(xsh, vkbd_backdir, "state", "%d",
>>> >> +                            XenbusStateInitWait))
>>> >> +                goto error;
>>> >> +
>>> > I'd probably reorder this a little to look more like this:
>>> >
>>> > (1) Set feature-abs-pointer
>>> > (2) Set state to InitWait
>>> > (3) Set hotplug status
>>> >
>>> > The only actual *required* constraint is (1) before (2), so that the
>>> > frontend doesn't initialise before we've set the feature and
>>> > potentially miss it.
>>> >
>>> > (2) before (3) is kind of nice, in that it makes sure that the backend
>>> > is ready before xend unpauses the domain, and so the frontend'll be
>>> > able to connect the first time it tries, but that's a lot less
>>> > important here than for e.g. block devices.
>>> Based on our previous discussions, I designed the startup protocol
>>> this way:
>>> 
>>>     backend                          frontend
>>>     ------------------------------------------------------------------
>>>     hotplug_status = connected
>>>     [makes xend populate xenstore, set fe and be state = Initialising]
>>>     wait for be state = Initialising
>>>       [i.e. wait for xend]
>>>     write xs: feature-abs-pointer    write xs: feature-update
>>>     be state = InitWait              fe state = Initialised
>>>     ------------------------------ sync ------------------------------
>>>     wait for fe state = Initialised  wait for be state = InitWait
>>>     ------------------------------ sync ------------------------------
>>>     read xs: feature-update          read xs: feature-abs-pointer
>>>     write xs: request-update         write xs: request-abs-pointer
>>>     be state = Connected             fe state = Connected
>>>     ------------------------------ sync ------------------------------
>>>     wait for fe state = Connected    wait for be state = Connected
>>>     ------------------------------ sync ------------------------------
>>>     read xs: request-abs-pointer     read xs: request-update
>>> 
>>> The symmetry made sense to me.
>> Ah, sorry, I wasn't clear enough.  You've got everything right after
>> the first sync line, but the bit before that isn't quite right.  Xend
>> creates xenstore area when the domain is created, and then waits until
>> hotplug-status is set before starting the domain running.  The idea is
>> that the backend driver should be watching its area of xenbus (so
>> /local/domain/0/backend/vif, say), so that it notices when the area is
>> created and creates the appropriate backend devices.  Creating the
>> backend devices triggers the hotplug scripts via some udev magic which
>> I've never quite understood, and they then e.g. connect vifs up to the
>> bridge.  Once they've finished, the backends are all ready, and so
>> it's safe to start the guest.  If you start the guest before the
>> backends are ready, you potentially have issues like your root
>> fileystem not becoming available until after the guest has booted,
>> which tends to make Linux unhappy.
>>
>> xend                         backend driver          hotplug scripts
>> Creates a new domain
>>      paused
>> Creates backend area
>>                              Notices new backend
>>                                      area, creates
>>                                      backend device
>>                              Does some basic setup
>>                                      on backend device
>>                              Go to state InitWait
>>                              Kicks udev
>>                                                      Does a bit more setup
>>                                                              on backend
>>                                                              device
>>                                                      Sets hotplug-status
>> Notices hotplug status,
>>      unpauses domain
>>
>> Now, the obvious mapping of this protocol onto the PVFB would have
>> xend create the xenstore area when the guest is created and spawn the
>> backend itself.  The backend could then set hotplug-status to indicate
>> that it's ready, which would unpause the guest and things would then
>> proceed in the usual way.
>
> I coded this, and it works.

Not quite.  I fear there's a race.

My xenkbd otherend_changed callback runs twice with backend_state ==
XenbusStateConnected instead of first with XenbusStateInitWait and
then with XenbusStateConnected.

Here's what I think happens.  First how backend, xend and frontend
synchronize:


    backend               xend                  frontend
    ------------------------------------------------------------------
                          create domain paused
                              create xenstore,
                          fe and be state =
                              Initialising
               ________ sync _______/
              /                                
    wait for be state                           
        Initialising
    write xs: feature-*                         
    be state = InitWait
    hotplug_status =                            
        connected                               
              \________ sync _______
                                    \          
                          wait for
                              hotplug_status
                                  connected
                          unpause domain
                                    \________ sync _______
                                                          \          
                                                write xs: feature-*
                                                fe state = Initialised
              \___________________ sync __________________/
              /                                           \
    wait for fe state                           wait for be state
        Initialised                                 InitWait
    read xs: feature-*                          read xs: feature-*
    write xs: request-*                         write xs: request-*
    be state = Connected                        fe state = Connected
              \___________________ sync __________________/
              /                                           \
    wait for fe state                           wait for be state
        Connected                                   Connected
    read xs: request-*                          read xs: request-*

Except the frontend doesn't actually wait for be state, it runs a
callback (otherend_changed) when the state changes.

Now, when the this callback in the frontend is delayed sufficiently,
the order of events could be:

    frontend                                    backend
    ------------------------------------------------------------------
                             [...]
    be state = InitWait
    hotplug_status =
        connected
                             [...]
                                                fe state = Initialised
    wait for fe state
        Initialised
        completes
    read xs: feature-*  
    write xs: request-* 
    be state = Connected
                                                otherend_changed runs
                                                    and sees be state
                                                       Connected
                                                    (actual trigger
                                                        was InitWait)
                                                otherend_changed runs
                                                    and sees be state
                                                       Connected

How do you want me to deal with this?

Note the funny code in drivers/xen/blkback/xenbus.c's
frontend_changed:

        case XenbusStateInitialised:
        case XenbusStateConnected:
                /* Ensure we connect even when two watches fire in 
                   close successsion and we miss the intermediate value 
                   of frontend_state. */

If this is the right thing to do there, why isn't it done elsewhere?

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