diff mbox

[v3] backlight: report error on failure

Message ID 1494093610-5561-1-git-send-email-sudipm.mukherjee@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sudip Mukherjee May 6, 2017, 6 p.m. UTC
It is possible to update the backlight power and the brightness using
the sysfs and on writing it either returns the count or if the callback
function does not exist then returns the error code 'ENXIO'.

We have a situation where the userspace client is writing to the sysfs
to update the power and since the callback function exists the client
receives the return value as count and considers the operation to be
successful. That is correct as the write to the sysfs was successful.
But there is no way to know if the actual operation was done or not.

backlight_update_status() returns the error code if it fails. Pass that
to the userspace client who is trying to update the power so that the
client knows that the operation failed.

This is not a change of ABI as the userspace expects an error of ENXIO,
after this patch the range of errors that are returned to the userspace
will increase.

Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
---

v3: remove rc = 0, and update rc with count in else condition.
v2: update power with old value on failure.

Copy-pasting from the last patch conversation:

The problem that prompted me to send this patch is the current project
that I am working on now. And we faced this there. The userspace code is
writing to the sysfs node to poweron the backlight and reported success.
But sometimes we noticed that backlight was not actally powered on. And
that lead me to check the code and noticed that it is swallowing all the
errors.

 drivers/video/backlight/backlight.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

Comments

Daniel Thompson May 8, 2017, 3:45 p.m. UTC | #1
On 06/05/17 19:00, Sudip Mukherjee wrote:
> It is possible to update the backlight power and the brightness using
> the sysfs and on writing it either returns the count or if the callback
> function does not exist then returns the error code 'ENXIO'.
> 
> We have a situation where the userspace client is writing to the sysfs
> to update the power and since the callback function exists the client
> receives the return value as count and considers the operation to be
> successful. That is correct as the write to the sysfs was successful.
> But there is no way to know if the actual operation was done or not.
> 
> backlight_update_status() returns the error code if it fails. Pass that
> to the userspace client who is trying to update the power so that the
> client knows that the operation failed.
> 
> This is not a change of ABI as the userspace expects an error of ENXIO,
> after this patch the range of errors that are returned to the userspace
> will increase.

This comment is wrong, no code path through 
backlight_device_set_brightness() can possibly return ENXIO.

My review comment to v1 was:
 > Strictly speaking this is an ABI change. Its probably a harmless one
 > making it ok to change but I'm interested what testing or code review
 > you've done to be sure the userspace doesn't do odd things if the
 > kernel starts to pass through errors.

I find myself somewhat surprised to find the above review comment 
addressed by adding text to the patch header denying that there is a 
change of ABI...


Daniel.


> 
> Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
> ---
> 
> v3: remove rc = 0, and update rc with count in else condition.
> v2: update power with old value on failure.
> 
> Copy-pasting from the last patch conversation:
> 
> The problem that prompted me to send this patch is the current project
> that I am working on now. And we faced this there. The userspace code is
> writing to the sysfs node to poweron the backlight and reported success.
> But sometimes we noticed that backlight was not actally powered on. And
> that lead me to check the code and noticed that it is swallowing all the
> errors.
> 
>   drivers/video/backlight/backlight.c | 14 +++++++++-----
>   1 file changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
> index 288318a..0289107 100644
> --- a/drivers/video/backlight/backlight.c
> +++ b/drivers/video/backlight/backlight.c
> @@ -134,7 +134,7 @@ static ssize_t bl_power_store(struct device *dev, struct device_attribute *attr,
>   {
>   	int rc;
>   	struct backlight_device *bd = to_backlight_device(dev);
> -	unsigned long power;
> +	unsigned long power, old_power;
>   
>   	rc = kstrtoul(buf, 0, &power);
>   	if (rc)
> @@ -145,10 +145,15 @@ static ssize_t bl_power_store(struct device *dev, struct device_attribute *attr,
>   	if (bd->ops) {
>   		pr_debug("set power to %lu\n", power);
>   		if (bd->props.power != power) {
> +			old_power = bd->props.power;
>   			bd->props.power = power;
> -			backlight_update_status(bd);
> +			rc = backlight_update_status(bd);
> +			if (rc)
> +				bd->props.power = old_power;
> +		} else {
> +			rc = count;
>   		}
> -		rc = count;
> +		rc = rc ? rc : count;
>   	}
>   	mutex_unlock(&bd->ops_lock);
>   
> @@ -176,8 +181,7 @@ int backlight_device_set_brightness(struct backlight_device *bd,
>   		else {
>   			pr_debug("set brightness to %lu\n", brightness);
>   			bd->props.brightness = brightness;
> -			backlight_update_status(bd);
> -			rc = 0;
> +			rc = backlight_update_status(bd);
>   		}
>   	}
>   	mutex_unlock(&bd->ops_lock);
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sudip Mukherjee May 9, 2017, 2:56 p.m. UTC | #2
On Mon, May 08, 2017 at 04:45:17PM +0100, Daniel Thompson wrote:
> On 06/05/17 19:00, Sudip Mukherjee wrote:
> >It is possible to update the backlight power and the brightness using
> >the sysfs and on writing it either returns the count or if the callback
> >function does not exist then returns the error code 'ENXIO'.
> >
> >We have a situation where the userspace client is writing to the sysfs
> >to update the power and since the callback function exists the client
> >receives the return value as count and considers the operation to be
> >successful. That is correct as the write to the sysfs was successful.
> >But there is no way to know if the actual operation was done or not.
> >
> >backlight_update_status() returns the error code if it fails. Pass that
> >to the userspace client who is trying to update the power so that the
> >client knows that the operation failed.
> >
> >This is not a change of ABI as the userspace expects an error of ENXIO,
> >after this patch the range of errors that are returned to the userspace
> >will increase.
> 
> This comment is wrong, no code path through
> backlight_device_set_brightness() can possibly return ENXIO.

I am seeing backlight_device_set_brightness() can return ENXIO
if bd->ops is NULL. ofcourse I have not tried to test by passing NULL as
backlight_ops in backlight_device_register().

> 
> My review comment to v1 was:
> > Strictly speaking this is an ABI change. Its probably a harmless one
> > making it ok to change but I'm interested what testing or code review
> > you've done to be sure the userspace doesn't do odd things if the
> > kernel starts to pass through errors.
> 
> I find myself somewhat surprised to find the above review comment addressed
> by adding text to the patch header denying that there is a change of ABI...

Yes, sorry about this. I got confused between API and ABI. :(

So, this is an ABI change (not API change, as I misunderstood) as now
the userspace might get some more error codes as return which it was not
expecting.
How will you want me to test and review it? I can make a list of the
other drivers which are registering the backlight and review what they
are doing if there is an error in the backlight or brightness. And then
we can have a statistics how many of the drivers will be returning extra
error codes. I have been seeing few drivers and i noticed all of them
are just returning 0 at the end.

Sorry again for the confusion.


Regards
Sudip
--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Daniel Thompson May 9, 2017, 7:19 p.m. UTC | #3
On 09/05/17 15:56, Sudip Mukherjee wrote:
> On Mon, May 08, 2017 at 04:45:17PM +0100, Daniel Thompson wrote:
>> On 06/05/17 19:00, Sudip Mukherjee wrote:
>>> It is possible to update the backlight power and the brightness using
>>> the sysfs and on writing it either returns the count or if the callback
>>> function does not exist then returns the error code 'ENXIO'.
>>>
>>> We have a situation where the userspace client is writing to the sysfs
>>> to update the power and since the callback function exists the client
>>> receives the return value as count and considers the operation to be
>>> successful. That is correct as the write to the sysfs was successful.
>>> But there is no way to know if the actual operation was done or not.
>>>
>>> backlight_update_status() returns the error code if it fails. Pass that
>>> to the userspace client who is trying to update the power so that the
>>> client knows that the operation failed.
>>>
>>> This is not a change of ABI as the userspace expects an error of ENXIO,
>>> after this patch the range of errors that are returned to the userspace
>>> will increase.
>>
>> This comment is wrong, no code path through
>> backlight_device_set_brightness() can possibly return ENXIO.
> 
> I am seeing backlight_device_set_brightness() can return ENXIO
> if bd->ops is NULL. ofcourse I have not tried to test by passing NULL as
> backlight_ops in backlight_device_register().
> 
>>
>> My review comment to v1 was:
>>> Strictly speaking this is an ABI change. Its probably a harmless one
>>> making it ok to change but I'm interested what testing or code review
>>> you've done to be sure the userspace doesn't do odd things if the
>>> kernel starts to pass through errors.
>>
>> I find myself somewhat surprised to find the above review comment addressed
>> by adding text to the patch header denying that there is a change of ABI...
> 
> Yes, sorry about this. I got confused between API and ABI. :(
> 
> So, this is an ABI change (not API change, as I misunderstood) as now
> the userspace might get some more error codes as return which it was not
> expecting.
> How will you want me to test and review it? I can make a list of the
> other drivers which are registering the backlight and review what they
> are doing if there is an error in the backlight or brightness. And then
> we can have a statistics how many of the drivers will be returning extra
> error codes. I have been seeing few drivers and i noticed all of them
> are just returning 0 at the end.

I really did just wonder what you had already done!

Since yesterday I've done a quick code review of Weston, KDE and 
gnome-settings-daemon and saw no particular grounds to worry. Mostly the 
userspace sets sysfs from layers of IPC mechanisms so there's loads of 
ways it can report failure... I doubt one more will hurt ;-)

Let's just get this comment removed and that's probably enough!


Daniel.
--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 288318a..0289107 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -134,7 +134,7 @@  static ssize_t bl_power_store(struct device *dev, struct device_attribute *attr,
 {
 	int rc;
 	struct backlight_device *bd = to_backlight_device(dev);
-	unsigned long power;
+	unsigned long power, old_power;
 
 	rc = kstrtoul(buf, 0, &power);
 	if (rc)
@@ -145,10 +145,15 @@  static ssize_t bl_power_store(struct device *dev, struct device_attribute *attr,
 	if (bd->ops) {
 		pr_debug("set power to %lu\n", power);
 		if (bd->props.power != power) {
+			old_power = bd->props.power;
 			bd->props.power = power;
-			backlight_update_status(bd);
+			rc = backlight_update_status(bd);
+			if (rc)
+				bd->props.power = old_power;
+		} else {
+			rc = count;
 		}
-		rc = count;
+		rc = rc ? rc : count;
 	}
 	mutex_unlock(&bd->ops_lock);
 
@@ -176,8 +181,7 @@  int backlight_device_set_brightness(struct backlight_device *bd,
 		else {
 			pr_debug("set brightness to %lu\n", brightness);
 			bd->props.brightness = brightness;
-			backlight_update_status(bd);
-			rc = 0;
+			rc = backlight_update_status(bd);
 		}
 	}
 	mutex_unlock(&bd->ops_lock);