diff mbox series

[bpf-next,4/6] selftests/xsk: implement set_hw_ring_size function to configure interface ring size

Message ID 20240315140726.22291-5-tushar.vyavahare@intel.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series Enhancing selftests/xsk Framework: Maximum and Minimum Ring Configurations | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 8 this patch: 8
netdev/build_tools success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 13 maintainers not CCed: linux-kselftest@vger.kernel.org haoluo@google.com john.fastabend@gmail.com eddyz87@gmail.com sdf@google.com song@kernel.org kpsingh@kernel.org shuah@kernel.org yonghong.song@linux.dev martin.lau@linux.dev jolsa@kernel.org mykolal@fb.com andrii@kernel.org
netdev/build_clang success Errors and warnings before: 8 this patch: 8
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 8 this patch: 8
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 41 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-next-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-next-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-17 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-18 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-19 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-10 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-28 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-34 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-next-VM_Test-35 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-42 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-next-VM_Test-6 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for s390x-gcc / test (test_maps, false, 360) / test_maps on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-36 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18 and -O2 optimization
bpf/vmtest-bpf-next-VM_Test-29 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17 and -O2 optimization
bpf/vmtest-bpf-next-VM_Test-21 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-25 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-30 success Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-31 success Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-32 success Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-33 success Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-37 success Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-39 success Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-41 success Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-38 success Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-40 success Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18

Commit Message

Tushar Vyavahare March 15, 2024, 2:07 p.m. UTC
Introduce a new function called set_hw_ring_size that allows for the
dynamic configuration of the ring size within the interface.

Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
---
 tools/testing/selftests/bpf/xskxceiver.c | 35 ++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

Comments

Alexei Starovoitov March 15, 2024, 3:47 p.m. UTC | #1
On Fri, Mar 15, 2024 at 7:23 AM Tushar Vyavahare
<tushar.vyavahare@intel.com> wrote:
>
> Introduce a new function called set_hw_ring_size that allows for the
> dynamic configuration of the ring size within the interface.
>
> Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
> ---
>  tools/testing/selftests/bpf/xskxceiver.c | 35 ++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
> index 32005bfb9c9f..aafa78307586 100644
> --- a/tools/testing/selftests/bpf/xskxceiver.c
> +++ b/tools/testing/selftests/bpf/xskxceiver.c
> @@ -441,6 +441,41 @@ static int get_hw_ring_size(struct ifobject *ifobj)
>         return 0;
>  }
>
> +static int set_hw_ring_size(struct ifobject *ifobj, u32 tx, u32 rx)
> +{
> +       struct ethtool_ringparam ring_param = {0};
> +       struct ifreq ifr = {0};
> +       int sockfd, ret;
> +       u32 ctr = 0;
> +
> +       sockfd = socket(AF_INET, SOCK_DGRAM, 0);
> +       if (sockfd < 0)
> +               return errno;
> +
> +       memcpy(ifr.ifr_name, ifobj->ifname, sizeof(ifr.ifr_name));
> +
> +       ring_param.tx_pending = tx;
> +       ring_param.rx_pending = rx;
> +
> +       ring_param.cmd = ETHTOOL_SRINGPARAM;
> +       ifr.ifr_data = (char *)&ring_param;
> +
> +       while (ctr++ < SOCK_RECONF_CTR) {
> +               ret = ioctl(sockfd, SIOCETHTOOL, &ifr);
> +               if (!ret)
> +                       break;
> +               /* Retry if it fails */
> +               if (ctr >= SOCK_RECONF_CTR) {
> +                       close(sockfd);
> +                       return errno;
> +               }
> +               usleep(USLEEP_MAX);

Does it really have to sleep or copy paste from other places?
This ioctl() is supposed to do synchronous config, no?
Stanislav Fomichev March 15, 2024, 5:44 p.m. UTC | #2
On 03/15, Tushar Vyavahare wrote:
> Introduce a new function called set_hw_ring_size that allows for the
> dynamic configuration of the ring size within the interface.
> 
> Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
> ---
>  tools/testing/selftests/bpf/xskxceiver.c | 35 ++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
> 
> diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
> index 32005bfb9c9f..aafa78307586 100644
> --- a/tools/testing/selftests/bpf/xskxceiver.c
> +++ b/tools/testing/selftests/bpf/xskxceiver.c
> @@ -441,6 +441,41 @@ static int get_hw_ring_size(struct ifobject *ifobj)
>  	return 0;
>  }
>  
> +static int set_hw_ring_size(struct ifobject *ifobj, u32 tx, u32 rx)

Hmm, now that we have set/get, should we put them into
network_helpers.c? These seem pretty generic if you accept
iface_name + ethtool_ringparam in the api.

> +{
> +	struct ethtool_ringparam ring_param = {0};
> +	struct ifreq ifr = {0};
> +	int sockfd, ret;
> +	u32 ctr = 0;
> +
> +	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
> +	if (sockfd < 0)
> +		return errno;
> +
> +	memcpy(ifr.ifr_name, ifobj->ifname, sizeof(ifr.ifr_name));
> +
> +	ring_param.tx_pending = tx;
> +	ring_param.rx_pending = rx;
> +
> +	ring_param.cmd = ETHTOOL_SRINGPARAM;
> +	ifr.ifr_data = (char *)&ring_param;
> +

[..]

> +	while (ctr++ < SOCK_RECONF_CTR) {

Is it to retry EINTR? Retrying something else doesn't make sense
probably? So maybe do only errno==EINTR cases? Will make it more
generic and not dependent on SOCK_RECONF_CTR.


> +		ret = ioctl(sockfd, SIOCETHTOOL, &ifr);
> +		if (!ret)
> +			break;
> +		/* Retry if it fails */
> +		if (ctr >= SOCK_RECONF_CTR) {
> +			close(sockfd);
> +			return errno;
> +		}

[..]

> +		usleep(USLEEP_MAX);

Same here. Not sure what's the purpose of sleep? Alternatively, maybe
clarify in the commit description what particular error case we want
to retry.
Tushar Vyavahare March 19, 2024, 6:52 a.m. UTC | #3
> -----Original Message-----
> From: Stanislav Fomichev <sdf@google.com>
> Sent: Friday, March 15, 2024 11:14 PM
> To: Vyavahare, Tushar <tushar.vyavahare@intel.com>
> Cc: bpf@vger.kernel.org; netdev@vger.kernel.org; bjorn@kernel.org; Karlsson,
> Magnus <magnus.karlsson@intel.com>; Fijalkowski, Maciej
> <maciej.fijalkowski@intel.com>; jonathan.lemon@gmail.com;
> davem@davemloft.net; kuba@kernel.org; pabeni@redhat.com;
> ast@kernel.org; daniel@iogearbox.net; Sarkar, Tirthendu
> <tirthendu.sarkar@intel.com>
> Subject: Re: [PATCH bpf-next 4/6] selftests/xsk: implement set_hw_ring_size
> function to configure interface ring size
> 
> On 03/15, Tushar Vyavahare wrote:
> > Introduce a new function called set_hw_ring_size that allows for the
> > dynamic configuration of the ring size within the interface.
> >
> > Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
> > ---
> >  tools/testing/selftests/bpf/xskxceiver.c | 35
> > ++++++++++++++++++++++++
> >  1 file changed, 35 insertions(+)
> >
> > diff --git a/tools/testing/selftests/bpf/xskxceiver.c
> > b/tools/testing/selftests/bpf/xskxceiver.c
> > index 32005bfb9c9f..aafa78307586 100644
> > --- a/tools/testing/selftests/bpf/xskxceiver.c
> > +++ b/tools/testing/selftests/bpf/xskxceiver.c
> > @@ -441,6 +441,41 @@ static int get_hw_ring_size(struct ifobject *ifobj)
> >  	return 0;
> >  }
> >
> > +static int set_hw_ring_size(struct ifobject *ifobj, u32 tx, u32 rx)
> 
> Hmm, now that we have set/get, should we put them into network_helpers.c?
> These seem pretty generic if you accept iface_name + ethtool_ringparam in
> the api.
> 

Clean version of get_hw_ring_size() and set_hw_ring_size() both are moved to network_helpers.c

> > +{
> > +	struct ethtool_ringparam ring_param = {0};
> > +	struct ifreq ifr = {0};
> > +	int sockfd, ret;
> > +	u32 ctr = 0;
> > +
> > +	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
> > +	if (sockfd < 0)
> > +		return errno;
> > +
> > +	memcpy(ifr.ifr_name, ifobj->ifname, sizeof(ifr.ifr_name));
> > +
> > +	ring_param.tx_pending = tx;
> > +	ring_param.rx_pending = rx;
> > +
> > +	ring_param.cmd = ETHTOOL_SRINGPARAM;
> > +	ifr.ifr_data = (char *)&ring_param;
> > +
> 
> [..]
> 
> > +	while (ctr++ < SOCK_RECONF_CTR) {
> 
> Is it to retry EINTR? Retrying something else doesn't make sense probably? So
> maybe do only errno==EINTR cases? Will make it more generic and not
> dependent on SOCK_RECONF_CTR.
> 
> 

The close of an AF_XDP socket is an asynchronous operation. When an AF_XDP socket is active, changing the ring size is forbidden. Therefore, when we call set_hw_ring_size(), a previous AF_XDP socket might still be in the process of being closed and the ioct() will then fail, as it is forbidden to change the ring size when there is an active AF_XDP socket.

When the AF_XDP socket is active, we are getting an EBUSY error. I will handle the retry logic for this in a separate patch for xskxceiver.c.

> > +		ret = ioctl(sockfd, SIOCETHTOOL, &ifr);
> > +		if (!ret)
> > +			break;
> > +		/* Retry if it fails */
> > +		if (ctr >= SOCK_RECONF_CTR) {
> > +			close(sockfd);
> > +			return errno;
> > +		}
> 
> [..]
> 
> > +		usleep(USLEEP_MAX);
> 
> Same here. Not sure what's the purpose of sleep? Alternatively, maybe clarify
> in the commit description what particular error case we want to retry.

Removed this retry logic from set_hw_ring_size() , which moved to networks_helpers.c.
I will handle the retry logic with sleep for this in a separate patch for xskxceiver.c and I will put this in the commit message.
Tushar Vyavahare March 19, 2024, 6:54 a.m. UTC | #4
> -----Original Message-----
> From: Alexei Starovoitov <alexei.starovoitov@gmail.com>
> Sent: Friday, March 15, 2024 9:18 PM
> To: Vyavahare, Tushar <tushar.vyavahare@intel.com>
> Cc: bpf <bpf@vger.kernel.org>; Network Development
> <netdev@vger.kernel.org>; Björn Töpel <bjorn@kernel.org>; Karlsson, Magnus
> <magnus.karlsson@intel.com>; Fijalkowski, Maciej
> <maciej.fijalkowski@intel.com>; Jonathan Lemon
> <jonathan.lemon@gmail.com>; David S. Miller <davem@davemloft.net>; Jakub
> Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; Alexei
> Starovoitov <ast@kernel.org>; Daniel Borkmann <daniel@iogearbox.net>;
> Sarkar, Tirthendu <tirthendu.sarkar@intel.com>
> Subject: Re: [PATCH bpf-next 4/6] selftests/xsk: implement set_hw_ring_size
> function to configure interface ring size
> 
> On Fri, Mar 15, 2024 at 7:23 AM Tushar Vyavahare
> <tushar.vyavahare@intel.com> wrote:
> >
> > Introduce a new function called set_hw_ring_size that allows for the
> > dynamic configuration of the ring size within the interface.
> >
> > Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
> > ---
> >  tools/testing/selftests/bpf/xskxceiver.c | 35
> > ++++++++++++++++++++++++
> >  1 file changed, 35 insertions(+)
> >
> > diff --git a/tools/testing/selftests/bpf/xskxceiver.c
> > b/tools/testing/selftests/bpf/xskxceiver.c
> > index 32005bfb9c9f..aafa78307586 100644
> > --- a/tools/testing/selftests/bpf/xskxceiver.c
> > +++ b/tools/testing/selftests/bpf/xskxceiver.c
> > @@ -441,6 +441,41 @@ static int get_hw_ring_size(struct ifobject *ifobj)
> >         return 0;
> >  }
> >
> > +static int set_hw_ring_size(struct ifobject *ifobj, u32 tx, u32 rx) {
> > +       struct ethtool_ringparam ring_param = {0};
> > +       struct ifreq ifr = {0};
> > +       int sockfd, ret;
> > +       u32 ctr = 0;
> > +
> > +       sockfd = socket(AF_INET, SOCK_DGRAM, 0);
> > +       if (sockfd < 0)
> > +               return errno;
> > +
> > +       memcpy(ifr.ifr_name, ifobj->ifname, sizeof(ifr.ifr_name));
> > +
> > +       ring_param.tx_pending = tx;
> > +       ring_param.rx_pending = rx;
> > +
> > +       ring_param.cmd = ETHTOOL_SRINGPARAM;
> > +       ifr.ifr_data = (char *)&ring_param;
> > +
> > +       while (ctr++ < SOCK_RECONF_CTR) {
> > +               ret = ioctl(sockfd, SIOCETHTOOL, &ifr);
> > +               if (!ret)
> > +                       break;
> > +               /* Retry if it fails */
> > +               if (ctr >= SOCK_RECONF_CTR) {
> > +                       close(sockfd);
> > +                       return errno;
> > +               }
> > +               usleep(USLEEP_MAX);
> 
> Does it really have to sleep or copy paste from other places?
> This ioctl() is supposed to do synchronous config, no?

Response in the previous mail  to Stanislav Fomichev <sdf@google.com>
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
index 32005bfb9c9f..aafa78307586 100644
--- a/tools/testing/selftests/bpf/xskxceiver.c
+++ b/tools/testing/selftests/bpf/xskxceiver.c
@@ -441,6 +441,41 @@  static int get_hw_ring_size(struct ifobject *ifobj)
 	return 0;
 }
 
+static int set_hw_ring_size(struct ifobject *ifobj, u32 tx, u32 rx)
+{
+	struct ethtool_ringparam ring_param = {0};
+	struct ifreq ifr = {0};
+	int sockfd, ret;
+	u32 ctr = 0;
+
+	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sockfd < 0)
+		return errno;
+
+	memcpy(ifr.ifr_name, ifobj->ifname, sizeof(ifr.ifr_name));
+
+	ring_param.tx_pending = tx;
+	ring_param.rx_pending = rx;
+
+	ring_param.cmd = ETHTOOL_SRINGPARAM;
+	ifr.ifr_data = (char *)&ring_param;
+
+	while (ctr++ < SOCK_RECONF_CTR) {
+		ret = ioctl(sockfd, SIOCETHTOOL, &ifr);
+		if (!ret)
+			break;
+		/* Retry if it fails */
+		if (ctr >= SOCK_RECONF_CTR) {
+			close(sockfd);
+			return errno;
+		}
+		usleep(USLEEP_MAX);
+	}
+
+	close(sockfd);
+	return 0;
+}
+
 static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
 			     struct ifobject *ifobj_rx)
 {