All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
To: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: netdev@vger.kernel.org, wg@grandegger.com,
	linux-can@vger.kernel.org, linux-sh@vger.kernel.org,
	vksavl@gmail.com
Subject: Re: [PATCH v3] can: add Renesas R-Car CAN driver
Date: Sat, 09 Nov 2013 01:54:00 +0300	[thread overview]
Message-ID: <527D6B88.3010409@cogentembedded.com> (raw)
In-Reply-To: <527CAC38.6040800@pengutronix.de>

Hello.

On 11/08/2013 12:17 PM, Marc Kleine-Budde wrote:

>>>> Index: linux-can-next/drivers/net/can/rcar_can.c
>>>> ===================================================================
>>>> --- /dev/null
>>>> +++ linux-can-next/drivers/net/can/rcar_can.c
>>>> @@ -0,0 +1,893 @@
[...]
>>>> +#define DRV_NAME    "rcar_can"
>>>> +
>>>> +/* Mailbox configuration:
>>>> + * mailbox 0 - not used
>>>> + * mailbox 1-31 - Rx
>>>> + * mailbox 32-63 - Tx
>>>> + * no FIFO mailboxes
>>>> + */
>>>> +#define N_MBX        64
>>>> +#define FIRST_TX_MB    32
>>>> +#define N_TX_MB        (N_MBX - FIRST_TX_MB)
>>>> +#define RX_MBX_MASK    0xFFFFFFFE

>>> Please use a common prefix for all defines.

>>     OK, done now. Could you however explain why the file-local #define's
>> should be prefixed? It's not quite obvious to me...

> It's about readability and maintainability. If you don't know the
> driver, but all driver local defines and functions have a common prefix,
> it's much easier to read if you are not the author of the driver IMHO.

    Well, actually I think the last changes somewhat impaired the readability. 
My idea was that you want to exclude name conflicts with #include'd headers 
this way...

>> [...]
>>>> +static netdev_tx_t rcar_can_start_xmit(struct sk_buff *skb,
>>>> +                       struct net_device *ndev)
>>>> +{
>>>> +    struct rcar_can_priv *priv = netdev_priv(ndev);
>>>> +    struct can_frame *cf = (struct can_frame *)skb->data;
>>>> +    u32 data, mier1, mbxno, i;
>>>> +    unsigned long flags;
>>>> +    u8 mctl = 0;
>>>> +
>>>> +    if (can_dropped_invalid_skb(ndev, skb))
>>>> +        return NETDEV_TX_OK;
>>>> +
>>>> +    spin_lock_irqsave(&priv->mier_lock, flags);
>>>> +    mier1 = readl(&priv->regs->mier1);
>>>> +    if (mier1) {
>>>> +        i = __builtin_clz(mier1);
>>>> +        mbxno = i ? N_MBX - i : FIRST_TX_MB;
>>>> +    } else {
>>>> +        mbxno = FIRST_TX_MB;
>>>> +    }

>>> Can you explain how the hardware arbitration works, and you do you
>>> guarantee the CAN frames are send by the hardware in the same order you
>>> put them into the hardware.

>>     Tx mailbox with the smallest mailbox number has the highest priority.
>> The other possible Tx mailbox selection rule (not used by the driver
>> now) is ID priority transmit mode (as defined in the ISO 11898-1 specs).
>> The algorithm used guarantees the mailboxes are filled sequentially.

    Well, not quite, unfortunately -- it wraps at the last mailbox...

> I see. You are using mier1 to track the used mailboxes....correct?

    Yes, the mailbox interrupts in MIER1 are enabled only for used mailboxes.

>> +	if (unlikely(mier1 == 0xffffffff))
>> +		netif_stop_queue(ndev);

> Then you have a race condition in your tx-complete handler
> rcar_can_tx_done(), as you call netif_wake_queue() unconditionally. If

    Yes, I'm seeing it now...

> mier1 == 0xffffffff you must wait until _all_ mailboxes are transmitted

    That 0xffffffff criterion seems wrong for me now, I changed the algorithm 
and moved the criterion but didn't update it. The correct one seems to be:

	if (unlikely(mier1 & 0x80000000))
		netif_stop_queue(ndev);

> until you are allowed to reenable the mailboxes. Have a look at the
> at91_can driver, it's using a similar scheme. The lowest mailbox is
> transmitted first, but there are three additional bits that indicate the
> priority.

    You mean 4 bits? Priorities are from 0 to 15...

>> I've used 'canfdtest' as suggested by Wolfgang Grandegger to verify, see
>> the log below:

>> root@am335x-evm:~# ./canfdtest -v -g can0
>> interface = can0, family = 29, type = 3, proto = 1
>> ...............................................................................C
>>
>> Test messages sent and received: 483203
>> Exiting...
>> root@am335x-evm:~#

    As you can see, 'canfdtest' didn't detect any race, maybe you could 
recommend a test which would help to detect it?

>> [...]
>>>> +static int rcar_can_rx_poll(struct napi_struct *napi, int quota)
>>>> +{
>>>> +    struct rcar_can_priv *priv = container_of(napi,
>>>> +                          struct rcar_can_priv, napi);
>>>> +    int num_pkts = 0;
>>>> +
>>>> +    /* Find mailbox */
>>>> +    while (num_pkts < quota) {
>>>> +        u8 mctl, mbx;
>>>> +
>>>> +        mbx = readb(&priv->regs->mssr);

>>> How does the RX work? Is it a hardware FIFO?

>>     In short, the MSSR register provides the smallest Rx mailbox number
>> that is looked up in the Rx search mode. We read MSSR until no search
>> results can be obtained, so it is some sort of FIFO.

> This looks racy....

    Could you please elaborate?

>>     And there is separate FIFO operation mode: some mailboxes can be
>> configured as FIFO and serviced by special registers but this operation
>> mode is not supported by the driver.

> if you hardware supports a real FIFO then I strongly suggest to make use
> of it.

    Well, Tx/Rx FIFOs are only 4 frames deep (although I haven't seen more 
than 2 Rx mailboxes ready in a row, there are 32 Tx mailboxes); also FIFO mode 
is less documented than mailbox mode (hence some nasty surprises are 
possible). We still can use mailboxes when in FIFO mode, it's just 8 of them 
are reserved for Tx/Rx FIFOs.

>> [...]
>>>> +static int rcar_can_probe(struct platform_device *pdev)
>>>> +{
[...]
>>>> +    ndev->netdev_ops = &rcar_can_netdev_ops;
>>>> +    ndev->irq = irq;
>>>> +    ndev->flags |= IFF_ECHO;
>>>> +    priv->ndev = ndev;
>>>> +    priv->regs = addr;
>>>> +    priv->clock_select = pdata->clock_select;
>>>> +    priv->can.clock.freq = clk_get_rate(priv->clk);
>>>> +    priv->can.bittiming_const = &rcar_can_bittiming_const;
>>>> +    priv->can.do_set_bittiming = rcar_can_set_bittiming;

>>> Please call this function directly during the open() function.

>>     OK, done, and the method installation was removed. However, I'm not
>> sure why you requested this as many drivers are still using the method.

> The callback was there from the beginning, but then we figured out that
> we don't need it in the driver, but no one has cleaned up the drivers
> yet. So don't use it in new drivers. I know it's not documented anywhere :(

    You should have clarified that in your first review -- that would have 
prevented me from going the wrong way...

> regards,
> Marc

WBR, Sergei


WARNING: multiple messages have this Message-ID (diff)
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
To: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: netdev@vger.kernel.org, wg@grandegger.com,
	linux-can@vger.kernel.org, linux-sh@vger.kernel.org,
	vksavl@gmail.com
Subject: Re: [PATCH v3] can: add Renesas R-Car CAN driver
Date: Fri, 08 Nov 2013 21:54:11 +0000	[thread overview]
Message-ID: <527D6B88.3010409@cogentembedded.com> (raw)
In-Reply-To: <527CAC38.6040800@pengutronix.de>

Hello.

On 11/08/2013 12:17 PM, Marc Kleine-Budde wrote:

>>>> Index: linux-can-next/drivers/net/can/rcar_can.c
>>>> =================================>>>> --- /dev/null
>>>> +++ linux-can-next/drivers/net/can/rcar_can.c
>>>> @@ -0,0 +1,893 @@
[...]
>>>> +#define DRV_NAME    "rcar_can"
>>>> +
>>>> +/* Mailbox configuration:
>>>> + * mailbox 0 - not used
>>>> + * mailbox 1-31 - Rx
>>>> + * mailbox 32-63 - Tx
>>>> + * no FIFO mailboxes
>>>> + */
>>>> +#define N_MBX        64
>>>> +#define FIRST_TX_MB    32
>>>> +#define N_TX_MB        (N_MBX - FIRST_TX_MB)
>>>> +#define RX_MBX_MASK    0xFFFFFFFE

>>> Please use a common prefix for all defines.

>>     OK, done now. Could you however explain why the file-local #define's
>> should be prefixed? It's not quite obvious to me...

> It's about readability and maintainability. If you don't know the
> driver, but all driver local defines and functions have a common prefix,
> it's much easier to read if you are not the author of the driver IMHO.

    Well, actually I think the last changes somewhat impaired the readability. 
My idea was that you want to exclude name conflicts with #include'd headers 
this way...

>> [...]
>>>> +static netdev_tx_t rcar_can_start_xmit(struct sk_buff *skb,
>>>> +                       struct net_device *ndev)
>>>> +{
>>>> +    struct rcar_can_priv *priv = netdev_priv(ndev);
>>>> +    struct can_frame *cf = (struct can_frame *)skb->data;
>>>> +    u32 data, mier1, mbxno, i;
>>>> +    unsigned long flags;
>>>> +    u8 mctl = 0;
>>>> +
>>>> +    if (can_dropped_invalid_skb(ndev, skb))
>>>> +        return NETDEV_TX_OK;
>>>> +
>>>> +    spin_lock_irqsave(&priv->mier_lock, flags);
>>>> +    mier1 = readl(&priv->regs->mier1);
>>>> +    if (mier1) {
>>>> +        i = __builtin_clz(mier1);
>>>> +        mbxno = i ? N_MBX - i : FIRST_TX_MB;
>>>> +    } else {
>>>> +        mbxno = FIRST_TX_MB;
>>>> +    }

>>> Can you explain how the hardware arbitration works, and you do you
>>> guarantee the CAN frames are send by the hardware in the same order you
>>> put them into the hardware.

>>     Tx mailbox with the smallest mailbox number has the highest priority.
>> The other possible Tx mailbox selection rule (not used by the driver
>> now) is ID priority transmit mode (as defined in the ISO 11898-1 specs).
>> The algorithm used guarantees the mailboxes are filled sequentially.

    Well, not quite, unfortunately -- it wraps at the last mailbox...

> I see. You are using mier1 to track the used mailboxes....correct?

    Yes, the mailbox interrupts in MIER1 are enabled only for used mailboxes.

>> +	if (unlikely(mier1 = 0xffffffff))
>> +		netif_stop_queue(ndev);

> Then you have a race condition in your tx-complete handler
> rcar_can_tx_done(), as you call netif_wake_queue() unconditionally. If

    Yes, I'm seeing it now...

> mier1 = 0xffffffff you must wait until _all_ mailboxes are transmitted

    That 0xffffffff criterion seems wrong for me now, I changed the algorithm 
and moved the criterion but didn't update it. The correct one seems to be:

	if (unlikely(mier1 & 0x80000000))
		netif_stop_queue(ndev);

> until you are allowed to reenable the mailboxes. Have a look at the
> at91_can driver, it's using a similar scheme. The lowest mailbox is
> transmitted first, but there are three additional bits that indicate the
> priority.

    You mean 4 bits? Priorities are from 0 to 15...

>> I've used 'canfdtest' as suggested by Wolfgang Grandegger to verify, see
>> the log below:

>> root@am335x-evm:~# ./canfdtest -v -g can0
>> interface = can0, family = 29, type = 3, proto = 1
>> ...............................................................................C
>>
>> Test messages sent and received: 483203
>> Exiting...
>> root@am335x-evm:~#

    As you can see, 'canfdtest' didn't detect any race, maybe you could 
recommend a test which would help to detect it?

>> [...]
>>>> +static int rcar_can_rx_poll(struct napi_struct *napi, int quota)
>>>> +{
>>>> +    struct rcar_can_priv *priv = container_of(napi,
>>>> +                          struct rcar_can_priv, napi);
>>>> +    int num_pkts = 0;
>>>> +
>>>> +    /* Find mailbox */
>>>> +    while (num_pkts < quota) {
>>>> +        u8 mctl, mbx;
>>>> +
>>>> +        mbx = readb(&priv->regs->mssr);

>>> How does the RX work? Is it a hardware FIFO?

>>     In short, the MSSR register provides the smallest Rx mailbox number
>> that is looked up in the Rx search mode. We read MSSR until no search
>> results can be obtained, so it is some sort of FIFO.

> This looks racy....

    Could you please elaborate?

>>     And there is separate FIFO operation mode: some mailboxes can be
>> configured as FIFO and serviced by special registers but this operation
>> mode is not supported by the driver.

> if you hardware supports a real FIFO then I strongly suggest to make use
> of it.

    Well, Tx/Rx FIFOs are only 4 frames deep (although I haven't seen more 
than 2 Rx mailboxes ready in a row, there are 32 Tx mailboxes); also FIFO mode 
is less documented than mailbox mode (hence some nasty surprises are 
possible). We still can use mailboxes when in FIFO mode, it's just 8 of them 
are reserved for Tx/Rx FIFOs.

>> [...]
>>>> +static int rcar_can_probe(struct platform_device *pdev)
>>>> +{
[...]
>>>> +    ndev->netdev_ops = &rcar_can_netdev_ops;
>>>> +    ndev->irq = irq;
>>>> +    ndev->flags |= IFF_ECHO;
>>>> +    priv->ndev = ndev;
>>>> +    priv->regs = addr;
>>>> +    priv->clock_select = pdata->clock_select;
>>>> +    priv->can.clock.freq = clk_get_rate(priv->clk);
>>>> +    priv->can.bittiming_const = &rcar_can_bittiming_const;
>>>> +    priv->can.do_set_bittiming = rcar_can_set_bittiming;

>>> Please call this function directly during the open() function.

>>     OK, done, and the method installation was removed. However, I'm not
>> sure why you requested this as many drivers are still using the method.

> The callback was there from the beginning, but then we figured out that
> we don't need it in the driver, but no one has cleaned up the drivers
> yet. So don't use it in new drivers. I know it's not documented anywhere :(

    You should have clarified that in your first review -- that would have 
prevented me from going the wrong way...

> regards,
> Marc

WBR, Sergei


  reply	other threads:[~2013-11-08 22:54 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-01 22:41 [PATCH v3] can: add Renesas R-Car CAN driver Sergei Shtylyov
2013-11-01 23:40 ` Sergei Shtylyov
2013-11-03 20:11 ` Marc Kleine-Budde
2013-11-03 20:11   ` Marc Kleine-Budde
2013-11-07 22:57   ` Sergei Shtylyov
2013-11-07 23:57     ` Sergei Shtylyov
2013-11-08  9:17     ` Marc Kleine-Budde
2013-11-08  9:17       ` Marc Kleine-Budde
2013-11-08 21:54       ` Sergei Shtylyov [this message]
2013-11-08 22:54         ` Sergei Shtylyov
2013-11-10 17:57         ` Marc Kleine-Budde
2013-11-10 17:57           ` Marc Kleine-Budde

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=527D6B88.3010409@cogentembedded.com \
    --to=sergei.shtylyov@cogentembedded.com \
    --cc=linux-can@vger.kernel.org \
    --cc=linux-sh@vger.kernel.org \
    --cc=mkl@pengutronix.de \
    --cc=netdev@vger.kernel.org \
    --cc=vksavl@gmail.com \
    --cc=wg@grandegger.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.