<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Yan Zhao <<a href="mailto:yan.y.zhao@intel.com">yan.y.zhao@intel.com</a>> 于2020年7月15日周三 下午4:32写道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Tue, Jul 14, 2020 at 02:59:48PM -0600, Alex Williamson wrote:<br>
> On Tue, 14 Jul 2020 18:19:46 +0100<br>
> "Dr. David Alan Gilbert" <<a href="mailto:dgilbert@redhat.com" target="_blank">dgilbert@redhat.com</a>> wrote:<br>
> <br>
> > * Alex Williamson (<a href="mailto:alex.williamson@redhat.com" target="_blank">alex.williamson@redhat.com</a>) wrote:<br>
> > > On Tue, 14 Jul 2020 11:21:29 +0100<br>
> > > Daniel P. Berrangé <<a href="mailto:berrange@redhat.com" target="_blank">berrange@redhat.com</a>> wrote:<br>
> > >   <br>
> > > > On Tue, Jul 14, 2020 at 07:29:57AM +0800, Yan Zhao wrote:  <br>
> > > > > hi folks,<br>
> > > > > we are defining a device migration compatibility interface that helps upper<br>
> > > > > layer stack like openstack/ovirt/libvirt to check if two devices are<br>
> > > > > live migration compatible.<br>
> > > > > The "devices" here could be MDEVs, physical devices, or hybrid of the two.<br>
> > > > > e.g. we could use it to check whether<br>
> > > > > - a src MDEV can migrate to a target MDEV,<br>
> > > > > - a src VF in SRIOV can migrate to a target VF in SRIOV,<br>
> > > > > - a src MDEV can migration to a target VF in SRIOV.<br>
> > > > >   (e.g. SIOV/SRIOV backward compatibility case)<br>
> > > > > <br>
> > > > > The upper layer stack could use this interface as the last step to check<br>
> > > > > if one device is able to migrate to another device before triggering a real<br>
> > > > > live migration procedure.<br>
> > > > > we are not sure if this interface is of value or help to you. please don't<br>
> > > > > hesitate to drop your valuable comments.<br>
> > > > > <br>
> > > > > <br>
> > > > > (1) interface definition<br>
> > > > > The interface is defined in below way:<br>
> > > > > <br>
> > > > >              __    userspace<br>
> > > > >               /\              \<br>
> > > > >              /                 \write<br>
> > > > >             / read              \<br>
> > > > >    ________/__________       ___\|/_____________<br>
> > > > >   | migration_version |     | migration_version |-->check migration<br>
> > > > >   ---------------------     ---------------------   compatibility<br>
> > > > >      device A                    device B<br>
> > > > > <br>
> > > > > <br>
> > > > > a device attribute named migration_version is defined under each device's<br>
> > > > > sysfs node. e.g. (/sys/bus/pci/devices/0000\:00\:02.0/$mdev_UUID/migration_version).<br>
> > > > > userspace tools read the migration_version as a string from the source device,<br>
> > > > > and write it to the migration_version sysfs attribute in the target device.<br>
> > > > > <br>
> > > > > The userspace should treat ANY of below conditions as two devices not compatible:<br>
> > > > > - any one of the two devices does not have a migration_version attribute<br>
> > > > > - error when reading from migration_version attribute of one device<br>
> > > > > - error when writing migration_version string of one device to<br>
> > > > >   migration_version attribute of the other device<br>
> > > > > <br>
> > > > > The string read from migration_version attribute is defined by device vendor<br>
> > > > > driver and is completely opaque to the userspace.<br>
> > > > > for a Intel vGPU, string format can be defined like<br>
> > > > > "parent device PCI ID" + "version of gvt driver" + "mdev type" + "aggregator count".<br>
> > > > > <br>
> > > > > for an NVMe VF connecting to a remote storage. it could be<br>
> > > > > "PCI ID" + "driver version" + "configured remote storage URL"<br>
> > > > > <br>
> > > > > for a QAT VF, it may be<br>
> > > > > "PCI ID" + "driver version" + "supported encryption set".<br>
> > > > > <br>
> > > > > (to avoid namespace confliction from each vendor, we may prefix a driver name to<br>
> > > > > each migration_version string. e.g. i915-v1-8086-591d-i915-GVTg_V5_8-1)  <br>
> > > <br>
> > > It's very strange to define it as opaque and then proceed to describe<br>
> > > the contents of that opaque string.  The point is that its contents<br>
> > > are defined by the vendor driver to describe the device, driver version,<br>
> > > and possibly metadata about the configuration of the device.  One<br>
> > > instance of a device might generate a different string from another.<br>
> > > The string that a device produces is not necessarily the only string<br>
> > > the vendor driver will accept, for example the driver might support<br>
> > > backwards compatible migrations.  <br>
> > <br>
> > (As I've said in the previous discussion, off one of the patch series)<br>
> > <br>
> > My view is it makes sense to have a half-way house on the opaqueness of<br>
> > this string; I'd expect to have an ID and version that are human<br>
> > readable, maybe a device ID/name that's human interpretable and then a<br>
> > bunch of other cruft that maybe device/vendor/version specific.<br>
> > <br>
> > I'm thinking that we want to be able to report problems and include the<br>
> > string and the user to be able to easily identify the device that was<br>
> > complaining and notice a difference in versions, and perhaps also use<br>
> > it in compatibility patterns to find compatible hosts; but that does<br>
> > get tricky when it's a 'ask the device if it's compatible'.<br>
> <br>
> In the reply I just sent to Dan, I gave this example of what a<br>
> "compatibility string" might look like represented as json:<br>
> <br>
> {<br>
>   "device_api": "vfio-pci",<br>
>   "vendor": "vendor-driver-name",<br>
>   "version": {<br>
>     "major": 0,<br>
>     "minor": 1<br>
>   },<br>
>   "vfio-pci": { // Based on above device_api<br>
>     "vendor": 0x1234, // Values for the exposed device<br>
>     "device": 0x5678,<br>
>       // Possibly further parameters for a more specific match<br>
>   },<br>
>   "mdev_attrs": [<br>
>     { "attribute0": "VALUE" }<br>
>   ]<br>
> }<br>
> <br>
> Are you thinking that we might allow the vendor to include a vendor<br>
> specific array where we'd simply require that both sides have matching<br>
> fields and values?  ie.<br>
> <br>
>   "vendor_fields": [<br>
>     { "unknown_field0": "unknown_value0" },<br>
>     { "unknown_field1": "unknown_value1" },<br>
>   ]<br>
> <br>
> We could certainly make that part of the spec, but I can't really<br>
> figure the value of it other than to severely restrict compatibility,<br>
> which the vendor could already do via the version.major value.  Maybe<br>
> they'd want to put a build timestamp, random uuid, or source sha1 into<br>
> such a field to make absolutely certain compatibility is only determined<br>
> between identical builds?  Thanks,<br>
><br>
Yes, I agree kernel could expose such sysfs interface to educate<br>
openstack how to filter out devices. But I still think the proposed<br>
migration_version (or rename to migration_compatibility) interface is<br>
still required for libvirt to do double check.<br>
<br>
In the following scenario: <br>
1. openstack chooses the target device by reading sysfs interface (of json<br>
format) of the source device. And Openstack are now pretty sure the two<br>
devices are migration compatible.<br>
2. openstack asks libvirt to create the target VM with the target device<br>
and start live migration.<br>
3. libvirt now receives the request. so it now has two choices:<br>
(1) create the target VM & target device and start live migration directly<br>
(2) double check if the target device is compatible with the source<br>
device before doing the remaining tasks.<br>
<br>
Because the factors to determine whether two devices are live migration<br>
compatible are complicated and may be dynamically changing, (e.g. driver<br>
upgrade or configuration changes), and also because libvirt should not<br>
totally rely on the input from openstack, I think the cost for libvirt is<br>
relatively lower if it chooses to go (2) than (1). At least it has no<br>
need to cancel migration and destroy the VM if it knows it earlier.<br></blockquote><div><br></div><div>If the driver upgrade or configuration changes, I guess there should be a restart of openstack agent on the host, that will update the info to the scheduler.</div><div>so it should be fine.</div><div><br></div><div>For (2), probably it need be used for double check when the orchestration layer doesn't implement the check logic in the scheduler.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
So, it means the kernel may need to expose two parallel interfaces:<br>
(1) with json format, enumerating all possible fields and comparing<br>
methods, so as to indicate openstack how to find a matching target device<br>
(2) an opaque driver defined string, requiring write and test in target,<br>
which is used by libvirt to make sure device compatibility, rather than<br>
rely on the input accurateness from openstack or rely on kernel driver<br>
implementing the compatibility detection immediately after migration<br>
start.<br>
<br>
Does it make sense?<br>
<br>
Thanks<br>
Yan<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</blockquote></div></div>