* [PATCH net-next 1/2] ifb: support ethtools driver info
@ 2021-11-25 2:01 xiangxia.m.yue
2021-11-25 2:01 ` [PATCH net-next 2/2] ifb: support ethtools stats xiangxia.m.yue
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: xiangxia.m.yue @ 2021-11-25 2:01 UTC (permalink / raw)
To: netdev; +Cc: Tonghao Zhang, Jakub Kicinski, David S. Miller
From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
ifb netdev may be created by others prefix, not ifbX.
For getting netdev driver info, add ifb ethtools callback.
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
---
drivers/net/ifb.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 31f522b8e54e..d9078ce041c4 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
@@ -35,7 +36,10 @@
#include <net/pkt_sched.h>
#include <net/net_namespace.h>
-#define TX_Q_LIMIT 32
+#define DRV_NAME "ifb"
+#define DRV_VERSION "1.0"
+#define TX_Q_LIMIT 32
+
struct ifb_q_private {
struct net_device *dev;
struct tasklet_struct ifb_tasklet;
@@ -181,6 +185,12 @@ static int ifb_dev_init(struct net_device *dev)
return 0;
}
+static void ifb_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+}
+
static const struct net_device_ops ifb_netdev_ops = {
.ndo_open = ifb_open,
.ndo_stop = ifb_close,
@@ -190,6 +200,10 @@ static const struct net_device_ops ifb_netdev_ops = {
.ndo_init = ifb_dev_init,
};
+static const struct ethtool_ops ifb_ethtool_ops = {
+ .get_drvinfo = ifb_get_drvinfo,
+};
+
#define IFB_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | \
NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL | \
NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX | \
@@ -224,6 +238,8 @@ static void ifb_setup(struct net_device *dev)
dev->vlan_features |= IFB_FEATURES & ~(NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX);
+ dev->ethtool_ops = &ifb_ethtool_ops;
+
dev->flags |= IFF_NOARP;
dev->flags &= ~IFF_MULTICAST;
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
@@ -289,7 +305,7 @@ static int ifb_validate(struct nlattr *tb[], struct nlattr *data[],
}
static struct rtnl_link_ops ifb_link_ops __read_mostly = {
- .kind = "ifb",
+ .kind = DRV_NAME,
.priv_size = sizeof(struct ifb_dev_private),
.setup = ifb_setup,
.validate = ifb_validate,
@@ -359,4 +375,4 @@ module_init(ifb_init_module);
module_exit(ifb_cleanup_module);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jamal Hadi Salim");
-MODULE_ALIAS_RTNL_LINK("ifb");
+MODULE_ALIAS_RTNL_LINK(DRV_NAME);
--
2.27.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH net-next 2/2] ifb: support ethtools stats 2021-11-25 2:01 [PATCH net-next 1/2] ifb: support ethtools driver info xiangxia.m.yue @ 2021-11-25 2:01 ` xiangxia.m.yue 2021-11-25 2:18 ` [PATCH net-next 1/2] ifb: support ethtools driver info Jakub Kicinski 2021-11-25 13:55 ` Leon Romanovsky 2 siblings, 0 replies; 5+ messages in thread From: xiangxia.m.yue @ 2021-11-25 2:01 UTC (permalink / raw) To: netdev; +Cc: Tonghao Zhang, Jakub Kicinski, David S. Miller From: Tonghao Zhang <xiangxia.m.yue@gmail.com> With this feature, we can use the ethtools to get tx/rx queues stats. This patch, introduce the ifb_update_q_stats helper to update the queues stats, and ifb_q_stats to simplify the codes. Cc: Jakub Kicinski <kuba@kernel.org> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com> --- drivers/net/ifb.c | 146 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 120 insertions(+), 26 deletions(-) diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index d9078ce041c4..e5b0eeadca20 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -40,30 +40,54 @@ #define DRV_VERSION "1.0" #define TX_Q_LIMIT 32 +struct ifb_q_stats { + u64 packets; + u64 bytes; + struct u64_stats_sync sync; +}; + struct ifb_q_private { struct net_device *dev; struct tasklet_struct ifb_tasklet; int tasklet_pending; int txqnum; struct sk_buff_head rq; - u64 rx_packets; - u64 rx_bytes; - struct u64_stats_sync rsync; - - struct u64_stats_sync tsync; - u64 tx_packets; - u64 tx_bytes; struct sk_buff_head tq; + struct ifb_q_stats rx_stats; + struct ifb_q_stats tx_stats; } ____cacheline_aligned_in_smp; struct ifb_dev_private { struct ifb_q_private *tx_private; }; +/* For ethtools. */ +struct ifb_q_stats_desc { + char desc[ETH_GSTRING_LEN]; + size_t offset; +}; + +#define IFB_Q_STAT(m) offsetof(struct ifb_q_stats, m) + +static const struct ifb_q_stats_desc ifb_q_stats_desc[] = { + { "packets", IFB_Q_STAT(packets) }, + { "bytes", IFB_Q_STAT(bytes) }, +}; + +#define IFB_Q_STATS_LEN ARRAY_SIZE(ifb_q_stats_desc) + static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev); static int ifb_open(struct net_device *dev); static int ifb_close(struct net_device *dev); +static inline void ifb_update_q_stats(struct ifb_q_stats *stats, int len) +{ + u64_stats_update_begin(&stats->sync); + stats->packets++; + stats->bytes += len; + u64_stats_update_end(&stats->sync); +} + static void ifb_ri_tasklet(struct tasklet_struct *t) { struct ifb_q_private *txp = from_tasklet(txp, t, ifb_tasklet); @@ -87,10 +111,7 @@ static void ifb_ri_tasklet(struct tasklet_struct *t) #endif nf_skip_egress(skb, true); - u64_stats_update_begin(&txp->tsync); - txp->tx_packets++; - txp->tx_bytes += skb->len; - u64_stats_update_end(&txp->tsync); + ifb_update_q_stats(&txp->tx_stats, skb->len); rcu_read_lock(); skb->dev = dev_get_by_index_rcu(dev_net(txp->dev), skb->skb_iif); @@ -143,18 +164,18 @@ static void ifb_stats64(struct net_device *dev, for (i = 0; i < dev->num_tx_queues; i++,txp++) { do { - start = u64_stats_fetch_begin_irq(&txp->rsync); - packets = txp->rx_packets; - bytes = txp->rx_bytes; - } while (u64_stats_fetch_retry_irq(&txp->rsync, start)); + start = u64_stats_fetch_begin_irq(&txp->rx_stats.sync); + packets = txp->rx_stats.packets; + bytes = txp->rx_stats.bytes; + } while (u64_stats_fetch_retry_irq(&txp->rx_stats.sync, start)); stats->rx_packets += packets; stats->rx_bytes += bytes; do { - start = u64_stats_fetch_begin_irq(&txp->tsync); - packets = txp->tx_packets; - bytes = txp->tx_bytes; - } while (u64_stats_fetch_retry_irq(&txp->tsync, start)); + start = u64_stats_fetch_begin_irq(&txp->tx_stats.sync); + packets = txp->tx_stats.packets; + bytes = txp->tx_stats.bytes; + } while (u64_stats_fetch_retry_irq(&txp->tx_stats.sync, start)); stats->tx_packets += packets; stats->tx_bytes += bytes; } @@ -177,8 +198,8 @@ static int ifb_dev_init(struct net_device *dev) txp->dev = dev; __skb_queue_head_init(&txp->rq); __skb_queue_head_init(&txp->tq); - u64_stats_init(&txp->rsync); - u64_stats_init(&txp->tsync); + u64_stats_init(&txp->rx_stats.sync); + u64_stats_init(&txp->tx_stats.sync); tasklet_setup(&txp->ifb_tasklet, ifb_ri_tasklet); netif_tx_start_queue(netdev_get_tx_queue(dev, i)); } @@ -191,6 +212,79 @@ static void ifb_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info strlcpy(info->version, DRV_VERSION, sizeof(info->version)); } +static void ifb_get_strings(struct net_device *dev, u32 stringset, u8 *buf) +{ + u8 *p = buf; + int i, j; + + switch(stringset) { + case ETH_SS_STATS: + for (i = 0; i < dev->real_num_rx_queues; i++) { + for (j = 0; j < IFB_Q_STATS_LEN; j++) + ethtool_sprintf(&p, "rx_queue_%u_%.18s", + i, ifb_q_stats_desc[j].desc); + } + + for (i = 0; i < dev->real_num_tx_queues; i++) { + for (j = 0; j < IFB_Q_STATS_LEN; j++) + ethtool_sprintf(&p, "tx_queue_%u_%.18s", + i, ifb_q_stats_desc[j].desc); + } + break; + } +} + +static int ifb_get_sset_count(struct net_device *dev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return IFB_Q_STATS_LEN * (dev->real_num_rx_queues + + dev->real_num_tx_queues); + default: + return -EOPNOTSUPP; + } +} + +static void ifb_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) +{ + struct ifb_dev_private *dp = netdev_priv(dev); + unsigned int start; + size_t offset; + int idx = 0; + int i, j; + + for (i = 0; i < dev->real_num_rx_queues; i++) { + struct ifb_q_private *txp = dp->tx_private + i; + struct ifb_q_stats *rq_stats = &txp->rx_stats; + void *stats_base = (void *)&txp->rx_stats;; + + do { + start = u64_stats_fetch_begin_irq(&rq_stats->sync); + for (j = 0; j < IFB_Q_STATS_LEN; j++) { + offset = ifb_q_stats_desc[j].offset; + data[idx + j] = *(u64 *)(stats_base + offset); + } + } while (u64_stats_fetch_retry_irq(&rq_stats->sync, start)); + idx += IFB_Q_STATS_LEN; + } + + for (i = 0; i < dev->real_num_tx_queues; i++) { + struct ifb_q_private *txp = dp->tx_private + i; + struct ifb_q_stats *tq_stats = &txp->tx_stats; + void *stats_base = (void *)&txp->tx_stats;; + + do { + start = u64_stats_fetch_begin_irq(&tq_stats->sync); + for (j = 0; j < IFB_Q_STATS_LEN; j++) { + offset = ifb_q_stats_desc[j].offset; + data[idx + j] = *(u64 *)(stats_base + offset); + } + } while (u64_stats_fetch_retry_irq(&tq_stats->sync, start)); + idx += IFB_Q_STATS_LEN; + } +} + static const struct net_device_ops ifb_netdev_ops = { .ndo_open = ifb_open, .ndo_stop = ifb_close, @@ -201,7 +295,10 @@ static const struct net_device_ops ifb_netdev_ops = { }; static const struct ethtool_ops ifb_ethtool_ops = { - .get_drvinfo = ifb_get_drvinfo, + .get_drvinfo = ifb_get_drvinfo, + .get_strings = ifb_get_strings, + .get_sset_count = ifb_get_sset_count, + .get_ethtool_stats = ifb_get_ethtool_stats, }; #define IFB_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | \ @@ -257,10 +354,7 @@ static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev) struct ifb_dev_private *dp = netdev_priv(dev); struct ifb_q_private *txp = dp->tx_private + skb_get_queue_mapping(skb); - u64_stats_update_begin(&txp->rsync); - txp->rx_packets++; - txp->rx_bytes += skb->len; - u64_stats_update_end(&txp->rsync); + ifb_update_q_stats(&txp->rx_stats, skb->len); if (!skb->redirected || !skb->skb_iif) { dev_kfree_skb(skb); -- 2.27.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net-next 1/2] ifb: support ethtools driver info 2021-11-25 2:01 [PATCH net-next 1/2] ifb: support ethtools driver info xiangxia.m.yue 2021-11-25 2:01 ` [PATCH net-next 2/2] ifb: support ethtools stats xiangxia.m.yue @ 2021-11-25 2:18 ` Jakub Kicinski 2021-11-25 7:29 ` Tonghao Zhang 2021-11-25 13:55 ` Leon Romanovsky 2 siblings, 1 reply; 5+ messages in thread From: Jakub Kicinski @ 2021-11-25 2:18 UTC (permalink / raw) To: xiangxia.m.yue; +Cc: netdev, David S. Miller On Thu, 25 Nov 2021 10:01:54 +0800 xiangxia.m.yue@gmail.com wrote: > +#define DRV_NAME "ifb" > +#define DRV_VERSION "1.0" Let's not invent meaningless driver versions. > +#define TX_Q_LIMIT 32 > + > struct ifb_q_private { > struct net_device *dev; > struct tasklet_struct ifb_tasklet; > @@ -181,6 +185,12 @@ static int ifb_dev_init(struct net_device *dev) > return 0; > } > > +static void ifb_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) > +{ > + strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); Can we make core fill in driver name from rtnl_link_ops so we don't need to do it in each driver? > + strlcpy(info->version, DRV_VERSION, sizeof(info->version)); Leave this field as is, core should fill it with the kernel release. > +} ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net-next 1/2] ifb: support ethtools driver info 2021-11-25 2:18 ` [PATCH net-next 1/2] ifb: support ethtools driver info Jakub Kicinski @ 2021-11-25 7:29 ` Tonghao Zhang 0 siblings, 0 replies; 5+ messages in thread From: Tonghao Zhang @ 2021-11-25 7:29 UTC (permalink / raw) To: Jakub Kicinski; +Cc: Linux Kernel Network Developers, David S. Miller On Thu, Nov 25, 2021 at 10:19 AM Jakub Kicinski <kuba@kernel.org> wrote: > > On Thu, 25 Nov 2021 10:01:54 +0800 xiangxia.m.yue@gmail.com wrote: > > +#define DRV_NAME "ifb" > > +#define DRV_VERSION "1.0" > > Let's not invent meaningless driver versions. Ok > > +#define TX_Q_LIMIT 32 > > + > > struct ifb_q_private { > > struct net_device *dev; > > struct tasklet_struct ifb_tasklet; > > @@ -181,6 +185,12 @@ static int ifb_dev_init(struct net_device *dev) > > return 0; > > } > > > > +static void ifb_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) > > +{ > > + strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); > > Can we make core fill in driver name from rtnl_link_ops so we don't > need to do it in each driver? Good idea! v2 is sent out, please review. https://patchwork.kernel.org/project/netdevbpf/patch/20211125072544.32578-1-xiangxia.m.yue@gmail.com/ > > + strlcpy(info->version, DRV_VERSION, sizeof(info->version)); > > Leave this field as is, core should fill it with the kernel release. Ok > > +} -- Best regards, Tonghao ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net-next 1/2] ifb: support ethtools driver info 2021-11-25 2:01 [PATCH net-next 1/2] ifb: support ethtools driver info xiangxia.m.yue 2021-11-25 2:01 ` [PATCH net-next 2/2] ifb: support ethtools stats xiangxia.m.yue 2021-11-25 2:18 ` [PATCH net-next 1/2] ifb: support ethtools driver info Jakub Kicinski @ 2021-11-25 13:55 ` Leon Romanovsky 2 siblings, 0 replies; 5+ messages in thread From: Leon Romanovsky @ 2021-11-25 13:55 UTC (permalink / raw) To: xiangxia.m.yue; +Cc: netdev, Jakub Kicinski, David S. Miller On Thu, Nov 25, 2021 at 10:01:54AM +0800, xiangxia.m.yue@gmail.com wrote: > From: Tonghao Zhang <xiangxia.m.yue@gmail.com> > > ifb netdev may be created by others prefix, not ifbX. > For getting netdev driver info, add ifb ethtools callback. > > Cc: Jakub Kicinski <kuba@kernel.org> > Cc: "David S. Miller" <davem@davemloft.net> > Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com> > --- > drivers/net/ifb.c | 22 +++++++++++++++++++--- > 1 file changed, 19 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c > index 31f522b8e54e..d9078ce041c4 100644 > --- a/drivers/net/ifb.c > +++ b/drivers/net/ifb.c > @@ -26,6 +26,7 @@ > > #include <linux/module.h> > #include <linux/kernel.h> > +#include <linux/ethtool.h> > #include <linux/netdevice.h> > #include <linux/etherdevice.h> > #include <linux/init.h> > @@ -35,7 +36,10 @@ > #include <net/pkt_sched.h> > #include <net/net_namespace.h> > > -#define TX_Q_LIMIT 32 > +#define DRV_NAME "ifb" > +#define DRV_VERSION "1.0" Please don't add this line too. Thanks ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-11-25 13:57 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-11-25 2:01 [PATCH net-next 1/2] ifb: support ethtools driver info xiangxia.m.yue 2021-11-25 2:01 ` [PATCH net-next 2/2] ifb: support ethtools stats xiangxia.m.yue 2021-11-25 2:18 ` [PATCH net-next 1/2] ifb: support ethtools driver info Jakub Kicinski 2021-11-25 7:29 ` Tonghao Zhang 2021-11-25 13:55 ` Leon Romanovsky
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox