[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAK8P3a08Bbzj9GtZi0Vo1-yRkqEMfnvTZMNEVWAn-gmLKx2Oag@mail.gmail.com>
Date: Mon, 31 May 2021 20:39:22 +0200
From: Arnd Bergmann <arnd@...nel.org>
To: Nikolai Zhubr <zhubr.2@...il.com>
Cc: netdev <netdev@...r.kernel.org>, Jeff Garzik <jgarzik@...ox.com>
Subject: Re: Realtek 8139 problem on 486.
On Mon, May 31, 2021 at 7:35 PM Nikolai Zhubr <zhubr.2@...il.com> wrote:
> @@ -2169,8 +2162,14 @@
> if (ackstat)
> RTL_W16 (IntrStatus, ackstat);
>
> - if (netif_running (dev) && (status & RxAckBits))
> - rtl8139_rx (dev, tp, 1000000000);
> + /* Receive packets are processed by poll routine.
> + If not running start it now. */
> + if (status & RxAckBits){
> + if (netif_rx_schedule_prep(dev)) {
> + RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
> + __netif_rx_schedule (dev);
> + }
> + }
Ok, so what you observe is that you get fewer interrupts because of NAPI,
and that TX times out, which points to a missing TX interrupt.
I looked at how the irq status and mask registers are handled, and did not
spot an obvious mistake there that would e.g. lead to the TX interrupts
being disabled or not acked while RX interrupts are disabled. (it does
seem odd that it both disables and defers the ack of the RX interrupts,
but that is probably harmless).
One possible issue is that the "RTL_W16 (IntrStatus, TxErr)" can
leak out of the spinlock unless it is changed to RTL_W16_F(), but
I don't see how that would cause your problem. This is probably
not the issue here, but it can't hurt to change that. Similarly,
the "RTL_W16 (IntrStatus, ackstat)" would need the same _F
to ensure that a normal TX-only interrupt gets acked before the
spinlock.
Another observation I have is that the loop used to be around
"RTL_R16(IntrStatus); rtl8139_rx(); rtl8139_tx_interrupt()", so
removing the loop also means that the tx handler is only called
once when it used to be called for every loop iteration.
If this is what triggers the problem, you should be able to break
it the same way by moving the rtl8139_tx_interrupt() ahead of the
loop, and adjusting the RTL_W16 (IntrStatus, ackstat) accordingly
so you only Ack the TX before calling rtl8139_tx_interrupt().
Arnd
Powered by blists - more mailing lists