|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v7 1/2] xen/pci: introduce PF<->VF links
On 11/14/24 05:34, Jan Beulich wrote:
> On 12.11.2024 21:53, Stewart Hildebrand wrote:
>> Add links between a VF's struct pci_dev and its associated PF struct
>> pci_dev.
>>
>> The hardware domain is expected to add a PF first before adding
>> associated VFs. Similarly, the hardware domain is expected to remove the
>> associated VFs before removing the PF. If adding/removing happens out of
>> order, print a warning and return an error. This means that VFs can only
>> exist with an associated PF.
>>
>> Additionally, if the hardware domain attempts to remove a PF with VFs
>> still present, mark the PF and VFs broken, because Linux Dom0 has been
>> observed to not respect the error returned.
>>
>> Move the call to pci_get_pdev() down to avoid dropping and re-acquiring
>> the pcidevs_lock(). Drop the call to pci_add_device() as it is invalid
>> to add a VF without an existing PF.
>>
>> Signed-off-by: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
>
> I'm okay with this, so in principle
> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
Thanks, I very much appreciate it! However, is it appropriate for me to
pick up this tag considering the requested/proposed changes?
> A few comments nevertheless, which may result in there wanting to be
> another revision.
I'll plan to send v8. There were some minor comments from Roger on the
removed snippet that I will also address, and I have another proposed
change.
>> ---
>> Candidate for backport to 4.19 (the next patch depends on this one)
>
> With this dependency (we definitely want to backport the other patch) ...
>
>> v6->v7:
>> * cope with multiple invocations of pci_add_device for VFs
>> * get rid of enclosing struct for single member
>> * during PF removal attempt with VFs still present:
>> * keep PF
>> * mark broken
>> * don't unlink
>> * return error
>> * during VF add:
>> * initialize pf_pdev in declaration
>> * remove logic catering to adding VFs without PF
>
> ... I'd like to point out that this change has an at least theoretical
> risk of causing regressions. I therefore wonder whether that wouldn't
> better be a separate change, not to be backported.
That makes sense. I'll split it into a separate patch for the next rev.
>> @@ -703,7 +696,38 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
>> * extended function.
>> */
>> if ( pdev->info.is_virtfn )
>> - pdev->info.is_extfn = pf_is_extfn;
>> + {
>> + struct pci_dev *pf_pdev = pci_get_pdev(NULL,
>> + PCI_SBDF(seg,
>> + info->physfn.bus,
>> +
>> info->physfn.devfn));
BTW, since I'm spinning another rev anyway, are there any opinions on
the indentation here?
>> + struct pci_dev *vf_pdev;
>
> const?
Yes, if it's still needed
>> + bool already_added = false;
>> +
>> + if ( !pf_pdev )
>> + {
>> + printk(XENLOG_WARNING
>> + "Attempted to add SR-IOV device VF %pp without PF
>> %pp\n",
>
> I'd omit "device" here.
OK
> (These changes alone I'd be happy to do while committing.)
I'll include the changes in v8.
>> + &pdev->sbdf,
>> + &PCI_SBDF(seg, info->physfn.bus,
>> info->physfn.devfn));
>> + free_pdev(pseg, pdev);
>> + ret = -ENODEV;
>> + goto out;
>> + }
>> +
>> + pdev->info.is_extfn = pf_pdev->info.is_extfn;
>
> There's a comment related to this, partly visible in patch context above.
> That comment imo needs moving here. And correcting while moving (it's
> inverted imo, or at least worded ambiguously).
I'll move it. As far as wording goes, I suggest:
/*
* PF's 'is_extfn' field indicates whether the VF is an extended
* function.
*/
>> + pdev->pf_pdev = pf_pdev;
>> + list_for_each_entry(vf_pdev, &pf_pdev->vf_list, vf_list)
>> + {
>> + if ( vf_pdev == pdev )
>> + {
>> + already_added = true;
>> + break;
>> + }
>> + }
>> + if ( !already_added )
>> + list_add(&pdev->vf_list, &pf_pdev->vf_list);
>> + }
>> }
>
> Personally, as I have a dislike for excess variables, I'd have gotten away
> without "already_added". Instead of setting it to true, vf_pdev could be
> set to NULL. Others may, however, consider this "obfuscation" or alike.
This relies on vf_pdev being set to non-NULL when the list is empty and
after the last iteration if the list doesn't contain the element. I had
to look up the definitions of list_for_each_entry, INIT_LIST_HEAD, and
list_{add,del,entry} to verify that vf_pdev would be non-NULL in those
cases.
Perhaps a better approach would be to introduce list_add_unique() in
Xen's list library? Then we can also get rid of the vf_pdev variable.
static inline bool list_contains(struct list_head *entry,
struct list_head *head)
{
struct list_head *ptr;
list_for_each(ptr, head)
{
if ( ptr == entry )
return true;
}
return false;
}
static inline void list_add_unique(struct list_head *new,
struct list_head *head)
{
if ( !list_contains(new, head) )
list_add(new, head);
}
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |