public inbox for linux-arm-kernel@lists.infradead.org 
 help / color / mirror / Atom feed
From: dingtianhong@huawei•com (Ding Tianhong)
To: linux-arm-kernel@lists•infradead.org
Subject: [PATCH net-next 0/6] net: hip04: fix some problem for hip04 drivers
Date: Thu, 16 Apr 2015 14:28:14 +0800	[thread overview]
Message-ID: <552F567E.6060808@huawei.com> (raw)
In-Reply-To: <3635761.IYy1QBa93a@wuerfel>

On 2015/4/15 22:25, Arnd Bergmann wrote:
> On Wednesday 15 April 2015 20:30:02 Ding Tianhong wrote:
>> The patches series was used to fix the issues of the hip04 driver, and added
>> some optimizations according to some good suggestion. 
>>
>>
> 
> Thanks, that looks much better, except for patch 4 that I commented on.
> 
I will check and fix it.

> I had at some point sent a patch that is archived at
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/318120.html
> 
> I believe that one is also still needed, but I have not tested whether it
> is correct. Can you have a look at the patch from back then and see if it
> works, of if you find something wrong about it?
> 
> I'm sending the unmodified patch from then here again for you to apply
> or comment. It will have to be rebased on top of your current changes.
> 
> 	Arnd
> 

Thanks for the suggestion, I notices that I miss this patch in my series from the maillist, 
I need time to check the code and try to test it, thanks for the work.:)

Ding

> 8<----
> Subject: [PATCH] net/hip04: refactor interrupt masking
> 
> The hip04 ethernet driver currently acknowledges all interrupts directly
> in the interrupt handler, and leaves all interrupts except the RX data
> enabled the whole time. This causes multiple problems:
> 
> - When more packets come in between the original interrupt and the
>   NAPI poll function, we will get an extraneous RX interrupt as soon
>   as interrupts are enabled again.
> 
> - The two error interrupts are by definition combining all errors that
>   may have happened since the last time they were handled, but just
>   acknowledging the irq without dealing with the cause of the condition
>   makes it come back immediately. In particular, when NAPI is intentionally
>   stalling the rx queue, this causes a storm of "rx dropped" messages.  
> 
> - The access to the 'reg_inten' field in hip_priv is used for serializing
>   access, but is in fact racy itself.
> 
> To deal with these issues, the driver is changed to only acknowledge
> the IRQ at the point when it is being handled. The RX interrupts now get
> acked right before reading the number of received frames to keep spurious
> interrupts to the absolute minimum without losing interrupts.
> 
> As there is no tx-complete interrupt, only an informational tx-dropped
> one, we now ack that in the tx reclaim handler, hoping that clearing
> the descriptors has also eliminated the error condition.
> 
> The only place that reads the reg_inten now just relies on
> napi_schedule_prep() to return whether NAPI is active or not, and
> the poll() function is then going to ack and reenabled the IRQ if
> necessary.
> 
> Finally, when we disable interrupts, they are now all disabled
> together, in order to simplify the logic and to avoid getting
> rx-dropped interrupts when NAPI is in control of the rx queue.
> 
> Signed-off-by: Arnd Bergmann <arnd@arndb•de>
> 
> diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c
> index 525214ef5984..83773247a368 100644
> --- a/drivers/net/ethernet/hisilicon/hip04_eth.c
> +++ b/drivers/net/ethernet/hisilicon/hip04_eth.c
> @@ -56,6 +56,8 @@
>  #define RCV_DROP                       BIT(7)
>  #define TX_DROP                                BIT(6)
>  #define DEF_INT_ERR                    (RCV_NOBUF | RCV_DROP | TX_DROP)
> +#define DEF_INT_RX                     (RCV_INT | RCV_NOBUF | RCV_DROP)
> +#define DEF_INT_TX                     (TX_DROP)
>  #define DEF_INT_MASK                   (RCV_INT | DEF_INT_ERR)
>  
>  /* TX descriptor config */
> @@ -154,7 +156,6 @@ struct hip04_priv {
>         unsigned int port;
>         unsigned int speed;
>         unsigned int duplex;
> -       unsigned int reg_inten;
>  
>         struct napi_struct napi;
>         struct net_device *ndev;
> @@ -303,17 +304,15 @@ static void hip04_mac_enable(struct net_device *ndev)
>         val |= GE_RX_PORT_EN | GE_TX_PORT_EN;
>         writel_relaxed(val, priv->base + GE_PORT_EN);
>  
> -       /* clear rx int */
> -       val = RCV_INT;
> -       writel_relaxed(val, priv->base + PPE_RINT);
> +       /* clear prior interrupts */
> +       writel_relaxed(DEF_INT_MASK, priv->base + PPE_RINT);
>  
>         /* config recv int */
>         val = GE_RX_INT_THRESHOLD | GE_RX_TIMEOUT;
>         writel_relaxed(val, priv->base + PPE_CFG_RX_PKT_INT);
>  
>         /* enable interrupt */
> -       priv->reg_inten = DEF_INT_MASK;
> -       writel_relaxed(priv->reg_inten, priv->base + PPE_INTEN);
> +       writel_relaxed(DEF_INT_MASK, priv->base + PPE_INTEN);
>  }
>  
>  static void hip04_mac_disable(struct net_device *ndev)
> @@ -322,8 +321,7 @@ static void hip04_mac_disable(struct net_device *ndev)
>         u32 val;
>  
>         /* disable int */
> -       priv->reg_inten &= ~(DEF_INT_MASK);
> -       writel_relaxed(priv->reg_inten, priv->base + PPE_INTEN);
> +       writel_relaxed(0, priv->base + PPE_INTEN);
>  
>         /* disable tx & rx */
>         val = readl_relaxed(priv->base + GE_PORT_EN);
> @@ -403,6 +401,8 @@ static int hip04_tx_reclaim(struct net_device *ndev, bool force)
>         priv->tx_tail = tx_tail;
>         smp_wmb(); /* Ensure tx_tail visible to xmit */
>  
> +       writel_relaxed(DEF_INT_TX, priv->base + PPE_RINT);
> +
>  out:
>         if (pkts_compl || bytes_compl)
>                 netdev_completed_queue(ndev, pkts_compl, bytes_compl);
> @@ -458,9 +458,7 @@ static int hip04_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
>         if (count >= priv->tx_coalesce_frames) {
>                 if (napi_schedule_prep(&priv->napi)) {
>                         /* disable rx interrupt and timer */
> -                       priv->reg_inten &= ~(RCV_INT);
> -                       writel_relaxed(DEF_INT_MASK & ~RCV_INT,
> -                                      priv->base + PPE_INTEN);
> +                       writel_relaxed(0, priv->base + PPE_INTEN);
>                         hrtimer_cancel(&priv->tx_coalesce_timer);
>                         __napi_schedule(&priv->napi);
>                 }
> @@ -478,7 +476,7 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget)
>         struct hip04_priv *priv = container_of(napi, struct hip04_priv, napi);
>         struct net_device *ndev = priv->ndev;
>         struct net_device_stats *stats = &ndev->stats;
> -       unsigned int cnt = hip04_recv_cnt(priv);
> +       unsigned int cnt;
>         struct rx_desc *desc;
>         struct sk_buff *skb;
>         unsigned char *buf;
> @@ -489,6 +487,10 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget)
>         u16 len;
>         u32 err;
>  
> +       /* acknowledge interrupts and read status */
> +       writel_relaxed(DEF_INT_RX, priv->base + PPE_RINT);
> +       cnt = hip04_recv_cnt(priv);
> +
>         while (cnt && !last) {
>                 buf = priv->rx_buf[priv->rx_head];
>                 skb = build_skb(buf, priv->rx_buf_size);
> @@ -539,11 +541,8 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget)
>                         cnt = hip04_recv_cnt(priv);
>         }
>  
> -       if (!(priv->reg_inten & RCV_INT)) {
> -               /* enable rx interrupt */
> -               priv->reg_inten |= RCV_INT;
> -               writel_relaxed(priv->reg_inten, priv->base + PPE_INTEN);
> -       }
> +       /* enable rx interrupt */
> +       writel_relaxed(DEF_INT_MASK, priv->base + PPE_INTEN);
>         napi_complete(napi);
>  done:
>         /* clean up tx descriptors and start a new timer if necessary */
> @@ -564,23 +563,21 @@ static irqreturn_t hip04_mac_interrupt(int irq, void *dev_id)
>         if (!ists)
>                 return IRQ_NONE;
>  
> -       writel_relaxed(DEF_INT_MASK, priv->base + PPE_RINT);
> -
>         if (unlikely(ists & DEF_INT_ERR)) {
> -               if (ists & (RCV_NOBUF | RCV_DROP))
> +               if (ists & (RCV_NOBUF | RCV_DROP)) {
>                         stats->rx_errors++;
>                         stats->rx_dropped++;
> -                       netdev_err(ndev, "rx drop\n");
> +                       netdev_dbg(ndev, "rx drop\n");
> +               }
>                 if (ists & TX_DROP) {
>                         stats->tx_dropped++;
> -                       netdev_err(ndev, "tx drop\n");
> +                       netdev_dbg(ndev, "tx drop\n");
>                 }
>         }
>  
> -       if (ists & RCV_INT && napi_schedule_prep(&priv->napi)) {
> -               /* disable rx interrupt */
> -               priv->reg_inten &= ~(RCV_INT);
> -               writel_relaxed(DEF_INT_MASK & ~RCV_INT, priv->base + PPE_INTEN);
> +       if (napi_schedule_prep(&priv->napi)) {
> +               /* disable interrupt */
> +               writel_relaxed(0, priv->base + PPE_INTEN);
>                 hrtimer_cancel(&priv->tx_coalesce_timer);
>                 __napi_schedule(&priv->napi);
>         }
> @@ -596,8 +593,7 @@ enum hrtimer_restart tx_done(struct hrtimer *hrtimer)
>  
>         if (napi_schedule_prep(&priv->napi)) {
>                 /* disable rx interrupt */
> -               priv->reg_inten &= ~(RCV_INT);
> -               writel_relaxed(DEF_INT_MASK & ~RCV_INT, priv->base + PPE_INTEN);
> +               writel_relaxed(0, priv->base + PPE_INTEN);
>                 __napi_schedule(&priv->napi);
>         }
>  
> 
> .
> 

      reply	other threads:[~2015-04-16  6:28 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-15 12:30 [PATCH net-next 0/6] net: hip04: fix some problem for hip04 drivers Ding Tianhong
2015-04-15 12:30 ` [PATCH net-next 1/6] net: hip04: Set more appropriate value for tx coalesce num Ding Tianhong
2015-04-15 14:11   ` Arnd Bergmann
2015-04-15 12:30 ` [PATCH net-next 2/6] net: hip04: use the big endian for tx and rx desc Ding Tianhong
2015-04-15 14:13   ` Arnd Bergmann
2015-04-16  6:25     ` Ding Tianhong
2015-04-15 12:30 ` [PATCH net-next 3/6] net: hip04: Solve the problem of the skb memory allocation failure Ding Tianhong
2015-04-15 14:17   ` Arnd Bergmann
2015-04-15 12:30 ` [PATCH net-next 4/6] net: hip04: Don't free the tx skb when the buffer is not ready for xmit Ding Tianhong
2015-04-15 14:19   ` Arnd Bergmann
2015-04-16  6:26     ` Ding Tianhong
2015-04-16  8:41       ` Arnd Bergmann
2015-04-16  9:38         ` Ding Tianhong
2015-04-15 12:30 ` [PATCH net-next 5/6] net: hip04: remove the unnecessary check Ding Tianhong
2015-04-15 14:14   ` Arnd Bergmann
2015-04-15 12:30 ` [PATCH net-next 6/6] net: hip04: add ratelimit for rx/tx drops skb Ding Tianhong
2015-04-15 14:20   ` Arnd Bergmann
2015-04-15 14:25 ` [PATCH net-next 0/6] net: hip04: fix some problem for hip04 drivers Arnd Bergmann
2015-04-16  6:28   ` Ding Tianhong [this message]

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=552F567E.6060808@huawei.com \
    --to=dingtianhong@huawei$(echo .)com \
    --cc=linux-arm-kernel@lists$(echo .)infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox