diff mbox series

[v3,03/14] PCI: Use sysfs_emit() and sysfs_emit_at() in "show" functions

Message ID 20210518034109.158450-3-kw@linux.com (mailing list archive)
State Superseded
Delegated to: Bjorn Helgaas
Headers show
Series [v3,01/14] PCI: Use sysfs_emit() and sysfs_emit_at() in "show" functions | expand

Commit Message

Krzysztof Wilczyński May 18, 2021, 3:40 a.m. UTC
The sysfs_emit() and sysfs_emit_at() functions were introduced to make
it less ambiguous which function is preferred when writing to the output
buffer in a device attribute's "show" callback [1].

Convert the PCI sysfs object "show" functions from sprintf(), snprintf()
and scnprintf() to sysfs_emit() and sysfs_emit_at() accordingly, as the
latter is aware of the PAGE_SIZE buffer and correctly returns the number
of bytes written into the buffer.

Modify the function dsm_label_utf16s_to_utf8s() to directly return the
number of bytes written into the buffer so that the strlen() used later
to calculate the length of the buffer can be removed as it would no
longer be needed.

No functional change intended.

[1] Documentation/filesystems/sysfs.rst

Related to:
  commit ad025f8e46f3 ("PCI/sysfs: Use sysfs_emit() and sysfs_emit_at() in "show" functions")

Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
---
Changes in v2:
  None.
Changes in v3:
  Added Logan Gunthorpe's "Reviewed-by".
  Change style to the preferred one in the drivers/pci/slot.c file.

 drivers/pci/pci-label.c | 18 ++++++++++--------
 drivers/pci/slot.c      | 18 +++++++++---------
 2 files changed, 19 insertions(+), 17 deletions(-)

Comments

Bjorn Helgaas May 24, 2021, 9:14 p.m. UTC | #1
On Tue, May 18, 2021 at 03:40:58AM +0000, Krzysztof Wilczyński wrote:
> The sysfs_emit() and sysfs_emit_at() functions were introduced to make
> it less ambiguous which function is preferred when writing to the output
> buffer in a device attribute's "show" callback [1].
> 
> Convert the PCI sysfs object "show" functions from sprintf(), snprintf()
> and scnprintf() to sysfs_emit() and sysfs_emit_at() accordingly, as the
> latter is aware of the PAGE_SIZE buffer and correctly returns the number
> of bytes written into the buffer.
> 
> Modify the function dsm_label_utf16s_to_utf8s() to directly return the
> number of bytes written into the buffer so that the strlen() used later
> to calculate the length of the buffer can be removed as it would no
> longer be needed.
> 
> No functional change intended.
> 
> [1] Documentation/filesystems/sysfs.rst
> 
> Related to:
>   commit ad025f8e46f3 ("PCI/sysfs: Use sysfs_emit() and sysfs_emit_at() in "show" functions")
> 
> Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
> Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
> ---
> Changes in v2:
>   None.
> Changes in v3:
>   Added Logan Gunthorpe's "Reviewed-by".
>   Change style to the preferred one in the drivers/pci/slot.c file.
> 
>  drivers/pci/pci-label.c | 18 ++++++++++--------
>  drivers/pci/slot.c      | 18 +++++++++---------
>  2 files changed, 19 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
> index c32f3b7540e8..000e169c7197 100644
> --- a/drivers/pci/pci-label.c
> +++ b/drivers/pci/pci-label.c
> @@ -139,14 +139,17 @@ enum acpi_attr_enum {
>  	ACPI_ATTR_INDEX_SHOW,
>  };
>  
> -static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
> +static int dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
>  {
>  	int len;
> +
>  	len = utf16s_to_utf8s((const wchar_t *)obj->buffer.pointer,
>  			      obj->buffer.length,
>  			      UTF16_LITTLE_ENDIAN,
>  			      buf, PAGE_SIZE);
>  	buf[len] = '\n';
> +
> +	return len;
>  }
>  
>  static int dsm_get_label(struct device *dev, char *buf,
> @@ -154,7 +157,7 @@ static int dsm_get_label(struct device *dev, char *buf,
>  {
>  	acpi_handle handle = ACPI_HANDLE(dev);
>  	union acpi_object *obj, *tmp;
> -	int len = -1;
> +	int len = 0;
>  
>  	if (!handle)
>  		return -1;
> @@ -175,20 +178,19 @@ static int dsm_get_label(struct device *dev, char *buf,
>  		 * this entry must return a null string.
>  		 */
>  		if (attr == ACPI_ATTR_INDEX_SHOW) {
> -			scnprintf(buf, PAGE_SIZE, "%llu\n", tmp->integer.value);
> +			len = sysfs_emit(buf, "%llu\n", tmp->integer.value);
>  		} else if (attr == ACPI_ATTR_LABEL_SHOW) {
>  			if (tmp[1].type == ACPI_TYPE_STRING)
> -				scnprintf(buf, PAGE_SIZE, "%s\n",
> -					  tmp[1].string.pointer);
> +				len = sysfs_emit(buf, "%s\n",
> +						 tmp[1].string.pointer);
>  			else if (tmp[1].type == ACPI_TYPE_BUFFER)
> -				dsm_label_utf16s_to_utf8s(tmp + 1, buf);
> +				len = dsm_label_utf16s_to_utf8s(tmp + 1, buf);
>  		}
> -		len = strlen(buf) > 0 ? strlen(buf) : -1;
>  	}
>  
>  	ACPI_FREE(obj);
>  
> -	return len;
> +	return len > 0 ? len : -1;

I really like this, but I would like it even better if the
sysfs_emit() change were easier to review.

It seems pointless that the current code uses strlen() when
scnprintf() and dsm_label_utf16s_to_utf8s() both have that
information and we just throw it away.

I think it should be possible to split the len and
dsm_label_utf16s_to_utf8s() changes to a separate patch, which would
remove the need for the strlen, and then the conversion to
sysfs_emit() would be completely trivial like all the rest of them.

My goal is to make all the sysfs_emit() changes look almost
mechanical, with the non-trivial parts separated out.

>  }
>  
>  static ssize_t label_show(struct device *dev, struct device_attribute *attr,
> diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
> index d627dd9179b4..751a26668e3a 100644
> --- a/drivers/pci/slot.c
> +++ b/drivers/pci/slot.c
> @@ -39,19 +39,19 @@ static const struct sysfs_ops pci_slot_sysfs_ops = {
>  static ssize_t address_read_file(struct pci_slot *slot, char *buf)
>  {
>  	if (slot->number == 0xff)
> -		return sprintf(buf, "%04x:%02x\n",
> -				pci_domain_nr(slot->bus),
> -				slot->bus->number);
> -	else
> -		return sprintf(buf, "%04x:%02x:%02x\n",
> -				pci_domain_nr(slot->bus),
> -				slot->bus->number,
> -				slot->number);
> +		return sysfs_emit(buf, "%04x:%02x\n",
> +				  pci_domain_nr(slot->bus),
> +				  slot->bus->number);
> +
> +	return sysfs_emit(buf, "%04x:%02x:%02x\n",
> +			  pci_domain_nr(slot->bus),
> +			  slot->bus->number,
> +			  slot->number);
>  }
>  
>  static ssize_t bus_speed_read(enum pci_bus_speed speed, char *buf)
>  {
> -	return sprintf(buf, "%s\n", pci_speed_string(speed));
> +	return sysfs_emit(buf, "%s\n", pci_speed_string(speed));
>  }
>  
>  static ssize_t max_speed_read_file(struct pci_slot *slot, char *buf)
> -- 
> 2.31.1
>
Bjorn Helgaas May 24, 2021, 9:19 p.m. UTC | #2
On Mon, May 24, 2021 at 04:14:32PM -0500, Bjorn Helgaas wrote:
> On Tue, May 18, 2021 at 03:40:58AM +0000, Krzysztof Wilczyński wrote:
> > The sysfs_emit() and sysfs_emit_at() functions were introduced to make
> > it less ambiguous which function is preferred when writing to the output
> > buffer in a device attribute's "show" callback [1].
> > 
> > Convert the PCI sysfs object "show" functions from sprintf(), snprintf()
> > and scnprintf() to sysfs_emit() and sysfs_emit_at() accordingly, as the
> > latter is aware of the PAGE_SIZE buffer and correctly returns the number
> > of bytes written into the buffer.
> > 
> > Modify the function dsm_label_utf16s_to_utf8s() to directly return the
> > number of bytes written into the buffer so that the strlen() used later
> > to calculate the length of the buffer can be removed as it would no
> > longer be needed.
> > 
> > No functional change intended.
> > 
> > [1] Documentation/filesystems/sysfs.rst
> > 
> > Related to:
> >   commit ad025f8e46f3 ("PCI/sysfs: Use sysfs_emit() and sysfs_emit_at() in "show" functions")
> > 
> > Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
> > Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
> > ---
> > Changes in v2:
> >   None.
> > Changes in v3:
> >   Added Logan Gunthorpe's "Reviewed-by".
> >   Change style to the preferred one in the drivers/pci/slot.c file.
> > 
> >  drivers/pci/pci-label.c | 18 ++++++++++--------
> >  drivers/pci/slot.c      | 18 +++++++++---------
> >  2 files changed, 19 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
> > index c32f3b7540e8..000e169c7197 100644
> > --- a/drivers/pci/pci-label.c
> > +++ b/drivers/pci/pci-label.c
> > @@ -139,14 +139,17 @@ enum acpi_attr_enum {
> >  	ACPI_ATTR_INDEX_SHOW,
> >  };
> >  
> > -static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
> > +static int dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
> >  {
> >  	int len;
> > +
> >  	len = utf16s_to_utf8s((const wchar_t *)obj->buffer.pointer,
> >  			      obj->buffer.length,
> >  			      UTF16_LITTLE_ENDIAN,
> >  			      buf, PAGE_SIZE);
> >  	buf[len] = '\n';
> > +
> > +	return len;
> >  }
> >  
> >  static int dsm_get_label(struct device *dev, char *buf,
> > @@ -154,7 +157,7 @@ static int dsm_get_label(struct device *dev, char *buf,
> >  {
> >  	acpi_handle handle = ACPI_HANDLE(dev);
> >  	union acpi_object *obj, *tmp;
> > -	int len = -1;
> > +	int len = 0;
> >  
> >  	if (!handle)
> >  		return -1;
> > @@ -175,20 +178,19 @@ static int dsm_get_label(struct device *dev, char *buf,
> >  		 * this entry must return a null string.
> >  		 */
> >  		if (attr == ACPI_ATTR_INDEX_SHOW) {
> > -			scnprintf(buf, PAGE_SIZE, "%llu\n", tmp->integer.value);
> > +			len = sysfs_emit(buf, "%llu\n", tmp->integer.value);
> >  		} else if (attr == ACPI_ATTR_LABEL_SHOW) {
> >  			if (tmp[1].type == ACPI_TYPE_STRING)
> > -				scnprintf(buf, PAGE_SIZE, "%s\n",
> > -					  tmp[1].string.pointer);
> > +				len = sysfs_emit(buf, "%s\n",
> > +						 tmp[1].string.pointer);
> >  			else if (tmp[1].type == ACPI_TYPE_BUFFER)
> > -				dsm_label_utf16s_to_utf8s(tmp + 1, buf);
> > +				len = dsm_label_utf16s_to_utf8s(tmp + 1, buf);
> >  		}
> > -		len = strlen(buf) > 0 ? strlen(buf) : -1;
> >  	}
> >  
> >  	ACPI_FREE(obj);
> >  
> > -	return len;
> > +	return len > 0 ? len : -1;
> 
> I really like this, but I would like it even better if the
> sysfs_emit() change were easier to review.
> 
> It seems pointless that the current code uses strlen() when
> scnprintf() and dsm_label_utf16s_to_utf8s() both have that
> information and we just throw it away.
> 
> I think it should be possible to split the len and
> dsm_label_utf16s_to_utf8s() changes to a separate patch, which would
> remove the need for the strlen, and then the conversion to
> sysfs_emit() would be completely trivial like all the rest of them.
> 
> My goal is to make all the sysfs_emit() changes look almost
> mechanical, with the non-trivial parts separated out.

And BTW, when all the sysfs_emit() changes are trivial like that, I
would probably squash them all into one patch that converts all of
drivers/pci/ at once.

That would still leave a few separate patches:

  - This dsm_label_utf16s_to_utf8s() change
  - The resource_alignment newline change
  - The devspec_show newline change
  - The driver_override change
Krzysztof Wilczyński May 25, 2021, 10:32 a.m. UTC | #3
Hi Bjorn,

[...]
> > I really like this, but I would like it even better if the
> > sysfs_emit() change were easier to review.
> > 
> > It seems pointless that the current code uses strlen() when
> > scnprintf() and dsm_label_utf16s_to_utf8s() both have that
> > information and we just throw it away.
> > 
> > I think it should be possible to split the len and
> > dsm_label_utf16s_to_utf8s() changes to a separate patch, which would
> > remove the need for the strlen, and then the conversion to
> > sysfs_emit() would be completely trivial like all the rest of them.
> > 
> > My goal is to make all the sysfs_emit() changes look almost
> > mechanical, with the non-trivial parts separated out.
> 
> And BTW, when all the sysfs_emit() changes are trivial like that, I
> would probably squash them all into one patch that converts all of
> drivers/pci/ at once.
> 
> That would still leave a few separate patches:
> 
>   - This dsm_label_utf16s_to_utf8s() change
>   - The resource_alignment newline change
>   - The devspec_show newline change
>   - The driver_override change

Got it!  I will send v4 updated as per the above suggestion.  Also, if
Logan does not mind, I will carry his "Reviewed-by" over as there will
be no changes to the actual code, just how the patch will be arranged.

	Krzysztof
Logan Gunthorpe May 25, 2021, 4:07 p.m. UTC | #4
On 2021-05-25 4:32 a.m., Krzysztof Wilczyński wrote:
> Hi Bjorn,
> 
> [...]
>>> I really like this, but I would like it even better if the
>>> sysfs_emit() change were easier to review.
>>>
>>> It seems pointless that the current code uses strlen() when
>>> scnprintf() and dsm_label_utf16s_to_utf8s() both have that
>>> information and we just throw it away.
>>>
>>> I think it should be possible to split the len and
>>> dsm_label_utf16s_to_utf8s() changes to a separate patch, which would
>>> remove the need for the strlen, and then the conversion to
>>> sysfs_emit() would be completely trivial like all the rest of them.
>>>
>>> My goal is to make all the sysfs_emit() changes look almost
>>> mechanical, with the non-trivial parts separated out.
>>
>> And BTW, when all the sysfs_emit() changes are trivial like that, I
>> would probably squash them all into one patch that converts all of
>> drivers/pci/ at once.
>>
>> That would still leave a few separate patches:
>>
>>   - This dsm_label_utf16s_to_utf8s() change
>>   - The resource_alignment newline change
>>   - The devspec_show newline change
>>   - The driver_override change
> 
> Got it!  I will send v4 updated as per the above suggestion.  Also, if
> Logan does not mind, I will carry his "Reviewed-by" over as there will
> be no changes to the actual code, just how the patch will be arranged.

Yup, I'm good with that. Still looks fine by me.

Logan
diff mbox series

Patch

diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
index c32f3b7540e8..000e169c7197 100644
--- a/drivers/pci/pci-label.c
+++ b/drivers/pci/pci-label.c
@@ -139,14 +139,17 @@  enum acpi_attr_enum {
 	ACPI_ATTR_INDEX_SHOW,
 };
 
-static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
+static int dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
 {
 	int len;
+
 	len = utf16s_to_utf8s((const wchar_t *)obj->buffer.pointer,
 			      obj->buffer.length,
 			      UTF16_LITTLE_ENDIAN,
 			      buf, PAGE_SIZE);
 	buf[len] = '\n';
+
+	return len;
 }
 
 static int dsm_get_label(struct device *dev, char *buf,
@@ -154,7 +157,7 @@  static int dsm_get_label(struct device *dev, char *buf,
 {
 	acpi_handle handle = ACPI_HANDLE(dev);
 	union acpi_object *obj, *tmp;
-	int len = -1;
+	int len = 0;
 
 	if (!handle)
 		return -1;
@@ -175,20 +178,19 @@  static int dsm_get_label(struct device *dev, char *buf,
 		 * this entry must return a null string.
 		 */
 		if (attr == ACPI_ATTR_INDEX_SHOW) {
-			scnprintf(buf, PAGE_SIZE, "%llu\n", tmp->integer.value);
+			len = sysfs_emit(buf, "%llu\n", tmp->integer.value);
 		} else if (attr == ACPI_ATTR_LABEL_SHOW) {
 			if (tmp[1].type == ACPI_TYPE_STRING)
-				scnprintf(buf, PAGE_SIZE, "%s\n",
-					  tmp[1].string.pointer);
+				len = sysfs_emit(buf, "%s\n",
+						 tmp[1].string.pointer);
 			else if (tmp[1].type == ACPI_TYPE_BUFFER)
-				dsm_label_utf16s_to_utf8s(tmp + 1, buf);
+				len = dsm_label_utf16s_to_utf8s(tmp + 1, buf);
 		}
-		len = strlen(buf) > 0 ? strlen(buf) : -1;
 	}
 
 	ACPI_FREE(obj);
 
-	return len;
+	return len > 0 ? len : -1;
 }
 
 static ssize_t label_show(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index d627dd9179b4..751a26668e3a 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -39,19 +39,19 @@  static const struct sysfs_ops pci_slot_sysfs_ops = {
 static ssize_t address_read_file(struct pci_slot *slot, char *buf)
 {
 	if (slot->number == 0xff)
-		return sprintf(buf, "%04x:%02x\n",
-				pci_domain_nr(slot->bus),
-				slot->bus->number);
-	else
-		return sprintf(buf, "%04x:%02x:%02x\n",
-				pci_domain_nr(slot->bus),
-				slot->bus->number,
-				slot->number);
+		return sysfs_emit(buf, "%04x:%02x\n",
+				  pci_domain_nr(slot->bus),
+				  slot->bus->number);
+
+	return sysfs_emit(buf, "%04x:%02x:%02x\n",
+			  pci_domain_nr(slot->bus),
+			  slot->bus->number,
+			  slot->number);
 }
 
 static ssize_t bus_speed_read(enum pci_bus_speed speed, char *buf)
 {
-	return sprintf(buf, "%s\n", pci_speed_string(speed));
+	return sysfs_emit(buf, "%s\n", pci_speed_string(speed));
 }
 
 static ssize_t max_speed_read_file(struct pci_slot *slot, char *buf)