Thread (9 messages) 9 messages, 2 authors, 2021-04-02

Re: [PATCH v14 1/4] can: etas_es58x: add core support for ETAS ES58X CAN USB interfaces

From: Vincent MAILHOL <hidden>
Date: 2021-04-02 13:02:25

On Fri. 2 Apr 2021 at 19:47, Marc Kleine-Budde [off-list ref] wrote:
On 02.04.2021 18:56:33, Vincent MAILHOL wrote:
quoted
quoted
quoted
+int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error,
+                  enum es58x_event event, u64 timestamp)
+{
+     struct es58x_priv *priv = es58x_priv(netdev);
+     struct can_priv *can = netdev_priv(netdev);
+     struct can_device_stats *can_stats = &can->can_stats;
+     struct can_frame *cf;
= NULL;

So that the if (cf) properly works...
I actually expected cfto be set to NULL when an error
occurred (same as skb).

But indeed, cf is not initialised if the allocation fails. I was
wondering if it would not be better to make both alloc_can_skb()
and and alloc_canfd_skb() set cf to NULL. That would remove a
pitfall.
Makes sense.
quoted
If you like the idea, I can submit a patch.
Sorry creating this drive by patch. The patch description took longer
than the actual patch :)
This is often the case for any patches where the diff is one or two lines!

[...]
quoted
quoted
quoted
+/**
+ * es58x_open() - Open and start network device.
+ * @netdev: CAN network device.
+ *
+ * Called when the network transitions to the up state.
+ *
+ * Return: zero on success, errno when any error occurs.
+ */
+static int es58x_open(struct net_device *netdev)
+{
+     int ret;
+
+     ret = open_candev(netdev);
+     if (ret)
+             return ret;
+
+     ret = es58x_enable_channel(netdev);
+     if (ret)
+             return ret;
Please do an as complete as possible reset and configuration during
open(). If there is any error a ifdown/ifup should fix it. Here on a USB
device with multiple interfaces it's not as easy as on devices with only
one CAN interface.
ACK.

I will use a function as below to check if all interfaces are
down.

static bool es58x_are_all_channels_closed(struct es58x_device *es58x_dev)
{
    int i;

    for (i = 0; i < es58x_dev->num_can_ch; i++) {
        struct can_priv *can_priv = netdev_priv(es58x_dev->netdev[i]);
        if (can_priv->state != CAN_STATE_STOPPED)
            return false;
    }
    return true;
}

I will modify both es58x_open() and es58x_close().
Have a look at
https://elixir.bootlin.com/linux/v5.11/source/include/linux/kref.h

I'm not sure if kref is overkill here :)
There is indeed a race condition in which the above function
might return true when it is not supposed to.

I checked the struct kref and the refcount_t, but here, I think
that a simple atomic_t is enough because there is no risk of
saturation.

Something like:
|     if (atomic_inc_return(opened_channel_cnt) == 1)
|         /* configure */
and
|     if (atomic_dec_and_test(opened_channel_cnt))
|         /* release */

[...]

Yours sincerely,
Vincent
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help