[PATCH 05/21] can: bcm: Don't initialized an unused hrtimer

Nam Cao posted 21 patches 4 weeks ago
[PATCH 05/21] can: bcm: Don't initialized an unused hrtimer
Posted by Nam Cao 4 weeks ago
The hrtimer "thrtimer" is not used for TX. But this timer is initialized
regardless.

Remove the hrtimer_init() for the unused hrtimer and change bcm_remove_op()
to make sure hrtimer_cancel() is not called with the uninitialized hrtimer.

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Oliver Hartkopp <socketcan@hartkopp.net>
Cc: Jakub Kicinski <kuba@kernel.org>
---
 net/can/bcm.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/net/can/bcm.c b/net/can/bcm.c
index 217049fa496e..792528f7bce2 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -780,10 +780,11 @@ static void bcm_free_op_rcu(struct rcu_head *rcu_head)
 	kfree(op);
 }
 
-static void bcm_remove_op(struct bcm_op *op)
+static void bcm_remove_op(struct bcm_op *op, bool is_tx)
 {
 	hrtimer_cancel(&op->timer);
-	hrtimer_cancel(&op->thrtimer);
+	if (!is_tx)
+		hrtimer_cancel(&op->thrtimer);
 
 	call_rcu(&op->rcu, bcm_free_op_rcu);
 }
@@ -844,7 +845,7 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
 						  bcm_rx_handler, op);
 
 			list_del(&op->list);
-			bcm_remove_op(op);
+			bcm_remove_op(op, false);
 			return 1; /* done */
 		}
 	}
@@ -864,7 +865,7 @@ static int bcm_delete_tx_op(struct list_head *ops, struct bcm_msg_head *mh,
 		if ((op->can_id == mh->can_id) && (op->ifindex == ifindex) &&
 		    (op->flags & CAN_FD_FRAME) == (mh->flags & CAN_FD_FRAME)) {
 			list_del(&op->list);
-			bcm_remove_op(op);
+			bcm_remove_op(op, true);
 			return 1; /* done */
 		}
 	}
@@ -1015,10 +1016,6 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 			     HRTIMER_MODE_REL_SOFT);
 		op->timer.function = bcm_tx_timeout_handler;
 
-		/* currently unused in tx_ops */
-		hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC,
-			     HRTIMER_MODE_REL_SOFT);
-
 		/* add this bcm_op to the list of the tx_ops */
 		list_add(&op->list, &bo->tx_ops);
 
@@ -1277,7 +1274,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 		if (err) {
 			/* this bcm rx op is broken -> remove it */
 			list_del(&op->list);
-			bcm_remove_op(op);
+			bcm_remove_op(op, false);
 			return err;
 		}
 	}
@@ -1581,7 +1578,7 @@ static int bcm_release(struct socket *sock)
 #endif /* CONFIG_PROC_FS */
 
 	list_for_each_entry_safe(op, next, &bo->tx_ops, list)
-		bcm_remove_op(op);
+		bcm_remove_op(op, true);
 
 	list_for_each_entry_safe(op, next, &bo->rx_ops, list) {
 		/*
@@ -1613,7 +1610,7 @@ static int bcm_release(struct socket *sock)
 	synchronize_rcu();
 
 	list_for_each_entry_safe(op, next, &bo->rx_ops, list)
-		bcm_remove_op(op);
+		bcm_remove_op(op, false);
 
 	/* remove device reference */
 	if (bo->bound) {
-- 
2.39.5
Re: [PATCH 05/21] can: bcm: Don't initialized an unused hrtimer
Posted by Oliver Hartkopp 3 weeks, 4 days ago

On 28.10.24 08:29, Nam Cao wrote:
> The hrtimer "thrtimer" is not used for TX. But this timer is initialized
> regardless.
> 
> Remove the hrtimer_init() for the unused hrtimer and change bcm_remove_op()
> to make sure hrtimer_cancel() is not called with the uninitialized hrtimer.

NAK.

There are several other occurrences of thrtimer that are not covered by 
RX/TX distinction, where the second timer is canceled.

This one-time init and cancel of an unused hrtimer costs nearly nothing 
and is not even in any hot path.

So this incomplete patch only adds complexity and potential error cases 
in some 20 y/o code for nothing.

Therefore I would like to skip it.

Thanks,
Oliver

> 
> Signed-off-by: Nam Cao <namcao@linutronix.de>
> ---
> Cc: Oliver Hartkopp <socketcan@hartkopp.net>
> Cc: Jakub Kicinski <kuba@kernel.org>
> ---
>   net/can/bcm.c | 19 ++++++++-----------
>   1 file changed, 8 insertions(+), 11 deletions(-)
> 
> diff --git a/net/can/bcm.c b/net/can/bcm.c
> index 217049fa496e..792528f7bce2 100644
> --- a/net/can/bcm.c
> +++ b/net/can/bcm.c
> @@ -780,10 +780,11 @@ static void bcm_free_op_rcu(struct rcu_head *rcu_head)
>   	kfree(op);
>   }
>   
> -static void bcm_remove_op(struct bcm_op *op)
> +static void bcm_remove_op(struct bcm_op *op, bool is_tx)
>   {
>   	hrtimer_cancel(&op->timer);
> -	hrtimer_cancel(&op->thrtimer);
> +	if (!is_tx)
> +		hrtimer_cancel(&op->thrtimer);
>   
>   	call_rcu(&op->rcu, bcm_free_op_rcu);
>   }
> @@ -844,7 +845,7 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
>   						  bcm_rx_handler, op);
>   
>   			list_del(&op->list);
> -			bcm_remove_op(op);
> +			bcm_remove_op(op, false);
>   			return 1; /* done */
>   		}
>   	}
> @@ -864,7 +865,7 @@ static int bcm_delete_tx_op(struct list_head *ops, struct bcm_msg_head *mh,
>   		if ((op->can_id == mh->can_id) && (op->ifindex == ifindex) &&
>   		    (op->flags & CAN_FD_FRAME) == (mh->flags & CAN_FD_FRAME)) {
>   			list_del(&op->list);
> -			bcm_remove_op(op);
> +			bcm_remove_op(op, true);
>   			return 1; /* done */
>   		}
>   	}
> @@ -1015,10 +1016,6 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
>   			     HRTIMER_MODE_REL_SOFT);
>   		op->timer.function = bcm_tx_timeout_handler;
>   
> -		/* currently unused in tx_ops */
> -		hrtimer_init(&op->thrtimer, CLOCK_MONOTONIC,
> -			     HRTIMER_MODE_REL_SOFT);
> -
>   		/* add this bcm_op to the list of the tx_ops */
>   		list_add(&op->list, &bo->tx_ops);
>   
> @@ -1277,7 +1274,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
>   		if (err) {
>   			/* this bcm rx op is broken -> remove it */
>   			list_del(&op->list);
> -			bcm_remove_op(op);
> +			bcm_remove_op(op, false);
>   			return err;
>   		}
>   	}
> @@ -1581,7 +1578,7 @@ static int bcm_release(struct socket *sock)
>   #endif /* CONFIG_PROC_FS */
>   
>   	list_for_each_entry_safe(op, next, &bo->tx_ops, list)
> -		bcm_remove_op(op);
> +		bcm_remove_op(op, true);
>   
>   	list_for_each_entry_safe(op, next, &bo->rx_ops, list) {
>   		/*
> @@ -1613,7 +1610,7 @@ static int bcm_release(struct socket *sock)
>   	synchronize_rcu();
>   
>   	list_for_each_entry_safe(op, next, &bo->rx_ops, list)
> -		bcm_remove_op(op);
> +		bcm_remove_op(op, false);
>   
>   	/* remove device reference */
>   	if (bo->bound) {
Re: [PATCH 05/21] can: bcm: Don't initialized an unused hrtimer
Posted by Nam Cao 3 weeks, 4 days ago
On Wed, Oct 30, 2024 at 11:49:49AM +0100, Oliver Hartkopp wrote:
> On 28.10.24 08:29, Nam Cao wrote:
> > The hrtimer "thrtimer" is not used for TX. But this timer is initialized
> > regardless.
> > 
> > Remove the hrtimer_init() for the unused hrtimer and change bcm_remove_op()
> > to make sure hrtimer_cancel() is not called with the uninitialized hrtimer.
> 
> NAK.
> 
> There are several other occurrences of thrtimer that are not covered by
> RX/TX distinction, where the second timer is canceled.
> 
> This one-time init and cancel of an unused hrtimer costs nearly nothing and
> is not even in any hot path.
> 
> So this incomplete patch only adds complexity and potential error cases in
> some 20 y/o code for nothing.

The "real" motivation is preparing to use hrtimer_setup() instead of
hrtimer_init() [1] and deleting hrtimer_init() [2]. The new function
mandates a callback function, and since the TX thrtimer doesn't have a
callback function, hrtimer_setup() cannot be used.

Your concerns are also valid. So I can drop this patch, and use a dummy
function to make hrtimer_setup() happy, like how it's done for the rt2x00
driver [3]. It will make the driver a bit ugly, but it's obvious that it
won't cause any regression.

Best regards,
Nam

[1] https://lore.kernel.org/lkml/e4ce3a3a28625d54ef93e47bfb02f7ffb741758a.1729865232.git.namcao@linutronix.de/
[2] https://lore.kernel.org/lkml/7bde2762d82d30dab184c7a747e76afc41208da0.1729865740.git.namcao@linutronix.de/
[3] https://lore.kernel.org/lkml/49f2bce487f56eb2a3ff572ea6d7de0a43560c0f.1729865232.git.namcao@linutronix.de/
Re: [PATCH 05/21] can: bcm: Don't initialized an unused hrtimer
Posted by Oliver Hartkopp 3 weeks, 4 days ago

On 30.10.24 13:15, Nam Cao wrote:
> On Wed, Oct 30, 2024 at 11:49:49AM +0100, Oliver Hartkopp wrote:
>> On 28.10.24 08:29, Nam Cao wrote:
>>> The hrtimer "thrtimer" is not used for TX. But this timer is initialized
>>> regardless.
>>>
>>> Remove the hrtimer_init() for the unused hrtimer and change bcm_remove_op()
>>> to make sure hrtimer_cancel() is not called with the uninitialized hrtimer.
>>
>> NAK.
>>
>> There are several other occurrences of thrtimer that are not covered by
>> RX/TX distinction, where the second timer is canceled.
>>
>> This one-time init and cancel of an unused hrtimer costs nearly nothing and
>> is not even in any hot path.
>>
>> So this incomplete patch only adds complexity and potential error cases in
>> some 20 y/o code for nothing.
> 
> The "real" motivation is preparing to use hrtimer_setup() instead of
> hrtimer_init() [1] and deleting hrtimer_init() [2]. The new function
> mandates a callback function, and since the TX thrtimer doesn't have a
> callback function, hrtimer_setup() cannot be used.
> 
> Your concerns are also valid. So I can drop this patch, and use a dummy
> function to make hrtimer_setup() happy, like how it's done for the rt2x00
> driver [3]. It will make the driver a bit ugly, but it's obvious that it
> won't cause any regression.

Many thanks for your efforts!
That's a good approach!

Best regards,
Oliver

> 
> Best regards,
> Nam
> 
> [1] https://lore.kernel.org/lkml/e4ce3a3a28625d54ef93e47bfb02f7ffb741758a.1729865232.git.namcao@linutronix.de/
> [2] https://lore.kernel.org/lkml/7bde2762d82d30dab184c7a747e76afc41208da0.1729865740.git.namcao@linutronix.de/
> [3] https://lore.kernel.org/lkml/49f2bce487f56eb2a3ff572ea6d7de0a43560c0f.1729865232.git.namcao@linutronix.de/
Re: [PATCH 05/21] can: bcm: Don't initialized an unused hrtimer
Posted by Oliver Hartkopp 3 weeks, 4 days ago
Just an additional idea:

Would it probably make sense to create a generic dummy function for all 
those cases like in the referenced rt2x00 driver?

E.g. as (inline?) function in hrtimer.h

enum hrtimer_restart hrtimer_nop_callback(struct hrtimer *timer)
{
	return HRTIMER_NORESTART;
}

??

Best regards,
Oliver

On 30.10.24 15:51, Oliver Hartkopp wrote:
> 
> 
> On 30.10.24 13:15, Nam Cao wrote:
>> On Wed, Oct 30, 2024 at 11:49:49AM +0100, Oliver Hartkopp wrote:
>>> On 28.10.24 08:29, Nam Cao wrote:
>>>> The hrtimer "thrtimer" is not used for TX. But this timer is 
>>>> initialized
>>>> regardless.
>>>>
>>>> Remove the hrtimer_init() for the unused hrtimer and change 
>>>> bcm_remove_op()
>>>> to make sure hrtimer_cancel() is not called with the uninitialized 
>>>> hrtimer.
>>>
>>> NAK.
>>>
>>> There are several other occurrences of thrtimer that are not covered by
>>> RX/TX distinction, where the second timer is canceled.
>>>
>>> This one-time init and cancel of an unused hrtimer costs nearly 
>>> nothing and
>>> is not even in any hot path.
>>>
>>> So this incomplete patch only adds complexity and potential error 
>>> cases in
>>> some 20 y/o code for nothing.
>>
>> The "real" motivation is preparing to use hrtimer_setup() instead of
>> hrtimer_init() [1] and deleting hrtimer_init() [2]. The new function
>> mandates a callback function, and since the TX thrtimer doesn't have a
>> callback function, hrtimer_setup() cannot be used.
>>
>> Your concerns are also valid. So I can drop this patch, and use a dummy
>> function to make hrtimer_setup() happy, like how it's done for the rt2x00
>> driver [3]. It will make the driver a bit ugly, but it's obvious that it
>> won't cause any regression.
> 
> Many thanks for your efforts!
> That's a good approach!
> 
> Best regards,
> Oliver
> 
>>
>> Best regards,
>> Nam
>>
>> [1] https://lore.kernel.org/lkml/ 
>> e4ce3a3a28625d54ef93e47bfb02f7ffb741758a.1729865232.git.namcao@linutronix.de/
>> [2] https://lore.kernel.org/ 
>> lkml/7bde2762d82d30dab184c7a747e76afc41208da0.1729865740.git.namcao@linutronix.de/
>> [3] https://lore.kernel.org/ 
>> lkml/49f2bce487f56eb2a3ff572ea6d7de0a43560c0f.1729865232.git.namcao@linutronix.de/
>
Re: [PATCH 05/21] can: bcm: Don't initialized an unused hrtimer
Posted by Thomas Gleixner 3 weeks, 4 days ago
On Wed, Oct 30 2024 at 16:01, Oliver Hartkopp wrote:

> Just an additional idea:
>
> Would it probably make sense to create a generic dummy function for all 
> those cases like in the referenced rt2x00 driver?
>
> E.g. as (inline?) function in hrtimer.h
>
> enum hrtimer_restart hrtimer_nop_callback(struct hrtimer *timer)
> {
> 	return HRTIMER_NORESTART;
> }

Yes.