From: Corinna Vinschen <vinschen@redhat.com>
To: romieu@fr.zoreil.com, netdev@vger.kernel.org,
David Miller <davem@davemloft.net>,
pomidorabelisima@gmail.com
Subject: Re: [PATCH net 3/3] r8169: increase the lifespan of the hardware counters dump area.
Date: Mon, 7 Sep 2015 16:44:12 +0200 [thread overview]
Message-ID: <20150907144412.GA26524@calimero.vinschen.de> (raw)
In-Reply-To: <20150906103732.GF30539@calimero.vinschen.de>
[-- Attachment #1: Type: text/plain, Size: 5041 bytes --]
On Sep 6 12:37, Corinna Vinschen wrote:
> On Sep 5 14:18, romieu@fr.zoreil.com wrote:
> > From: Francois Romieu <romieu@fr.zoreil.com>
> >
> > net/core/net-sysfs.c::netstat_show retrieves stats with spinlock held.
> >
> > This change avoids sleepable allocation and performs some housekeeping:
> > - receive ring, transmit ring and counters dump area allocation failures
> > are all considered fatal during open()
> > - netif_warn is now redundant with rtl_reset_counters_cond built-in
> > failure message.
> > - rtl_reset_counters_cond induced failures in open() are also considered
> > fatal: it takes acceptable work to unwind comfortably.
>
> Why? The counter reset is not a fatal condition for the operation of
> the NIC. Even if the counters show incorrect values, the normal
> operation of the NIC is not affected. And to top that off, even if
> resetting the counters actually doesn't work, the driver keeps the
> offset values, so a failed reset won't even harm the statistics. It
> just doesn't make sense to break the NIC operation for such a minor
> problem. And worse:
>
> > -static bool rtl8169_reset_counters(struct net_device *dev)
> > +static int rtl8169_reset_counters(struct net_device *dev)
> > {
> > struct rtl8169_private *tp = netdev_priv(dev);
> > - struct rtl8169_counters *counters;
> > - dma_addr_t paddr;
> > - bool ret = true;
> >
> > /*
> > * Versions prior to RTL_GIGA_MAC_VER_19 don't support resetting the
> > * tally counters.
> > */
> > if (tp->mac_version < RTL_GIGA_MAC_VER_19)
> > - return true;
> > -
> > - counters = rtl8169_map_counters(dev, &paddr, CounterReset);
> > - if (!counters)
> > - return false;
> > -
> > - if (!rtl_udelay_loop_wait_low(tp, &rtl_reset_counters_cond, 10, 1000))
> > - ret = false;
> > -
> > - rtl8169_unmap_counters(dev, paddr, counters);
> > + return -EINVAL;
>
> This returns -EINVAL even for older chip versions which are not capable
> of resetting the counters. The result is, this driver will not work at
> all on chip versions prior to RTL_GIGA_MAC_VER_19 anymore, because
> rtl_open will always fail.
>
> Other then that, I can test the patch probably tomorrow.
I have a bit of a problem with this patch. It crashes when loading the
driver manually w/ modprobe. For some reason dev_get_stats is called
during rtl_init_one and at that time the counters pointer is NULL, so
the kernel gets a SEGV. After I worked around that I got a SEGV in
rtl_remove_one, which I still have to find out why. I didn't test with
the latest kernel, though, so I still have to check if that's the reason
for the crashes. That takes a bit longer, I just wanted to let you
know.
There's also a problem with rtl8169_cmd_counters: It always calls
rtl_udelay_loop_wait_low w/ rtl_reset_counters_cond, even when called
from rtl8169_update_counters, where it should call
rtl_udelay_loop_wait_low w/ rtl_counters_cond to check for the
CounterDump flag, rather than for the CounterReset flag.
For now I applied the below patch, but I think it's a bit ugly to
conditionalize the rtl_cond struct by the incoming flag value.
Corinna
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index ae07567..cd7adbf 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -2200,6 +2200,13 @@ DECLARE_RTL_COND(rtl_reset_counters_cond)
return RTL_R32(CounterAddrLow) & CounterReset;
}
+DECLARE_RTL_COND(rtl_counters_cond)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return RTL_R32(CounterAddrLow) & CounterDump;
+}
+
static int rtl8169_cmd_counters(struct net_device *dev, u32 counter_cmd)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -2212,7 +2219,10 @@ static int rtl8169_cmd_counters(struct net_device *dev, u32 counter_cmd)
RTL_W32(CounterAddrLow, cmd);
RTL_W32(CounterAddrLow, cmd | counter_cmd);
- return rtl_udelay_loop_wait_low(tp, &rtl_reset_counters_cond, 10, 1000);
+ return rtl_udelay_loop_wait_low(tp,
+ counter_cmd == CounterDump ? &rtl_counters_cond :
+ &rtl_reset_counters_cond,
+ 10, 1000);
}
static int rtl8169_reset_counters(struct net_device *dev)
@@ -2229,13 +2239,6 @@ static int rtl8169_reset_counters(struct net_device *dev)
return rtl8169_cmd_counters(dev, CounterReset);
}
-DECLARE_RTL_COND(rtl_counters_cond)
-{
- void __iomem *ioaddr = tp->mmio_addr;
-
- return RTL_R32(CounterAddrLow) & CounterDump;
-}
-
static int rtl8169_update_counters(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -7800,8 +7803,11 @@ rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
/*
* Fetch additonal counter values missing in stats collected by driver
- * from tally counters.
+ * from tally counters, but only if we're already initialized.
*/
+ if (!counters)
+ return stats;
+
rtl8169_update_counters(dev);
/*
[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]
next prev parent reply other threads:[~2015-09-07 14:44 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-05 12:18 [PATCH net 0/3] r8169: fix sleepable allocation during netdevice stats retrieval romieu
2015-09-05 12:18 ` [PATCH net 1/3] r8169: decouple the counters data and the device private area romieu
2015-09-06 10:38 ` Corinna Vinschen
2015-09-05 12:18 ` [PATCH net 2/3] r8169: move rtl_reset_counters_cond before the hardware counters helpers romieu
2015-09-05 12:18 ` [PATCH net 3/3] r8169: increase the lifespan of the hardware counters dump area romieu
2015-09-06 10:37 ` Corinna Vinschen
2015-09-06 20:21 ` Francois Romieu
2015-09-07 7:05 ` David Miller
2015-09-07 9:29 ` Corinna Vinschen
2015-09-08 0:00 ` David Miller
2015-09-08 8:05 ` Corinna Vinschen
2015-09-07 14:44 ` Corinna Vinschen [this message]
2015-09-07 21:52 ` Francois Romieu
2015-09-08 0:02 ` Francois Romieu
2015-09-08 20:23 ` Corinna Vinschen
2015-09-08 23:27 ` Francois Romieu
2015-09-09 9:00 ` Corinna Vinschen
2015-09-08 8:09 ` Corinna Vinschen
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=20150907144412.GA26524@calimero.vinschen.de \
--to=vinschen@redhat.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=pomidorabelisima@gmail.com \
--cc=romieu@fr.zoreil.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).