
在 2018/9/11 下午8:05, Andrea Bolognani 写道:
On Tue, 2018-09-04 at 16:39 +0800, Yi Min Zhao wrote: [...]
+static int +virZPCIDeviceAddressIsValid(virZPCIDeviceAddressPtr zpci) This is a predicate, so it should return a bool. OK.
[...]
+ virReportError(VIR_ERR_XML_ERROR, + _("Invalid PCI address uid='0x%x', " + "must be > 0x0 and <= 0x%x"), + zpci->uid, + VIR_DOMAIN_DEVICE_ZPCI_MAX_UID); You should always use "0x%.4x" when printing uids. ditto
[...]
+static int +virZPCIDeviceAddressParseXML(xmlNodePtr node, + virPCIDeviceAddressPtr addr) +{ + char *uid, *fid; + int ret = -1; + virZPCIDeviceAddress def = { 0 }; One variable per line, please.
Also structs are usually declared first and 'ret' is usually last, but that's admittedly not very important :) ditto. I'm very glad that you could give me so many valuable comments even if it's just about code style.
[...]
+ if (uid) { + if (virStrToLong_uip(uid, NULL, 0, &def.uid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'uid' attribute")); + goto cleanup; + } + } You can convert the above to
if (uid && virStrToLong_uip(...) < 0) { ... }
and do the same with fid. OK.
+bool +virZPCIDeviceAddressIsEmpty(const virZPCIDeviceAddress *addr) +{ + return !(addr->uid || addr->fid); +} This function belongs in virpci, besides the struct definition and
[...] the very much related virPCIDeviceAddressIsEmpty(). I'm not very clear with your comment. Do you mean I should move it to other place?
[...]
@@ -267,6 +333,9 @@ virPCIDeviceAddressParseXML(xmlNodePtr node, if (!virPCIDeviceAddressIsEmpty(addr) && !virPCIDeviceAddressIsValid(addr, true)) goto cleanup;
+ if (virZPCIDeviceAddressParseXML(node, addr) < 0) + goto cleanup; I'm not super convinced about this.
On one hand, it makes it so callers can't possibly forget to parse the zPCI part, and that's literally embedded in the PCI part now; on the other hand, we have functions to verify separately whether the PCI and zPCI parts are empty, which is pretty weird. It's weird indeed. But if we merge zPCI part check into PCI code. We might have to merge other code. But PCI address has extension only on S390 at least now.
I guess we can leave as it is for now, but the semantics are muddy enough that I can pretty much guarantee someone will have to clean them up at some point down the line. OK.
[...]
@@ -1044,6 +1044,9 @@ virDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs, dev->isolationGroup, function) < 0) return -1;
+ if (dev->pciAddressExtFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) + addr.zpci = dev->addr.pci.zpci; I'm confused by this part. Shouldn't this either request a new set of zPCI ids, the same way it's allocating a new PCI address right above, or do nothing at all because zPCI address allocation is handled by later calling virDomainZPCIAddressReserveNextAddr()? Here, we want to store the defined zPCI address which has been reserved. If we don't do this, we might lose zPCI address and do reservation again but the reserved one are still existing in zPCI set.
For this problem, I once thought about adding extension address into DeviceInfo next to PCI address embraced in a struct. Then here is not a problem.
This is basically another manifestation of the issue I mentioned above: we don't seem to have a well-defined and strictly adhered to idea of how the PCI part and zPCI part should relate to each other, so they're either considered separate entities or part of the same entity depending on which APIs you're looking at.
I think the above idea I thought about before is like what you said?
[...]
+ if (!virZPCIDeviceAddressIsEmpty(&info->addr.pci.zpci)) { + virBufferAsprintf(buf, " uid='0x%.4x'", + info->addr.pci.zpci.uid); + virBufferAsprintf(buf, " fid='0x%.8x'", + info->addr.pci.zpci.fid); You only need a single call to virBufferAsprintf() here.
OK. -- Yi Min