Netdev List
 help / color / mirror / Atom feed
From: Vladimir Oltean <vladimir.oltean@nxp.com>
To: Colin Foster <colin.foster@in-advantage.com>
Cc: "netdev@vger.kernel.org" <netdev@vger.kernel.org>,
	Andrew Lunn <andrew@lunn.ch>,
	Vivien Didelot <vivien.didelot@gmail.com>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Claudiu Manoil <claudiu.manoil@nxp.com>,
	Alexandre Belloni <alexandre.belloni@bootlin.com>,
	"UNGLinuxDriver@microchip.com" <UNGLinuxDriver@microchip.com>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Maxim Kochetkov <fido_max@inbox.ru>
Subject: Re: [PATCH net 6/8] net: mscc: ocelot: make struct ocelot_stat_layout array indexable
Date: Wed, 17 Aug 2022 11:06:45 +0000	[thread overview]
Message-ID: <20220817110644.bhvzl7fslq2l6g23@skbuf> (raw)
In-Reply-To: <YvyO1kjPKPQM0Zw8@euler>

On Tue, Aug 16, 2022 at 11:46:46PM -0700, Colin Foster wrote:
> Hi Vladimir,
> 
> I'm not sure if this is an issue here, and I'm not sure it will ever
> be... ocelot_stat_layout as you know relies on consecutive register
> addresses to be most efficient. This was indirectly enforced by
> *_stats_layout[] always being laid out in ascending order.
> 
> If the order of ocelot_stat doesn't match each device's register
> offset order, there'll be unnecessary overhead. I tried to test
> this just now, but I'll have to deal with a few conflicts that I won't
> be able to get to immediately.
> 
> Do you see this as a potential issue in the future? Or do you expect all
> hardware is simliar enough that they'll all be ordered the same?
> 
> Or, because I'm the lucky one running on a slow SPI bus, this will be my
> problem to monitor and fix if need be :)

No, you're right and the bulk reads complicate things; in fact I'm not
sure that this patch even works by anything other than pure chance.

In some future changes I'm making the first N elements of the
struct ocelot_stat_layout array be common across all drivers. Only Felix
VSC9959 has some extra TSN-related counters which the others don't have.
It would look like this:

/* 32-bit counter checked for wraparound by ocelot_port_update_stats()
 * and copied to ocelot->stats.
 */
#define OCELOT_STAT(kind) \
	[OCELOT_STAT_ ## kind] = { .reg = SYS_COUNT_ ## kind }
/* Same as above, except also exported to ethtool -S. Standard counters should
 * only be exposed to more specific interfaces rather than by their string name.
 */
#define OCELOT_STAT_ETHTOOL(kind, ethtool_name) \
	[OCELOT_STAT_ ## kind] = { .reg = SYS_COUNT_ ## kind, .name = ethtool_name }

#define OCELOT_COMMON_STATS \
	OCELOT_STAT_ETHTOOL(RX_OCTETS, "rx_octets"), \
	OCELOT_STAT_ETHTOOL(RX_UNICAST, "rx_unicast"), \
	OCELOT_STAT_ETHTOOL(RX_MULTICAST, "rx_multicast"), \
	OCELOT_STAT_ETHTOOL(RX_BROADCAST, "rx_broadcast"), \
	OCELOT_STAT_ETHTOOL(RX_SHORTS, "rx_shorts"), \
	OCELOT_STAT_ETHTOOL(RX_FRAGMENTS, "rx_fragments"), \
	OCELOT_STAT_ETHTOOL(RX_JABBERS, "rx_jabbers"), \
	OCELOT_STAT_ETHTOOL(RX_CRC_ALIGN_ERRS, "rx_crc_align_errs"), \
	OCELOT_STAT_ETHTOOL(RX_SYM_ERRS, "rx_sym_errs"), \
	OCELOT_STAT_ETHTOOL(RX_64, "rx_frames_below_65_octets"), \
	OCELOT_STAT_ETHTOOL(RX_65_127, "rx_frames_65_to_127_octets"), \
	OCELOT_STAT_ETHTOOL(RX_128_255, "rx_frames_128_to_255_octets"), \
	OCELOT_STAT_ETHTOOL(RX_256_511, "rx_frames_256_to_511_octets"), \
	OCELOT_STAT_ETHTOOL(RX_512_1023, "rx_frames_512_to_1023_octets"), \
	OCELOT_STAT_ETHTOOL(RX_1024_1526, "rx_frames_1024_to_1526_octets"), \
	OCELOT_STAT_ETHTOOL(RX_1527_MAX, "rx_frames_over_1526_octets"), \
	OCELOT_STAT_ETHTOOL(RX_PAUSE, "rx_pause"), \
	OCELOT_STAT_ETHTOOL(RX_CONTROL, "rx_control"), \
	OCELOT_STAT_ETHTOOL(RX_LONGS, "rx_longs"), \
	OCELOT_STAT_ETHTOOL(RX_CLASSIFIED_DROPS, "rx_classified_drops"), \
	OCELOT_STAT_ETHTOOL(RX_RED_PRIO_0, "rx_red_prio_0"), \
	OCELOT_STAT_ETHTOOL(RX_RED_PRIO_1, "rx_red_prio_1"), \
	OCELOT_STAT_ETHTOOL(RX_RED_PRIO_2, "rx_red_prio_2"), \
	OCELOT_STAT_ETHTOOL(RX_RED_PRIO_3, "rx_red_prio_3"), \
	OCELOT_STAT_ETHTOOL(RX_RED_PRIO_4, "rx_red_prio_4"), \
	OCELOT_STAT_ETHTOOL(RX_RED_PRIO_5, "rx_red_prio_5"), \
	OCELOT_STAT_ETHTOOL(RX_RED_PRIO_6, "rx_red_prio_6"), \
	OCELOT_STAT_ETHTOOL(RX_RED_PRIO_7, "rx_red_prio_7"), \
	OCELOT_STAT_ETHTOOL(RX_YELLOW_PRIO_0, "rx_yellow_prio_0"), \
	OCELOT_STAT_ETHTOOL(RX_YELLOW_PRIO_1, "rx_yellow_prio_1"), \
	OCELOT_STAT_ETHTOOL(RX_YELLOW_PRIO_2, "rx_yellow_prio_2"), \
	OCELOT_STAT_ETHTOOL(RX_YELLOW_PRIO_3, "rx_yellow_prio_3"), \
	OCELOT_STAT_ETHTOOL(RX_YELLOW_PRIO_4, "rx_yellow_prio_4"), \
	OCELOT_STAT_ETHTOOL(RX_YELLOW_PRIO_5, "rx_yellow_prio_5"), \
	OCELOT_STAT_ETHTOOL(RX_YELLOW_PRIO_6, "rx_yellow_prio_6"), \
	OCELOT_STAT_ETHTOOL(RX_YELLOW_PRIO_7, "rx_yellow_prio_7"), \
	OCELOT_STAT_ETHTOOL(RX_GREEN_PRIO_0, "rx_green_prio_0"), \
	OCELOT_STAT_ETHTOOL(RX_GREEN_PRIO_1, "rx_green_prio_1"), \
	OCELOT_STAT_ETHTOOL(RX_GREEN_PRIO_2, "rx_green_prio_2"), \
	OCELOT_STAT_ETHTOOL(RX_GREEN_PRIO_3, "rx_green_prio_3"), \
	OCELOT_STAT_ETHTOOL(RX_GREEN_PRIO_4, "rx_green_prio_4"), \
	OCELOT_STAT_ETHTOOL(RX_GREEN_PRIO_5, "rx_green_prio_5"), \
	OCELOT_STAT_ETHTOOL(RX_GREEN_PRIO_6, "rx_green_prio_6"), \
	OCELOT_STAT_ETHTOOL(RX_GREEN_PRIO_7, "rx_green_prio_7"), \
	OCELOT_STAT_ETHTOOL(TX_OCTETS, "tx_octets"), \
	OCELOT_STAT_ETHTOOL(TX_UNICAST, "tx_unicast"), \
	OCELOT_STAT_ETHTOOL(TX_MULTICAST, "tx_multicast"), \
	OCELOT_STAT_ETHTOOL(TX_BROADCAST, "tx_broadcast"), \
	OCELOT_STAT_ETHTOOL(TX_COLLISION, "tx_collision"), \
	OCELOT_STAT_ETHTOOL(TX_DROPS, "tx_drops"), \
	OCELOT_STAT_ETHTOOL(TX_PAUSE, "tx_pause"), \
	OCELOT_STAT_ETHTOOL(TX_64, "tx_frames_below_65_octets"), \
	OCELOT_STAT_ETHTOOL(TX_65_127, "tx_frames_65_to_127_octets"), \
	OCELOT_STAT_ETHTOOL(TX_128_255, "tx_frames_128_255_octets"), \
	OCELOT_STAT_ETHTOOL(TX_256_511, "tx_frames_256_511_octets"), \
	OCELOT_STAT_ETHTOOL(TX_512_1023, "tx_frames_512_1023_octets"), \
	OCELOT_STAT_ETHTOOL(TX_1024_1526, "tx_frames_1024_1526_octets"), \
	OCELOT_STAT_ETHTOOL(TX_1527_MAX, "tx_frames_over_1526_octets"), \
	OCELOT_STAT_ETHTOOL(TX_YELLOW_PRIO_0, "tx_yellow_prio_0"), \
	OCELOT_STAT_ETHTOOL(TX_YELLOW_PRIO_1, "tx_yellow_prio_1"), \
	OCELOT_STAT_ETHTOOL(TX_YELLOW_PRIO_2, "tx_yellow_prio_2"), \
	OCELOT_STAT_ETHTOOL(TX_YELLOW_PRIO_3, "tx_yellow_prio_3"), \
	OCELOT_STAT_ETHTOOL(TX_YELLOW_PRIO_4, "tx_yellow_prio_4"), \
	OCELOT_STAT_ETHTOOL(TX_YELLOW_PRIO_5, "tx_yellow_prio_5"), \
	OCELOT_STAT_ETHTOOL(TX_YELLOW_PRIO_6, "tx_yellow_prio_6"), \
	OCELOT_STAT_ETHTOOL(TX_YELLOW_PRIO_7, "tx_yellow_prio_7"), \
	OCELOT_STAT_ETHTOOL(TX_GREEN_PRIO_0, "tx_green_prio_0"), \
	OCELOT_STAT_ETHTOOL(TX_GREEN_PRIO_1, "tx_green_prio_1"), \
	OCELOT_STAT_ETHTOOL(TX_GREEN_PRIO_2, "tx_green_prio_2"), \
	OCELOT_STAT_ETHTOOL(TX_GREEN_PRIO_3, "tx_green_prio_3"), \
	OCELOT_STAT_ETHTOOL(TX_GREEN_PRIO_4, "tx_green_prio_4"), \
	OCELOT_STAT_ETHTOOL(TX_GREEN_PRIO_5, "tx_green_prio_5"), \
	OCELOT_STAT_ETHTOOL(TX_GREEN_PRIO_6, "tx_green_prio_6"), \
	OCELOT_STAT_ETHTOOL(TX_GREEN_PRIO_7, "tx_green_prio_7"), \
	OCELOT_STAT_ETHTOOL(TX_AGED, "tx_aged"), \
	OCELOT_STAT_ETHTOOL(DROP_LOCAL, "drop_local"), \
	OCELOT_STAT_ETHTOOL(DROP_TAIL, "drop_tail"), \
	OCELOT_STAT_ETHTOOL(DROP_YELLOW_PRIO_0, "drop_yellow_prio_0"), \
	OCELOT_STAT_ETHTOOL(DROP_YELLOW_PRIO_1, "drop_yellow_prio_1"), \
	OCELOT_STAT_ETHTOOL(DROP_YELLOW_PRIO_2, "drop_yellow_prio_2"), \
	OCELOT_STAT_ETHTOOL(DROP_YELLOW_PRIO_3, "drop_yellow_prio_3"), \
	OCELOT_STAT_ETHTOOL(DROP_YELLOW_PRIO_4, "drop_yellow_prio_4"), \
	OCELOT_STAT_ETHTOOL(DROP_YELLOW_PRIO_5, "drop_yellow_prio_5"), \
	OCELOT_STAT_ETHTOOL(DROP_YELLOW_PRIO_6, "drop_yellow_prio_6"), \
	OCELOT_STAT_ETHTOOL(DROP_YELLOW_PRIO_7, "drop_yellow_prio_7"), \
	OCELOT_STAT_ETHTOOL(DROP_GREEN_PRIO_0, "drop_green_prio_0"), \
	OCELOT_STAT_ETHTOOL(DROP_GREEN_PRIO_1, "drop_green_prio_1"), \
	OCELOT_STAT_ETHTOOL(DROP_GREEN_PRIO_2, "drop_green_prio_2"), \
	OCELOT_STAT_ETHTOOL(DROP_GREEN_PRIO_3, "drop_green_prio_3"), \
	OCELOT_STAT_ETHTOOL(DROP_GREEN_PRIO_4, "drop_green_prio_4"), \
	OCELOT_STAT_ETHTOOL(DROP_GREEN_PRIO_5, "drop_green_prio_5"), \
	OCELOT_STAT_ETHTOOL(DROP_GREEN_PRIO_6, "drop_green_prio_6"), \
	OCELOT_STAT_ETHTOOL(DROP_GREEN_PRIO_7, "drop_green_prio_7")

static const struct ocelot_stat_layout ocelot_stats_layout[OCELOT_NUM_STATS] = {
	OCELOT_COMMON_STATS,
};

static const struct ocelot_stat_layout vsc9953_stats_layout[OCELOT_NUM_STATS] = {
	OCELOT_COMMON_STATS,
};

static const struct ocelot_stat_layout vsc9959_stats_layout[OCELOT_NUM_STATS] = {
	OCELOT_COMMON_STATS,
	OCELOT_STAT(RX_ASSEMBLY_ERRS),
	OCELOT_STAT(RX_SMD_ERRS),
	OCELOT_STAT(RX_ASSEMBLY_OK),
	OCELOT_STAT(RX_MERGE_FRAGMENTS),
	OCELOT_STAT(TX_MERGE_FRAGMENTS),
	OCELOT_STAT(RX_PMAC_OCTETS),
	OCELOT_STAT(RX_PMAC_UNICAST),
	OCELOT_STAT(RX_PMAC_MULTICAST),
	OCELOT_STAT(RX_PMAC_BROADCAST),
	OCELOT_STAT(RX_PMAC_SHORTS),
	OCELOT_STAT(RX_PMAC_FRAGMENTS),
	OCELOT_STAT(RX_PMAC_JABBERS),
	OCELOT_STAT(RX_PMAC_CRC_ALIGN_ERRS),
	OCELOT_STAT(RX_PMAC_SYM_ERRS),
	OCELOT_STAT(RX_PMAC_64),
	OCELOT_STAT(RX_PMAC_65_127),
	OCELOT_STAT(RX_PMAC_128_255),
	OCELOT_STAT(RX_PMAC_256_511),
	OCELOT_STAT(RX_PMAC_512_1023),
	OCELOT_STAT(RX_PMAC_1024_1526),
	OCELOT_STAT(RX_PMAC_1527_MAX),
	OCELOT_STAT(RX_PMAC_PAUSE),
	OCELOT_STAT(RX_PMAC_CONTROL),
	OCELOT_STAT(RX_PMAC_LONGS),
	OCELOT_STAT(TX_PMAC_OCTETS),
	OCELOT_STAT(TX_PMAC_UNICAST),
	OCELOT_STAT(TX_PMAC_MULTICAST),
	OCELOT_STAT(TX_PMAC_BROADCAST),
	OCELOT_STAT(TX_PMAC_PAUSE),
	OCELOT_STAT(TX_PMAC_64),
	OCELOT_STAT(TX_PMAC_65_127),
	OCELOT_STAT(TX_PMAC_128_255),
	OCELOT_STAT(TX_PMAC_256_511),
	OCELOT_STAT(TX_PMAC_512_1023),
	OCELOT_STAT(TX_PMAC_1024_1526),
	OCELOT_STAT(TX_PMAC_1527_MAX),
};

I would like to keep the flexibility of defining the counters in this
way without too much regard for:
- the order in which they are listed in enum ocelot_stat
- the order in which they are listed in the struct ocelot_stat_layout array
- the value of the SYS_COUNT_* of their underlying register address

However I'd still like to have a way in which I can index ocelot->stats
when I know specifically what I am looking for.

I think in practice this means that ocelot_prepare_stats_regions() would
need to be modified to first sort the ocelot_stat_layout array by "reg"
value (to keep bulking efficient), and then, I think I'd have to keep to
introduce another array of u32 *ocelot->stat_indices (to keep specific
indexing possible). Then I'd have to go through one extra layer of
indirection; RX_OCTETS would be available at

ocelot->stats[port * OCELOT_NUM_STATS + ocelot->stat_indices[OCELOT_STAT_RX_OCTETS]].

(I can wrap this behind a helper, of course)

This is a bit complicated, but I'm not aware of something simpler that
would do what you want and what I want. What are your thoughts?

  reply	other threads:[~2022-08-17 11:06 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-16 13:53 [PATCH net 0/8] Fixes for Ocelot driver statistics Vladimir Oltean
2022-08-16 13:53 ` [PATCH net 1/8] net: dsa: felix: fix ethtool 256-511 and 512-1023 TX packet counters Vladimir Oltean
2022-08-16 13:53 ` [PATCH net 2/8] net: mscc: ocelot: fix incorrect ndo_get_stats64 " Vladimir Oltean
2022-08-17  6:26   ` Colin Foster
2022-08-16 13:53 ` [PATCH net 3/8] net: mscc: ocelot: fix address of SYS_COUNT_TX_AGING counter Vladimir Oltean
2022-08-16 13:53 ` [PATCH net 4/8] net: mscc: ocelot: turn stats_lock into a spinlock Vladimir Oltean
2022-08-16 13:53 ` [PATCH net 5/8] net: mscc: ocelot: fix race between ndo_get_stats64 and ocelot_check_stats_work Vladimir Oltean
2022-08-16 13:53 ` [PATCH net 6/8] net: mscc: ocelot: make struct ocelot_stat_layout array indexable Vladimir Oltean
2022-08-17  6:46   ` Colin Foster
2022-08-17 11:06     ` Vladimir Oltean [this message]
2022-08-17 13:05       ` Vladimir Oltean
2022-08-17 15:14         ` Colin Foster
2022-08-17 17:42           ` Vladimir Oltean
2022-08-17 20:47             ` Colin Foster
2022-08-17 22:03               ` Vladimir Oltean
2022-08-17 22:07                 ` Colin Foster
2022-08-18  6:01                 ` Colin Foster
2022-08-16 13:53 ` [PATCH net 7/8] net: mscc: ocelot: keep ocelot_stat_layout by reg address, not offset Vladimir Oltean
2022-08-16 13:53 ` [PATCH net 8/8] net: mscc: ocelot: report ndo_get_stats64 from the wraparound-resistant ocelot->stats Vladimir Oltean
2022-08-18  5:20 ` [PATCH net 0/8] Fixes for Ocelot driver statistics patchwork-bot+netdevbpf

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=20220817110644.bhvzl7fslq2l6g23@skbuf \
    --to=vladimir.oltean@nxp.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=alexandre.belloni@bootlin.com \
    --cc=andrew@lunn.ch \
    --cc=claudiu.manoil@nxp.com \
    --cc=colin.foster@in-advantage.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=f.fainelli@gmail.com \
    --cc=fido_max@inbox.ru \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=vivien.didelot@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox