[PATCH] drm/xe/pf: Restore TotalVFs
Michal Wajdeczko
michal.wajdeczko at intel.com
Wed Aug 7 10:05:43 UTC 2024
On 15.07.2024 19:40, Michal Wajdeczko wrote:
>
>
> On 15.07.2024 19:09, Lucas De Marchi wrote:
>> On Mon, Jul 15, 2024 at 01:40:52PM GMT, Michal Wajdeczko wrote:
>>> If we update TotalVFs to a new value and fail the .probe() then
>>> the PCI subsystem will not restore original value, which might
>>> impact next .probe() attempt. As a backup plan, use managed action
>>> to restore it ourselves.
>>>
>>> Signed-off-by: Michal Wajdeczko <michal.wajdeczko at intel.com>
>>> Cc: Piotr Piórkowski <piotr.piorkowski at intel.com>
>>> ---
>>> Attempt to fix that at PCI layer is here [1], but until it will be
>>> available for us, we can still fix that on our side.
>>>
>>> [1]
>>> https://lore.kernel.org/linux-pci/20240715102835.1286-1-michal.wajdeczko@intel.com/
>>
>> I don't think we should merge this while that is pending with no reply.
>> If that is not accepted, then we can think about doing this.
>
> fair enough, but idea was to have it little sooner so it will help Piotr
> with his quite frequent issue
3 weeks passed and there is still no reply on [1]
can we move on with this local fix instead?
>
>>
>>> ---
>>> drivers/gpu/drm/xe/xe_sriov_pf.c | 48 +++++++++++++++++++++++++++-----
>>> 1 file changed, 41 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/xe/xe_sriov_pf.c
>>> b/drivers/gpu/drm/xe/xe_sriov_pf.c
>>> index 0f721ae17b26..d61933770f1c 100644
>>> --- a/drivers/gpu/drm/xe/xe_sriov_pf.c
>>> +++ b/drivers/gpu/drm/xe/xe_sriov_pf.c
>>> @@ -17,12 +17,40 @@ static unsigned int wanted_max_vfs(struct
>>> xe_device *xe)
>>> return xe_modparam.max_vfs;
>>> }
>>>
>>> -static int pf_reduce_totalvfs(struct xe_device *xe, int limit)
>>> +static void restore_totalvfs(void *arg)
>>> +{
>>> + struct xe_device *xe = arg;
>>> + struct device *dev = xe->drm.dev;
>>> + struct pci_dev *pdev = to_pci_dev(dev);
>>> + int totalvfs = xe->sriov.pf.device_total_vfs;
>>> +
>>> + xe_sriov_dbg_verbose(xe, "restoring totalvfs to %d\n", totalvfs);
>>> + pci_sriov_set_totalvfs(pdev, totalvfs);
>>> +}
>>> +
>>> +static int pf_reduce_totalvfs(struct xe_device *xe, u16 limit)
>>
>> ^^^^^^
>>
>> so the current logic assumes the maximum comes from BIOS, but it could
>> rather come from a previous (failed) driver load? once we set the value
>> is the information lost from the device or can we recover it from
>> somewhere?
>> somewhere != where we saved in the this driver.
>
> PCI layer keeps the original value read from the device PCI config space
> and currently restores it only on .remove but not after failed .probe
>
> [2] https://elixir.bootlin.com/linux/latest/source/drivers/pci/iov.c#L934
>
> lucky for us, we already were caching this original value for debugfs
> reporting, so it's quite easy to restore it by ourselves
>
>>
>>
>>> {
>>> struct device *dev = xe->drm.dev;
>>> struct pci_dev *pdev = to_pci_dev(dev);
>>> int err;
>>>
>>> + xe->sriov.pf.device_total_vfs = pci_sriov_get_totalvfs(pdev);
>>> + xe->sriov.pf.driver_max_vfs = limit;
>>> +
>>> + xe_sriov_dbg_verbose(xe, "reducing totalvfs from %u to %u\n",
>>> + xe->sriov.pf.device_total_vfs,
>>> + xe->sriov.pf.driver_max_vfs);
>>> +
>>> + /*
>>> + * XXX: If we update TotalVFs to a new value and fail the .probe()
>>
>> why XXX?
>
> as only this chunk (comment/call) could be removed when [1] lands on our
> tree, but even if it stays it will be harmless
>
>>
>>> + * then the PCI subsystem might not restore original TotalVFs value,
>>> + * which might impact next .probe() attempt. As a backup plan, use
>>> + * managed action to restore it ourselves.
>>> + *
>>> + * Note that it's not critical if registering that action fails.
>>> + */
>>> + devm_add_action(xe->drm.dev, restore_totalvfs, xe);
>>> +
>>> err = pci_sriov_set_totalvfs(pdev, limit);
>>> if (err)
>>> xe_sriov_notice(xe, "Failed to set number of VFs to %d (%pe)\n",
>>> @@ -37,6 +65,14 @@ static bool pf_continue_as_native(struct xe_device
>>> *xe, const char *why)
>>> return false;
>>> }
>>>
>>> +static bool pf_continue_ready(struct xe_device *xe, u16 max_vfs)
>>> +{
>>> + xe_assert(xe, max_vfs > 0);
>>> + xe_sriov_dbg(xe, "preparing for %u VF%s\n", max_vfs,
>>> str_plural(max_vfs));
>>> + pf_reduce_totalvfs(xe, max_vfs);
>>> + return true;
>>
>> what's the point of splitting this function that always return true? I'd
>> rather leave it where it was
>
> I've moved statements to store device_total_vfs & driver_max_vfs to
> pf_reduce_totalvfs() so below function is now just a _dispatcher_ and
> this function name also acts a self-comment
>
>>
>> Lucas De Marchi
>>
>>> +}
>>> +
>>> /**
>>> * xe_sriov_pf_readiness - Check if PF functionality can be enabled.
>>> * @xe: the &xe_device to check
>>> @@ -58,18 +94,16 @@ bool xe_sriov_pf_readiness(struct xe_device *xe)
>>> if (!dev_is_pf(dev))
>>> return false;
>>>
>>> + if (!totalvfs)
>>> + return pf_continue_as_native(xe, "no VFs reported");
>>> +
>>> if (!xe_device_uc_enabled(xe))
>>> return pf_continue_as_native(xe, "Guc submission disabled");
>>>
>>> if (!newlimit)
>>> return pf_continue_as_native(xe, "all VFs disabled");
>>>
>>> - pf_reduce_totalvfs(xe, newlimit);
>>> -
>>> - xe->sriov.pf.device_total_vfs = totalvfs;
>>> - xe->sriov.pf.driver_max_vfs = newlimit;
>>> -
>>> - return true;
>>> + return pf_continue_ready(xe, newlimit);
>>> }
>>>
>>> /**
>>> --
>>> 2.43.0
>>>
More information about the Intel-xe
mailing list