diff mbox series

[01/15] genirq/devres: Add error information printing for devm_request_threaded_irq()

Message ID 20230627071707.77659-1-frank.li@vivo.com (mailing list archive)
State New, archived
Headers show
Series [01/15] genirq/devres: Add error information printing for devm_request_threaded_irq() | expand

Commit Message

Yangtao Li June 27, 2023, 7:16 a.m. UTC
Ensure that all error handling branches print error information. In this
way, when this function fails, the upper-layer functions can directly
return an error code without missing debugging information. Otherwise,
the error message will be printed redundantly or missing.

There are more than 700 calls to the devm_request_threaded_irq method.
If error messages are printed everywhere, more than 1000 lines of code
can be saved by removing the msg in the driver.

Signed-off-by: Yangtao Li <frank.li@vivo.com>
---
 kernel/irq/devres.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Krzysztof Kozlowski June 27, 2023, 7:43 a.m. UTC | #1
On 27/06/2023 09:16, Yangtao Li wrote:
> Ensure that all error handling branches print error information. In this
> way, when this function fails, the upper-layer functions can directly
> return an error code without missing debugging information. Otherwise,
> the error message will be printed redundantly or missing.
> 
> There are more than 700 calls to the devm_request_threaded_irq method.
> If error messages are printed everywhere, more than 1000 lines of code
> can be saved by removing the msg in the driver.
> 
> Signed-off-by: Yangtao Li <frank.li@vivo.com>
> ---
>  kernel/irq/devres.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
> index f6e5515ee077..94039a915218 100644
> --- a/kernel/irq/devres.c
> +++ b/kernel/irq/devres.c
> @@ -58,8 +58,10 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
>  
>  	dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
>  			  GFP_KERNEL);
> -	if (!dr)
> +	if (!dr) {
> +		dev_err(dev, "Failed to allocate device resource data\n");

Just like any memory allocation, I don't think we print anything for
devres failures. Why do you think we should start doing it?

>  		return -ENOMEM;
> +	}
>  
>  	if (!devname)
>  		devname = dev_name(dev);
> @@ -67,6 +69,7 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
>  	rc = request_threaded_irq(irq, handler, thread_fn, irqflags, devname,
>  				  dev_id);
>  	if (rc) {
> +		dev_err(dev, "Failed to request threaded irq\n");

I don't like that one path - devm() managed - prints error, but regular
path does not. Code should be here consistent. Also error message is too
generic. You need to print at least irq number, maybe also devname?

Best regards,
Krzysztof
Uwe Kleine-König June 27, 2023, 8:49 a.m. UTC | #2
Hello,

On Tue, Jun 27, 2023 at 03:16:52PM +0800, Yangtao Li wrote:
> Ensure that all error handling branches print error information. In this
> way, when this function fails, the upper-layer functions can directly
> return an error code without missing debugging information. Otherwise,
> the error message will be printed redundantly or missing.
> 
> There are more than 700 calls to the devm_request_threaded_irq method.
> If error messages are printed everywhere, more than 1000 lines of code
> can be saved by removing the msg in the driver.
> 
> Signed-off-by: Yangtao Li <frank.li@vivo.com>
> ---
>  kernel/irq/devres.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
> index f6e5515ee077..94039a915218 100644
> --- a/kernel/irq/devres.c
> +++ b/kernel/irq/devres.c
> @@ -58,8 +58,10 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
>  
>  	dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
>  			  GFP_KERNEL);
> -	if (!dr)
> +	if (!dr) {
> +		dev_err(dev, "Failed to allocate device resource data\n");
>  		return -ENOMEM;
> +	}
>  
>  	if (!devname)
>  		devname = dev_name(dev);
> @@ -67,6 +69,7 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
>  	rc = request_threaded_irq(irq, handler, thread_fn, irqflags, devname,
>  				  dev_id);
>  	if (rc) {
> +		dev_err(dev, "Failed to request threaded irq\n");
>  		devres_free(dr);
>  		return rc;
>  	}

My personal opinion is that generic allocation functions should be
silent. The reason is that the consuming driver is in a better position
to emit a helpful error message.

While there is some room to improvment in this generic variant (by
mentioning the error code and maybe also the irq number), consider a
device that has up to 3 irqs and sometimes only 1. So the driver might
want to handle some irq requesting silently. And also for non-optional
irqs

	mybus:mydev: Failed to request TX irq (EBUSY)

is much more helpful than

	mybus:mydev: Failed to request threaded irq

(Hint: "threaded" is not a helpful information here either.)

Yes, a message in the driver has the downside of making the kernel image
(or module) bigger, but the added value is IMHO worth that.

Also you might want to handle -EPROBE_DEFER and not emit a message then?
(Not sure if request_threaded_irq can return that.)

Best regards
Uwe
Yangtao Li July 3, 2023, 9:10 a.m. UTC | #3
On 2023/6/27 15:43, Krzysztof Kozlowski wrote:

> On 27/06/2023 09:16, Yangtao Li wrote:
>> Ensure that all error handling branches print error information. In this
>> way, when this function fails, the upper-layer functions can directly
>> return an error code without missing debugging information. Otherwise,
>> the error message will be printed redundantly or missing.
>>
>> There are more than 700 calls to the devm_request_threaded_irq method.
>> If error messages are printed everywhere, more than 1000 lines of code
>> can be saved by removing the msg in the driver.
>>
>> Signed-off-by: Yangtao Li <frank.li@vivo.com>
>> ---
>>   kernel/irq/devres.c | 5 ++++-
>>   1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
>> index f6e5515ee077..94039a915218 100644
>> --- a/kernel/irq/devres.c
>> +++ b/kernel/irq/devres.c
>> @@ -58,8 +58,10 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
>>   
>>   	dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
>>   			  GFP_KERNEL);
>> -	if (!dr)
>> +	if (!dr) {
>> +		dev_err(dev, "Failed to allocate device resource data\n");
> Just like any memory allocation, I don't think we print anything for
> devres failures. Why do you think we should start doing it?


And tglx point out that:

Having proper and consistent information why the device cannot be used 
_is_ useful.

>
>>   		return -ENOMEM;
>> +	}
>>   
>>   	if (!devname)
>>   		devname = dev_name(dev);
>> @@ -67,6 +69,7 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
>>   	rc = request_threaded_irq(irq, handler, thread_fn, irqflags, devname,
>>   				  dev_id);
>>   	if (rc) {
>> +		dev_err(dev, "Failed to request threaded irq\n");
> I don't like that one path - devm() managed - prints error, but regular
> path does not. Code should be here consistent. Also error message is too
> generic. You need to print at least irq number, maybe also devname?


v3 has been added.


Thx,

Yangtao


>
> Best regards,
> Krzysztof
>
Krzysztof Kozlowski July 3, 2023, 11:38 a.m. UTC | #4
On 03/07/2023 11:10, Yangtao Li wrote:
> On 2023/6/27 15:43, Krzysztof Kozlowski wrote:
> 
>> On 27/06/2023 09:16, Yangtao Li wrote:
>>> Ensure that all error handling branches print error information. In this
>>> way, when this function fails, the upper-layer functions can directly
>>> return an error code without missing debugging information. Otherwise,
>>> the error message will be printed redundantly or missing.
>>>
>>> There are more than 700 calls to the devm_request_threaded_irq method.
>>> If error messages are printed everywhere, more than 1000 lines of code
>>> can be saved by removing the msg in the driver.
>>>
>>> Signed-off-by: Yangtao Li <frank.li@vivo.com>
>>> ---
>>>   kernel/irq/devres.c | 5 ++++-
>>>   1 file changed, 4 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
>>> index f6e5515ee077..94039a915218 100644
>>> --- a/kernel/irq/devres.c
>>> +++ b/kernel/irq/devres.c
>>> @@ -58,8 +58,10 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
>>>   
>>>   	dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
>>>   			  GFP_KERNEL);
>>> -	if (!dr)
>>> +	if (!dr) {
>>> +		dev_err(dev, "Failed to allocate device resource data\n");
>> Just like any memory allocation, I don't think we print anything for
>> devres failures. Why do you think we should start doing it?
> 
> 
> And tglx point out that:
> 
> Having proper and consistent information why the device cannot be used 
> _is_ useful.

Where did tglx suggest printing devres allocation ENOMEM errors?

Best regards,
Krzysztof
diff mbox series

Patch

diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
index f6e5515ee077..94039a915218 100644
--- a/kernel/irq/devres.c
+++ b/kernel/irq/devres.c
@@ -58,8 +58,10 @@  int devm_request_threaded_irq(struct device *dev, unsigned int irq,
 
 	dr = devres_alloc(devm_irq_release, sizeof(struct irq_devres),
 			  GFP_KERNEL);
-	if (!dr)
+	if (!dr) {
+		dev_err(dev, "Failed to allocate device resource data\n");
 		return -ENOMEM;
+	}
 
 	if (!devname)
 		devname = dev_name(dev);
@@ -67,6 +69,7 @@  int devm_request_threaded_irq(struct device *dev, unsigned int irq,
 	rc = request_threaded_irq(irq, handler, thread_fn, irqflags, devname,
 				  dev_id);
 	if (rc) {
+		dev_err(dev, "Failed to request threaded irq\n");
 		devres_free(dr);
 		return rc;
 	}