Re: [PATCH v6 04/24] PCI/sysfs: Use BAR length in pci_llseek_resource() when attr->size is zero

Bjorn Helgaas <[email protected]> Wed, 29 Apr 2026 14:50:55 -0500
Newsgroups org.kernel.vger.linux-alpha,org.kernel.vger.linux-pci,org.ozlabs.lists.linuxppc-dev
Message-ID <20260429195055.GA312811@bhelgaas>
On Wed, Apr 22, 2026 at 04:13:47PM +0000, Krzysztof Wilczyński wrote:
> Both legacy and resource attributes set .f_mapping = iomem_get_mapping,
> so the default generic_file_llseek() would consult iomem_inode for the
> file size, which knows nothing about the attribute.  That is why this
> custom llseek callback exists.
> 
> Currently, the legacy and resource attributes have .size set at creation
> time, as such, using the attr->size is sufficient.  However, the upcoming
> static resource attributes will have .size == 0 set, since they are const,
> and the .bin_size callback will be used to provide the real size to kernfs
> instead.
> 
> Thus, update pci_llseek_resource() to derive the file size from the
> BAR using pci_resource_len() instead of reading the attr->size directly.
> 
> The custom pci_llseek_resource() helper has been added in commit
> 24de09c16f97 ("PCI: Implement custom llseek for sysfs resource
> entries").
> 
> Signed-off-by: Krzysztof Wilczyński <[email protected]>
> ---
>  drivers/pci/pci-sysfs.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
> index 6783c6168445..73a9ae9d289b 100644
> --- a/drivers/pci/pci-sysfs.c
> +++ b/drivers/pci/pci-sysfs.c
> @@ -909,11 +909,21 @@ static const struct attribute_group pci_dev_config_attr_group = {
>   */
>  static __maybe_unused loff_t
>  pci_llseek_resource(struct file *filep,
> -		    struct kobject *kobj __always_unused,
> +		    struct kobject *kobj,
>  		    const struct bin_attribute *attr,
>  		    loff_t offset, int whence)
>  {
> -	return fixed_size_llseek(filep, offset, whence, attr->size);
> +	struct pci_dev *pdev;
> +	int bar;
> +
> +	if (attr->size)
> +		return fixed_size_llseek(filep, offset, whence, attr->size);
> +
> +	pdev = to_pci_dev(kobj_to_dev(kobj));
> +	bar = (unsigned long)attr->private;
> +
> +	return fixed_size_llseek(filep, offset, whence,
> +				 pci_resource_len(pdev, bar));

Is there a case where using "attr->size" is better than using
"pci_resource_len(pdev, bar)"?

In other words, would the following be equivalent?

  pci_llseek_resource(...)
  {
    ...
    pdev = to_pci_dev(kobj_to_dev(kobj));
    bar = (unsigned long)attr->private;

    return fixed_size_llseek(filep, offset, whence,
                             pci_resource_len(pdev, bar));
  }