From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
To: Yoshihiro Kaneko <ykaneko0929@gmail.com>, netdev@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>,
Simon Horman <horms@verge.net.au>,
Magnus Damm <magnus.damm@gmail.com>,
linux-sh@vger.kernel.org
Subject: Re: [PATCH/RFC v4 net-next] ravb: Add dma queue interrupt support
Date: Thu, 28 Jan 2016 16:48:52 +0000 [thread overview]
Message-ID: <56AA4674.6020001@cogentembedded.com> (raw)
In-Reply-To: <1453650775-19886-1-git-send-email-ykaneko0929@gmail.com>
Hello.
On 01/24/2016 06:52 PM, Yoshihiro Kaneko wrote:
> From: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
>
> This patch supports the following interrupts.
>
> - One interrupt for multiple (descriptor, error, management)
> - One interrupt for emac
> - Four interrupts for dma queue (best effort rx/tx, network control rx/tx)
>
> This patch improve efficiency of the interrupt handler by adding the
> interrupt handler corresponding to each interrupt source described
> above. Additionally, it reduces the number of times of the access to
> EthernetAVB IF.
>
> Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
> Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
> ---
>
> This patch is based on the master branch of David Miller's next networking
> tree.
>
> v4 [Yoshihiro Kaneko]
> * compile tested only
> * As suggested by Sergei Shtylyov
> drivers/net/ethernet/renesas/ravb.h:
> - make two lines of comment into one line.
> - remove unused definition of xxx_ALL.
> drivers/net/ethernet/renesas/ravb_main.c:
> - remove unrelated change (fix indentation).
> - output warning messages when napi_schedule_prep() fails in ravb_dmaq_
> interrupt() like ravb_interrupt().
> - change the function name from req_irq to hook_irq.
> - fix programming error in hook_irq().
> - do free_irq() for rx_irqs[] and tx_irqs[] for only gen3 in out_free_
> irq label in ravb_open().
>
> v3 [Yoshihiro Kaneko]
> * compile tested only
> * As suggested by Sergei Shtylyov
> - update changelog
> drivers/net/ethernet/renesas/ravb.h:
> - add comments to the additional registers like CIE
> drivers/net/ethernet/renesas/ravb_main.c:
> - fix the initialization of the interrupt in ravb_dmac_init()
> - revert ravb_error_interrupt() because gen3 code is wrong
> - change the comment "Management" in ravb_multi_interrupt()
> - add a helper function for request_irq() in ravb_open()
> - revert ravb_close() because atomicity is not necessary here
> drivers/net/ethernet/renesas/ravb_ptp.c:
> - revert ravb_ptp_stop() because atomicity is not necessary here
>
> v2 [Yoshihiro Kaneko]
> * compile tested only
> * As suggested by Sergei Shtylyov
> - add comment to CIE
> - remove comments from CIE bits
> - fix value of TIx_ALL
> - define each bits for CIE, GIE, GID, RIE0, RID0, RIE2, RID2, TIE, TID
> - reversed Christmas tree declaration ordered
> - rename _ravb_emac_interrupt() to ravb_emac_interrupt_unlocked()
> - remove unnecessary clearing of CIE
> - use a bit name corresponding to the target register, RIE0, RIE2, TIE,
> TID, RID2, GID, GIE
As I already noted, the changes made to the original patch are supposed to
be documented above --- (no need to separate diff versions there though).
Either that, or just say that it's your patch, based on Mizuguchi-san's
work (the amount of changes makes that possible, I think).
[...]
> diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
> index ac43ed9..076f25f 100644
> --- a/drivers/net/ethernet/renesas/ravb_main.c
> +++ b/drivers/net/ethernet/renesas/ravb_main.c
[...]
> +static irqreturn_t ravb_dmaq_interrupt(int irq, void *dev_id, int ravb_queue)
> +{
> + struct net_device *ndev = dev_id;
> + struct ravb_private *priv = netdev_priv(ndev);
> + irqreturn_t result = IRQ_NONE;
> + u32 ris0, ric0, tis, tic;
> + int q = ravb_queue;
Just give a shorter name to the 'ravb_queue' parameter, no need to copy it.
> +
> + spin_lock(&priv->lock);
> +
> + ris0 = ravb_read(ndev, RIS0);
> + ric0 = ravb_read(ndev, RIC0);
> + tis = ravb_read(ndev, TIS);
> + tic = ravb_read(ndev, TIC);
> +
> + /* Timestamp updated */
> + if (tis & TIS_TFUF) {
> + ravb_write(ndev, TID_TFUD, TID);
Wait, you're supposed to clear the TFUF interrupt, not to disable!
And with that fixed, this interrupt's handler could get factored out into a
function...
> + ravb_get_tx_tstamp(ndev);
> + result = IRQ_HANDLED;
> + }
> +
> + /* Best effort queue RX/TX */
> + if (((ris0 & ric0) & BIT(q)) ||
> + ((tis & tic) & BIT(q))) {
> + if (napi_schedule_prep(&priv->napi[q])) {
> + /* Mask RX and TX interrupts */
> + ravb_write(ndev, BIT(q), RID0);
> + ravb_write(ndev, BIT(q), TID);
> + __napi_schedule(&priv->napi[q]);
> + } else {
> + netdev_warn(ndev,
> + "ignoring interrupt, rx status 0x%08x, rx mask 0x%08x,\n",
> + ris0, ric0);
> + netdev_warn(ndev,
> + " tx status 0x%08x, tx mask 0x%08x.\n",
> + tis, tic);
> + }
> + result = IRQ_HANDLED;
> + }
In principle, this also can get factored out.
[...]
> @@ -1215,29 +1332,64 @@ static const struct ethtool_ops ravb_ethtool_ops = {
> .get_ts_info = ravb_get_ts_info,
> };
>
> +static inline int hook_irq(unsigned int irq, irq_handler_t handler,
Namespacing this function with 'ravb_' prefix would be preferable, I did
that for all functions, even those that didn't have this prefix in sh_eth...
> + struct net_device *ndev, struct device *dev,
> + const char *ch)
> +{
> + char *name;
> + int error;
> +
> + name = devm_kasprintf(dev, GFP_KERNEL, "%s:%s", ndev->name, ch);
> + error = request_irq(irq, handler, IRQF_SHARED, name, ndev);
Not sure if we need IRQF_SHARED on those IRQs, they're not really shareable...
[...]
> /* Network device open function for Ethernet AVB */
> static int ravb_open(struct net_device *ndev)
> {
> struct ravb_private *priv = netdev_priv(ndev);
> - int error;
> + struct platform_device *pdev = priv->pdev;
> + struct device *dev = &pdev->dev;
> + int error, i;
>
> napi_enable(&priv->napi[RAVB_BE]);
> napi_enable(&priv->napi[RAVB_NC]);
>
> - error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED, ndev->name,
> - ndev);
> - if (error) {
> - netdev_err(ndev, "cannot request IRQ\n");
> - goto out_napi_off;
> - }
> -
> - if (priv->chip_id = RCAR_GEN3) {
> - error = request_irq(priv->emac_irq, ravb_interrupt,
> - IRQF_SHARED, ndev->name, ndev);
> + if (priv->chip_id = RCAR_GEN2) {
> + error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED,
> + ndev->name, ndev);
> if (error) {
> netdev_err(ndev, "cannot request IRQ\n");
> - goto out_free_irq;
> + goto out_napi_off;
> }
> + } else {
> + error = hook_irq(ndev->irq, ravb_multi_interrupt, ndev, dev,
> + "ch22:multi");
> + if (error)
> + goto out_napi_off;
> + error = hook_irq(priv->emac_irq, ravb_emac_interrupt, ndev,
> + dev, "ch24:emac");
> + if (error)
> + goto out_free_irq;
> + error = hook_irq(priv->rx_irqs[RAVB_BE], ravb_be_interrupt,
> + ndev, dev, "ch0:rx_be");
> + if (error)
> + goto out_free_irq;
And you fail to call free_irq() for the EMAC IRQ... :-(
Sorry for not noticing this in a previous review.
> + error = hook_irq(priv->tx_irqs[RAVB_BE], ravb_be_interrupt,
> + ndev, dev, "ch18:tx_be");
> + if (error)
> + goto out_free_irq;
> + error = hook_irq(priv->rx_irqs[RAVB_NC], ravb_nc_interrupt,
> + ndev, dev, "ch1:rx_nc");
> + if (error)
> + goto out_free_irq;
> + error = hook_irq(priv->tx_irqs[RAVB_NC], ravb_nc_interrupt,
> + ndev, dev, "ch19:tx_nc");
> + if (error)
> + goto out_free_irq;
Same comment for all these *goto* statements...
[...]
> @@ -1268,6 +1420,12 @@ out_free_irq2:
> free_irq(priv->emac_irq, ndev);
> out_free_irq:
> free_irq(ndev->irq, ndev);
> + if (priv->chip_id = RCAR_GEN3) {
> + for (i = 0; i < NUM_RX_QUEUE; i++)
> + free_irq(priv->rx_irqs[i], ndev);
> + for (i = 0; i < NUM_TX_QUEUE; i++)
> + free_irq(priv->tx_irqs[i], ndev);
> + }
I'm afraid __free_irq() would complain anyway in case not all IRQs had
been successfully hooked... I don't have an easy recipe for fixing that... you
probably just shouldn't use loops here.
[...]
OK, I'll now proceed to sanity-testing this patch on the gen2 hardware.
MBR, Sergei
WARNING: multiple messages have this Message-ID (diff)
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
To: Yoshihiro Kaneko <ykaneko0929@gmail.com>, netdev@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>,
Simon Horman <horms@verge.net.au>,
Magnus Damm <magnus.damm@gmail.com>,
linux-sh@vger.kernel.org
Subject: Re: [PATCH/RFC v4 net-next] ravb: Add dma queue interrupt support
Date: Thu, 28 Jan 2016 19:48:52 +0300 [thread overview]
Message-ID: <56AA4674.6020001@cogentembedded.com> (raw)
In-Reply-To: <1453650775-19886-1-git-send-email-ykaneko0929@gmail.com>
Hello.
On 01/24/2016 06:52 PM, Yoshihiro Kaneko wrote:
> From: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
>
> This patch supports the following interrupts.
>
> - One interrupt for multiple (descriptor, error, management)
> - One interrupt for emac
> - Four interrupts for dma queue (best effort rx/tx, network control rx/tx)
>
> This patch improve efficiency of the interrupt handler by adding the
> interrupt handler corresponding to each interrupt source described
> above. Additionally, it reduces the number of times of the access to
> EthernetAVB IF.
>
> Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
> Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
> ---
>
> This patch is based on the master branch of David Miller's next networking
> tree.
>
> v4 [Yoshihiro Kaneko]
> * compile tested only
> * As suggested by Sergei Shtylyov
> drivers/net/ethernet/renesas/ravb.h:
> - make two lines of comment into one line.
> - remove unused definition of xxx_ALL.
> drivers/net/ethernet/renesas/ravb_main.c:
> - remove unrelated change (fix indentation).
> - output warning messages when napi_schedule_prep() fails in ravb_dmaq_
> interrupt() like ravb_interrupt().
> - change the function name from req_irq to hook_irq.
> - fix programming error in hook_irq().
> - do free_irq() for rx_irqs[] and tx_irqs[] for only gen3 in out_free_
> irq label in ravb_open().
>
> v3 [Yoshihiro Kaneko]
> * compile tested only
> * As suggested by Sergei Shtylyov
> - update changelog
> drivers/net/ethernet/renesas/ravb.h:
> - add comments to the additional registers like CIE
> drivers/net/ethernet/renesas/ravb_main.c:
> - fix the initialization of the interrupt in ravb_dmac_init()
> - revert ravb_error_interrupt() because gen3 code is wrong
> - change the comment "Management" in ravb_multi_interrupt()
> - add a helper function for request_irq() in ravb_open()
> - revert ravb_close() because atomicity is not necessary here
> drivers/net/ethernet/renesas/ravb_ptp.c:
> - revert ravb_ptp_stop() because atomicity is not necessary here
>
> v2 [Yoshihiro Kaneko]
> * compile tested only
> * As suggested by Sergei Shtylyov
> - add comment to CIE
> - remove comments from CIE bits
> - fix value of TIx_ALL
> - define each bits for CIE, GIE, GID, RIE0, RID0, RIE2, RID2, TIE, TID
> - reversed Christmas tree declaration ordered
> - rename _ravb_emac_interrupt() to ravb_emac_interrupt_unlocked()
> - remove unnecessary clearing of CIE
> - use a bit name corresponding to the target register, RIE0, RIE2, TIE,
> TID, RID2, GID, GIE
As I already noted, the changes made to the original patch are supposed to
be documented above --- (no need to separate diff versions there though).
Either that, or just say that it's your patch, based on Mizuguchi-san's
work (the amount of changes makes that possible, I think).
[...]
> diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
> index ac43ed9..076f25f 100644
> --- a/drivers/net/ethernet/renesas/ravb_main.c
> +++ b/drivers/net/ethernet/renesas/ravb_main.c
[...]
> +static irqreturn_t ravb_dmaq_interrupt(int irq, void *dev_id, int ravb_queue)
> +{
> + struct net_device *ndev = dev_id;
> + struct ravb_private *priv = netdev_priv(ndev);
> + irqreturn_t result = IRQ_NONE;
> + u32 ris0, ric0, tis, tic;
> + int q = ravb_queue;
Just give a shorter name to the 'ravb_queue' parameter, no need to copy it.
> +
> + spin_lock(&priv->lock);
> +
> + ris0 = ravb_read(ndev, RIS0);
> + ric0 = ravb_read(ndev, RIC0);
> + tis = ravb_read(ndev, TIS);
> + tic = ravb_read(ndev, TIC);
> +
> + /* Timestamp updated */
> + if (tis & TIS_TFUF) {
> + ravb_write(ndev, TID_TFUD, TID);
Wait, you're supposed to clear the TFUF interrupt, not to disable!
And with that fixed, this interrupt's handler could get factored out into a
function...
> + ravb_get_tx_tstamp(ndev);
> + result = IRQ_HANDLED;
> + }
> +
> + /* Best effort queue RX/TX */
> + if (((ris0 & ric0) & BIT(q)) ||
> + ((tis & tic) & BIT(q))) {
> + if (napi_schedule_prep(&priv->napi[q])) {
> + /* Mask RX and TX interrupts */
> + ravb_write(ndev, BIT(q), RID0);
> + ravb_write(ndev, BIT(q), TID);
> + __napi_schedule(&priv->napi[q]);
> + } else {
> + netdev_warn(ndev,
> + "ignoring interrupt, rx status 0x%08x, rx mask 0x%08x,\n",
> + ris0, ric0);
> + netdev_warn(ndev,
> + " tx status 0x%08x, tx mask 0x%08x.\n",
> + tis, tic);
> + }
> + result = IRQ_HANDLED;
> + }
In principle, this also can get factored out.
[...]
> @@ -1215,29 +1332,64 @@ static const struct ethtool_ops ravb_ethtool_ops = {
> .get_ts_info = ravb_get_ts_info,
> };
>
> +static inline int hook_irq(unsigned int irq, irq_handler_t handler,
Namespacing this function with 'ravb_' prefix would be preferable, I did
that for all functions, even those that didn't have this prefix in sh_eth...
> + struct net_device *ndev, struct device *dev,
> + const char *ch)
> +{
> + char *name;
> + int error;
> +
> + name = devm_kasprintf(dev, GFP_KERNEL, "%s:%s", ndev->name, ch);
> + error = request_irq(irq, handler, IRQF_SHARED, name, ndev);
Not sure if we need IRQF_SHARED on those IRQs, they're not really shareable...
[...]
> /* Network device open function for Ethernet AVB */
> static int ravb_open(struct net_device *ndev)
> {
> struct ravb_private *priv = netdev_priv(ndev);
> - int error;
> + struct platform_device *pdev = priv->pdev;
> + struct device *dev = &pdev->dev;
> + int error, i;
>
> napi_enable(&priv->napi[RAVB_BE]);
> napi_enable(&priv->napi[RAVB_NC]);
>
> - error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED, ndev->name,
> - ndev);
> - if (error) {
> - netdev_err(ndev, "cannot request IRQ\n");
> - goto out_napi_off;
> - }
> -
> - if (priv->chip_id == RCAR_GEN3) {
> - error = request_irq(priv->emac_irq, ravb_interrupt,
> - IRQF_SHARED, ndev->name, ndev);
> + if (priv->chip_id == RCAR_GEN2) {
> + error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED,
> + ndev->name, ndev);
> if (error) {
> netdev_err(ndev, "cannot request IRQ\n");
> - goto out_free_irq;
> + goto out_napi_off;
> }
> + } else {
> + error = hook_irq(ndev->irq, ravb_multi_interrupt, ndev, dev,
> + "ch22:multi");
> + if (error)
> + goto out_napi_off;
> + error = hook_irq(priv->emac_irq, ravb_emac_interrupt, ndev,
> + dev, "ch24:emac");
> + if (error)
> + goto out_free_irq;
> + error = hook_irq(priv->rx_irqs[RAVB_BE], ravb_be_interrupt,
> + ndev, dev, "ch0:rx_be");
> + if (error)
> + goto out_free_irq;
And you fail to call free_irq() for the EMAC IRQ... :-(
Sorry for not noticing this in a previous review.
> + error = hook_irq(priv->tx_irqs[RAVB_BE], ravb_be_interrupt,
> + ndev, dev, "ch18:tx_be");
> + if (error)
> + goto out_free_irq;
> + error = hook_irq(priv->rx_irqs[RAVB_NC], ravb_nc_interrupt,
> + ndev, dev, "ch1:rx_nc");
> + if (error)
> + goto out_free_irq;
> + error = hook_irq(priv->tx_irqs[RAVB_NC], ravb_nc_interrupt,
> + ndev, dev, "ch19:tx_nc");
> + if (error)
> + goto out_free_irq;
Same comment for all these *goto* statements...
[...]
> @@ -1268,6 +1420,12 @@ out_free_irq2:
> free_irq(priv->emac_irq, ndev);
> out_free_irq:
> free_irq(ndev->irq, ndev);
> + if (priv->chip_id == RCAR_GEN3) {
> + for (i = 0; i < NUM_RX_QUEUE; i++)
> + free_irq(priv->rx_irqs[i], ndev);
> + for (i = 0; i < NUM_TX_QUEUE; i++)
> + free_irq(priv->tx_irqs[i], ndev);
> + }
I'm afraid __free_irq() would complain anyway in case not all IRQs had
been successfully hooked... I don't have an easy recipe for fixing that... you
probably just shouldn't use loops here.
[...]
OK, I'll now proceed to sanity-testing this patch on the gen2 hardware.
MBR, Sergei
next prev parent reply other threads:[~2016-01-28 16:48 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-24 15:52 [PATCH/RFC v4 net-next] ravb: Add dma queue interrupt support Yoshihiro Kaneko
2016-01-24 15:52 ` Yoshihiro Kaneko
2016-01-26 0:23 ` Simon Horman
2016-01-26 0:23 ` Simon Horman
2016-01-26 19:00 ` Sergei Shtylyov
2016-01-26 19:00 ` Sergei Shtylyov
2016-01-27 1:49 ` Simon Horman
2016-01-27 1:49 ` Simon Horman
2016-01-28 15:50 ` Sergei Shtylyov
2016-01-28 15:50 ` Sergei Shtylyov
2016-01-28 18:36 ` Sergei Shtylyov
2016-01-28 18:36 ` Sergei Shtylyov
2016-01-28 16:48 ` Sergei Shtylyov [this message]
2016-01-28 16:48 ` Sergei Shtylyov
2016-02-07 16:50 ` Yoshihiro Kaneko
2016-02-07 16:50 ` Yoshihiro Kaneko
2016-02-07 17:09 ` Sergei Shtylyov
2016-02-07 17:09 ` Sergei Shtylyov
2016-02-08 17:19 ` Yoshihiro Kaneko
2016-02-08 17:19 ` Yoshihiro Kaneko
2016-02-21 15:42 ` Sergei Shtylyov
2016-02-21 15:42 ` Sergei Shtylyov
2016-02-21 19:16 ` Sergei Shtylyov
2016-02-21 19:16 ` Sergei Shtylyov
2016-02-25 22:22 ` Sergei Shtylyov
2016-02-25 22:22 ` Sergei Shtylyov
2016-01-28 17:32 ` Sergei Shtylyov
2016-01-28 17:32 ` Sergei Shtylyov
2016-02-07 16:56 ` Yoshihiro Kaneko
2016-02-07 16:56 ` Yoshihiro Kaneko
2016-02-07 17:18 ` Sergei Shtylyov
2016-02-07 17:18 ` Sergei Shtylyov
2016-01-28 17:51 ` Sergei Shtylyov
2016-01-28 17:51 ` Sergei Shtylyov
2016-02-07 17:18 ` Yoshihiro Kaneko
2016-02-07 17:18 ` Yoshihiro Kaneko
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=56AA4674.6020001@cogentembedded.com \
--to=sergei.shtylyov@cogentembedded.com \
--cc=davem@davemloft.net \
--cc=horms@verge.net.au \
--cc=linux-sh@vger.kernel.org \
--cc=magnus.damm@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=ykaneko0929@gmail.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.