Re: [PATCH RFC UNTESTED] vfio-ccw: indirect access to translated cps

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

 



On Tue, 30 Jul 2019 17:49:10 +0200
Halil Pasic <pasic@xxxxxxxxxxxxx> wrote:

> On Fri, 26 Jul 2019 12:06:17 +0200
> Cornelia Huck <cohuck@xxxxxxxxxx> wrote:
> 
> > We're currently keeping a single area for translated channel
> > programs in our private structure, which is filled out when
> > we are translating a channel program we have been given by
> > user space and marked invalid again when we received an final
> > interrupt for that I/O.
> > 
> > Unfortunately, properly tracking the lifetime of that cp is
> > not easy: failures may happen during translation or right when
> > it is sent to the hardware, unsolicited interrupts may trigger
> > a deferred condition code, a halt/clear request may be issued
> > while the I/O is supposed to be running, or a reset request may
> > come in from the side. The _PROCESSING state and the ->initialized
> > flag help a bit, but not enough.
> > 
> > We want to have a way to figure out whether we actually have a cp
> > currently in progress, so we can update/free only when applicable.
> > Points to keep in mind:
> > - We will get an interrupt after a cp has been submitted iff ssch
> >   finished with cc 0.
> > - We will get more interrupts for a cp if the interrupt status is
> >   not final.
> > - We can have only one cp in flight at a time.
> > 
> > Let's decouple the actual area in the private structure from the
> > means to access it: Only after we have successfully submitted a
> > cp (ssch with cc 0), update the pointer in the private structure
> > to point to the area used. Therefore, the interrupt handler won't
> > access the cp if we don't actually expect an interrupt pertaining
> > to it.
> > 
> > Signed-off-by: Cornelia Huck <cohuck@xxxxxxxxxx>
> > ---
> > 
> > Just hacked this up to get some feedback, did not actually try it
> > out. Not even sure if this is a sensible approach; if not, let's
> > blame it on the heat and pretend it didn't happen :)
> >   
> 
> Do not multiple threads access this new cp pointer (and at least one of
> them writes)? If that is the case, it smells like a data race to me.

We might need some additional concurrent read/write handling on top, if
state machine guarantees are not enough. (We may need a respin of the
state machine locking for that, which we probably want anyway.)

> 
> Besides the only point of converting cp to a pointer seems to be
> policing access to cp_area (which used to be cp). I.e. if it is
> NULL: don't touch it, otherwise: go ahead. We can do that with a single
> bit, we don't need a pointer for that.

The idea was
- do translation etc. on an area only accessed by the thread doing the
  translation
- switch the pointer to that area once the cp has been submitted
  successfully (and it is therefore associated with further interrupts
  etc.)
The approach in this patch is probably a bit simplistic.

I think one bit is not enough, we have at least three states:
- idle; start using the area if you like
- translating; i.e. only the translator is touching the area, keep off
- submitted; we wait for interrupts, handle them or free if no (more)
  interrupts can happen

> 
> Could we convert initialized into some sort of cp.status that
> tracks/controls access and responsibilities? By working with bits we
> could benefit from the atomicity of bit-ops -- if I'm not wrong.

We have both the state of the device (state machine) and the state of a
cp, then. If we keep to a single cp area, we should track that within a
single state (i.e. the device state).

> 
> > I also thought about having *two* translation areas and switching
> > the pointer between them; this might be too complicated, though?  
> 
> We only have one channel program at a time or? I can't see the benefit
> of having two areas.

We can only have one in flight at a time; we could conceivably have
another one that is currently in the process of being built. The idea
was to switch between the two (so processing an in-flight one cannot
overwrite one that is currently being built); but I think this is too
complicated.



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux