All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Lobakin <alexandr.lobakin@intel.com>
To: Jian Shen <shenjian15@huawei.com>
Cc: Alexander Lobakin <alexandr.lobakin@intel.com>,
	davem@davemloft.net, kuba@kernel.org, andrew@lunn.ch,
	ecree.xilinx@gmail.com, hkallweit1@gmail.com, saeed@kernel.org,
	leon@kernel.org, netdev@vger.kernel.org, linuxarm@openeuler.org,
	lipeng321@huawei.com
Subject: Re: [RFCv6 PATCH net-next 01/19] net: introduce operation helpers for netdev features
Date: Tue, 19 Apr 2022 16:40:45 +0200	[thread overview]
Message-ID: <20220419144045.1664765-1-alexandr.lobakin@intel.com> (raw)
In-Reply-To: <20220419022206.36381-2-shenjian15@huawei.com>

From: Jian Shen <shenjian15@huawei.com>
Date: Tue, 19 Apr 2022 10:21:48 +0800

> Introduce a set of bitmap operation helpers for netdev features,
> then we can use them to replace the logical operation with them.
> As the nic driversare not supposed to modify netdev_features
> directly, it also introduces wrappers helpers to this.
> 
> The implementation of these helpers are based on the old prototype
> of netdev_features_t is still u64. I will rewrite them on the last
> patch, when the prototype changes.
> 
> To avoid interdependencies between netdev_features_helper.h and
> netdevice.h, put the helpers for testing feature is set in the
> netdevice.h, and move advandced helpers like
> netdev_get_wanted_features() and netdev_intersect_features() to
> netdev_features_helper.h.
> 
> Signed-off-by: Jian Shen <shenjian15@huawei.com>
> ---
>  .../net/ethernet/netronome/nfp/nfp_net_repr.c |   1 +
>  include/linux/netdev_features.h               |  12 +
>  include/linux/netdev_features_helper.h        | 604 ++++++++++++++++++
>  include/linux/netdevice.h                     |  45 +-
>  net/8021q/vlan_dev.c                          |   1 +
>  net/core/dev.c                                |   1 +
>  6 files changed, 646 insertions(+), 18 deletions(-)
>  create mode 100644 include/linux/netdev_features_helper.h
> 
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
> index ba3fa7eac98d..08f2c54e0a11 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
> @@ -4,6 +4,7 @@
>  #include <linux/etherdevice.h>
>  #include <linux/io-64-nonatomic-hi-lo.h>
>  #include <linux/lockdep.h>
> +#include <linux/netdev_features_helper.h>
>  #include <net/dst_metadata.h>
>  
>  #include "nfpcore/nfp_cpp.h"
> diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
> index 2c6b9e416225..e2b66fa3d7d6 100644
> --- a/include/linux/netdev_features.h
> +++ b/include/linux/netdev_features.h
> @@ -11,6 +11,18 @@
>  
>  typedef u64 netdev_features_t;
>  
> +struct netdev_feature_set {
> +	unsigned int cnt;
> +	unsigned short feature_bits[];
> +};
> +
> +#define DECLARE_NETDEV_FEATURE_SET(name, features...)		\
> +	static unsigned short __##name##_s[] = {features};	\
> +	struct netdev_feature_set name = {			\

I suggest using `const` here. Those sets are needed only to
initialize bitmaps, that's it. They are not supposed to be
modified. This would be one more hardening here to avoid some weird
usages of sets, and also would place them in .rodata instead of just
.data.

Function                                     old     new   delta
main                                          35      33      -2
Total: Before=78, After=76, chg -2.56%
add/remove: 0/2 grow/shrink: 0/0 up/down: 0/-14 (-14)
Data                                         old     new   delta
arr1                                           6       -      -6
arr2                                           8       -      -8
Total: Before=15, After=1, chg -93.33%
add/remove: 2/0 grow/shrink: 0/0 up/down: 14/0 (14)
RO Data                                      old     new   delta
arr1                                           -       8      +8
arr2                                           -       6      +6
Total: Before=36, After=50, chg +38.89%

As you can see, there's a 2-byte code optimization. And that was
just a simpliest oneliner. The gains will be much bigger from the
real usages.

> +		.cnt = ARRAY_SIZE(__##name##_s),		\
> +		.feature_bits = {features},			\
> +	}

The problem with the current macro is that it doesn't allow to
declare feature sets as static. Because the temporary array for
counting the number of bits goes first, and doing

static DECLARE_NETDEV_FEATURE_SET();

wouldn't change anything.
But we want to have most feature sets static as they will be needed
only inside one file. Making every of them global would hurt
optimization.

At the end, I came to

#define DECLARE_NETDEV_FEATURE_SET(name, features...)			\
	const struct netdev_feature_set name = {			\
		.feature_bits = { features },				\
		.cnt = sizeof((u16 []){ features }) / sizeof(u16),	\
	}

because ARRAY_SIZE() can be taken only from a variable, not from
a compound literal.
But this one is actually OK. We don't need ARRAY_SIZE() in here
since we define an unnamed array of an explicit type that we know
for sure inline. So there's no chance to do it wrong as long as
the @features argument is correct.

The ability to make it static is important. For example, when I
marked them both static, I got

add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0 (0)
Function                                     old     new   delta
Total: Before=76, After=76, chg +0.00%
add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0 (0)
Data                                         old     new   delta
Total: Before=1, After=1, chg +0.00%
add/remove: 0/2 grow/shrink: 0/0 up/down: 0/-14 (-14)
RO Data                                      old     new   delta
arr1                                           6       -      -6
arr2                                           8       -      -8
Total: Before=50, After=36, chg -28.00%

i.e. both of the sets were removed, because my main() was:

	printf("cnt1: %u, cnt2: %u\n", arr1.cnt, arr2.cnt);

The compiler saw that I don't use them, except for printing values
which are actually compile-time constants, and wiped them.
Previously, they were global so it didn't have a clue if they're
used anywhere else.
This was a simple stupid example, but it will bring a lot more value
in real use cases. So please consider my variant :D

> +
>  enum {
>  	NETIF_F_SG_BIT,			/* Scatter/gather IO. */
>  	NETIF_F_IP_CSUM_BIT,		/* Can checksum TCP/UDP over IPv4. */

--- 8< ---

> -- 
> 2.33.0

Thanks,
Al

  reply	other threads:[~2022-04-19 14:44 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-19  2:21 [RFCv6 PATCH net-next 00/19] net: extend the type of netdev_features_t to bitmap Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 01/19] net: introduce operation helpers for netdev features Jian Shen
2022-04-19 14:40   ` Alexander Lobakin [this message]
2022-04-20  9:24     ` shenjian (K)
2022-04-19  2:21 ` [RFCv6 PATCH net-next 02/19] net: replace general features macroes with global netdev_features variables Jian Shen
2022-04-19 14:49   ` Alexander Lobakin
2022-04-20  9:54     ` shenjian (K)
2022-07-20 15:09       ` Alexander Lobakin
2022-07-21  1:15         ` shenjian (K)
2022-07-21 14:57           ` Alexander Lobakin
2022-07-21 15:21             ` shenjian (K)
2022-07-20 15:10       ` Alexander Lobakin
2022-07-20 15:13       ` Alexander Lobakin
2022-04-19  2:21 ` [RFCv6 PATCH net-next 03/19] net: replace multiple feature bits with netdev features array Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 04/19] net: sfc: replace const features initialization " Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 05/19] net: simplify the netdev features expression Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 06/19] net: adjust variables definition for netdev_features_t Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 07/19] net: use netdev_feature_add helpers Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 08/19] net: use netdev_features_or helpers Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 09/19] net: use netdev_features_xor helpers Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 10/19] net: use netdev_feature_del helpers Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 11/19] net: use netdev_features_andnot helpers Jian Shen
2022-04-19  2:21 ` [RFCv6 PATCH net-next 12/19] net: use netdev_feature_test helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 13/19] net: use netdev_features_intersects helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 14/19] net: use netdev_features_and helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 15/19] net: use netdev_features_subset helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 16/19] net: use netdev_features_equal helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 17/19] net: use netdev_features_copy helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 18/19] net: use netdev_xxx_features helpers Jian Shen
2022-04-19  2:22 ` [RFCv6 PATCH net-next 19/19] net: redefine the prototype of netdev_features_t Jian Shen

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=20220419144045.1664765-1-alexandr.lobakin@intel.com \
    --to=alexandr.lobakin@intel.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=ecree.xilinx@gmail.com \
    --cc=hkallweit1@gmail.com \
    --cc=kuba@kernel.org \
    --cc=leon@kernel.org \
    --cc=linuxarm@openeuler.org \
    --cc=lipeng321@huawei.com \
    --cc=netdev@vger.kernel.org \
    --cc=saeed@kernel.org \
    --cc=shenjian15@huawei.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.