On Mon, Jul 01, 2019 at 12:03:27PM +0200, Antoine Tenart wrote:

> +static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
> +{
> +     struct ocelot *ocelot = arg;
> +
> +     do {
> +             struct skb_shared_hwtstamps shhwtstamps;
> +             struct list_head *pos, *tmp;
> +             struct ocelot_skb *entry;
> +             struct ocelot_port *port;
> +             struct timespec64 ts;
> +             struct sk_buff *skb = NULL;
> +             u32 val, id, txport;
> +
> +             val = ocelot_read(ocelot, SYS_PTP_STATUS);
> +
> +             /* Check if a timestamp can be retrieved */
> +             if (!(val & SYS_PTP_STATUS_PTP_MESS_VLD))
> +                     break;

Instead of an infinite do/while loop, I suggest a for loop bounded by
number of iterations or by execution time.  That would avoid getting
stuck here forever.  After all, this code is an ISR.

Thanks,
Richard

> +             WARN_ON(val & SYS_PTP_STATUS_PTP_OVFL);
> +
> +             /* Retrieve the ts ID and Tx port */
> +             id = SYS_PTP_STATUS_PTP_MESS_ID_X(val);
> +             txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val);
> +
> +             /* Retrieve its associated skb */
> +             port = ocelot->ports[txport];
> +
> +             list_for_each_safe(pos, tmp, &port->skbs) {
> +                     entry = list_entry(pos, struct ocelot_skb, head);
> +                     if (entry->id != id)
> +                             continue;
> +
> +                     skb = entry->skb;
> +
> +                     list_del(pos);
> +                     kfree(entry);
> +             }
> +
> +             /* Next ts */
> +             ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);
> +
> +             if (unlikely(!skb))
> +                     continue;
> +
> +             /* Get the h/w timestamp */
> +             ocelot_get_hwtimestamp(ocelot, &ts);
> +
> +             /* Set the timestamp into the skb */
> +             memset(&shhwtstamps, 0, sizeof(shhwtstamps));
> +             shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
> +             skb_tstamp_tx(skb, &shhwtstamps);
> +
> +             dev_kfree_skb_any(skb);
> +     } while (true);
> +
> +     return IRQ_HANDLED;
> +}

Reply via email to