Skip to contentSkip to conversation

liburing: add api for napi busy poll

PATCH Superseded Stefan Roesch 2 participants 7 messages Nov 21, 2022 – Nov 25, 2022

Subsystems (3)

v5 of 9 Superseded Latest is v9 →

lore
Share & tools
lore
#0 lore raw

v5 cover liburing: add api for napi busy poll

This adds two new api's to set/clear the napi busy poll settings. The two new functions are called:
- io_uring_register_napi
- io_uring_unregister_napi

The patch series also contains the documentation for the two new functions and two example programs. The client program is called napi-busy-poll-client and the server program napi-busy-poll-server. The client measures the roundtrip times of requests.

There is also a kernel patch "io-uring: support napi busy poll" to enable this feature on the kernel side.

Changes:
- V5:
- Fixes to documentation.
- Correct opcode for unregister call
- Initialize napi structure in example programs
- Address tab issues in recordRTT()
- V4:
- Modify functions to use a structure to pass the napi busy poll settings to the kernel.
- Return previous values when returning from the above functions.
- Rename the functions and remove one function (no longer needed as the data is passed as a structure)
- V3:
- Updated liburing.map file
- Moved example programs from the test directory to the example directory. The two example programs don't fit well in the test category and need to be run from separate hosts.
- Added the io_uring_register_napi_prefer_busy_poll API.
- Added the call to io_uring_register_napi_prefer_busy_poll to the example programs
- Updated the documentation
- V2:
- Updated the liburing.map file for the two new functions. (added a 2.4 section)
- Added a description of the new feature to the changelog file
- Fixed the indentation of the longopts structure
- Used defined exit constants
- Fixed encodeUserData to support 32 bit builds

Stefan Roesch (4):
liburing: add api to set napi busy poll settings
liburing: add documentation for new napi busy polling
liburing: add example programs for napi busy poll
liburing: update changelog with new feature

 .gitignore                       |   2 +
 CHANGELOG                        |   3 +
 examples/Makefile                |   2 +
 examples/napi-busy-poll-client.c | 442 +++++++++++++++++++++++++++++++
 examples/napi-busy-poll-server.c | 386 +++++++++++++++++++++++++++
 man/io_uring_register_napi.3     |  40 +++
 man/io_uring_unregister_napi.3   |  27 ++
 src/include/liburing.h           |   3 +
 src/include/liburing/io_uring.h  |  12 +
 src/liburing.map                 |   6 +
 src/register.c                   |  12 +
 11 files changed, 935 insertions(+)
 create mode 100644 examples/napi-busy-poll-client.c
 create mode 100644 examples/napi-busy-poll-server.c
 create mode 100644 man/io_uring_register_napi.3
 create mode 100644 man/io_uring_unregister_napi.3

base-commit: 8fc22e3b3348c0a6384ec926e0b19b6707622e58

Signature · 1 line
2.30.2
#1 lore raw

PATCH v5 1/4 liburing: add api to set napi busy poll settings

This adds two functions to manage the napi busy poll settings:
- io_uring_register_napi
- io_uring_unregister_napi

---
 src/include/liburing.h          |  3 +++
 src/include/liburing/io_uring.h | 12 ++++++++++++
 src/liburing.map                |  6 ++++++
 src/register.c                  | 12 ++++++++++++
 4 files changed, 33 insertions(+)
src/include/liburing.h +3 -0
index 12a703f..98ffd73 100644
@@ -235,6 +235,9 @@ int io_uring_register_sync_cancel(struct io_uring *ring,
 int io_uring_register_file_alloc_range(struct io_uring *ring,
 					unsigned off, unsigned len);
 
+int io_uring_register_napi(struct io_uring *ring, struct io_uring_napi *napi);
+int io_uring_unregister_napi(struct io_uring *ring, struct io_uring_napi *napi);
+
 int io_uring_get_events(struct io_uring *ring);
 int io_uring_submit_and_get_events(struct io_uring *ring);
 
src/include/liburing/io_uring.h +12 -0
index a3e0920..25caee3 100644
@@ -499,6 +499,10 @@ enum {
 	/* register a range of fixed file slots for automatic slot allocation */
 	IORING_REGISTER_FILE_ALLOC_RANGE	= 25,
 
+	/* set/clear busy poll settings */
+	IORING_REGISTER_NAPI			= 26,
+	IORING_UNREGISTER_NAPI			= 27,
+
 	/* this goes last */
 	IORING_REGISTER_LAST
 };
@@ -621,6 +625,14 @@ struct io_uring_buf_reg {
 	__u64	resv[3];
 };
 
+/* argument for IORING_(UN)REGISTER_NAPI */
+struct io_uring_napi {
+	__u32   busy_poll_to;
+	__u8    prefer_busy_poll;
+	__u8    pad[3];
+	__u64   resv;
+};
+
 /*
  * io_uring_restriction->opcode values
  */
src/liburing.map +6 -0
index 06c64f8..74036d3 100644
@@ -67,3 +67,9 @@ LIBURING_2.3 {
 		io_uring_get_events;
 		io_uring_submit_and_get_events;
 } LIBURING_2.2;
+
+LIBURING_2.4 {
+	global:
+		io_uring_register_napi;
+		io_uring_unregister_napi;
+} LIBURING_2.3;
src/register.c +12 -0
index e849825..ff87e73 100644
@@ -367,3 +367,15 @@ int io_uring_register_file_alloc_range(struct io_uring *ring,
 				       IORING_REGISTER_FILE_ALLOC_RANGE, &range,
 				       0);
 }
+
+int io_uring_register_napi(struct io_uring *ring, struct io_uring_napi *napi)
+{
+	return __sys_io_uring_register(ring->ring_fd,
+				IORING_REGISTER_NAPI, napi, 0);
+}
+
+int io_uring_unregister_napi(struct io_uring *ring, struct io_uring_napi *napi)
+{
+	return __sys_io_uring_register(ring->ring_fd,
+				IORING_UNREGISTER_NAPI, napi, 0);
+}
Signature · 1 line
2.30.2
#2 lore raw

PATCH v5 2/4 liburing: add documentation for new napi busy polling

In reply to Stefan Roesch

This adds two man pages for the two new functions:
- io_uring_register_nap
- io_uring_unregister_napi

---
 man/io_uring_register_napi.3   | 40 ++++++++++++++++++++++++++++++++++
 man/io_uring_unregister_napi.3 | 27 +++++++++++++++++++++++
 2 files changed, 67 insertions(+)
 create mode 100644 man/io_uring_register_napi.3
 create mode 100644 man/io_uring_unregister_napi.3
man/io_uring_register_napi.3 new file +40 -0
new file mode 100644
index 0000000..78eaa71
@@ -0,0 +1,40 @@
+.\" Copyright (C) 2022 Stefan Roesch <[email protected]>
+.\"
+.\" SPDX-License-Identifier: LGPL-2.0-or-later
+.\"
+.TH io_uring_register_napi 3 "November 16, 2022" "liburing-2.4" "liburing Manual"
+.SH NAME
+io_uring_register_napi \- register NAPI busy poll settings
+.SH SYNOPSIS
+.nf
+.B #include <liburing.h>
+.PP
+.BI "int io_uring_register_napi(struct io_uring *" ring ","
+.BI "                           struct io_uring_napi *" napi)
+.PP
+.fi
+.SH DESCRIPTION
+.PP
+The
+.BR io_uring_register_napi (3)
+function registers the NAPI settings for subsequent operations. The NAPI
+settings are specified in the structure that is passed in the
+.I napi
+parameter. The structure consists of the napi timeout
+.I busy_poll_to
+(napi busy poll timeout in us) and
+.I prefer_busy_poll.
+
+Registering a NAPI settings sets the mode when calling the function
+napi_busy_loop and corresponds to the SO_PREFER_BUSY_POLL socket
+option.
+
+NAPI busy poll can reduce the network roundtrip time.
+
+
+.SH RETURN VALUE
+On success
+.BR io_uring_register_napi (3)
+return 0. On failure they return
+.BR -errno .
+It also updates the napi structure with the current values.
man/io_uring_unregister_napi.3 new file +27 -0
new file mode 100644
index 0000000..f7087ef
@@ -0,0 +1,27 @@
+.\" Copyright (C) 2022 Stefan Roesch <[email protected]>
+.\"
+.\" SPDX-License-Identifier: LGPL-2.0-or-later
+.\"
+.TH io_uring_unregister_napi 3 "November 16, 2022" "liburing-2.4" "liburing Manual"
+.SH NAME
+io_uring_unregister_napi \- unregister NAPI busy poll settings
+.SH SYNOPSIS
+.nf
+.B #include <liburing.h>
+.PP
+.BI "int io_uring_unregister_napi(struct io_uring *" ring ","
+.BI "                             struct io_uring_napi *" napi)
+.PP
+.fi
+.SH DESCRIPTION
+.PP
+The
+.BR io_uring_unregister_napi (3)
+function unregisters the NAPI busy poll settings for subsequent operations.
+
+.SH RETURN VALUE
+On success
+.BR io_uring_unregister_napi (3)
+return 0. On failure they return
+.BR -errno .
+It also updates the napi structure with the current values.
Signature · 1 line
2.30.2
#3 lore raw

PATCH v5 3/4 liburing: add example programs for napi busy poll

In reply to Stefan Roesch

This adds two example programs to test the napi busy poll functionality. It consists of a client program and a server program. To get a napi id, the client and the server program need to be run on different hosts.

To test the napi busy poll timeout, the -t needs to be specified. A reasonable value for the busy poll timeout is 100. By specifying the busy poll timeout on the server and the client the best results are accomplished.

---
 .gitignore                       |   2 +
 examples/Makefile                |   2 +
 examples/napi-busy-poll-client.c | 442 +++++++++++++++++++++++++++++++
 examples/napi-busy-poll-server.c | 386 +++++++++++++++++++++++++++
 4 files changed, 832 insertions(+)
 create mode 100644 examples/napi-busy-poll-client.c
 create mode 100644 examples/napi-busy-poll-server.c
.gitignore +2 -0
index 6e8a2f7..89b5a41 100644
@@ -15,6 +15,8 @@
 /examples/io_uring-test
 /examples/io_uring-udp
 /examples/link-cp
+/examples/napi-busy-poll-client
+/examples/napi-busy-poll-server
 /examples/ucontext-cp
 /examples/poll-bench
 /examples/send-zerocopy
examples/Makefile +2 -0
index e561e05..59f1260 100644
@@ -15,6 +15,8 @@ example_srcs := \
 	io_uring-test.c \
 	io_uring-udp.c \
 	link-cp.c \
+	napi-busy-poll-client.c \
+	napi-busy-poll-server.c \
 	poll-bench.c \
 	send-zerocopy.c
 
examples/napi-busy-poll-client.c new file +442 -0

442 lines not on this page · raw message

examples/napi-busy-poll-server.c new file +386 -0

386 lines not on this page · raw message

Signature · 1 line
2.30.2
#4 lore raw

Re: [PATCH v5 3/4] liburing: add example programs for napi busy poll

Quoted 10 lines · Stefan Roesch

This adds two example programs to test the napi busy poll functionality. It consists of a client program and a server program. To get a napi id, the client and the server program need to be run on different hosts.

To test the napi busy poll timeout, the -t needs to be specified. A reasonable value for the busy poll timeout is 100. By specifying the busy poll timeout on the server and the client the best results are accomplished.

Since commit:

    fd6b571b0b03aeeb529f235c5c9c0a7c3256340c ("github: Add -Wmissing-prototypes for GitHub CI bot")

liburing GitHub CI robot enforces functions and global variables that are not used outside the translation unit to be marked as static.

This patch fails the build.

GitHub CI says:

clang -Werror -D_GNU_SOURCE -I../src/include/ -g -O3 -Wall -Wextra -Werror -Wmissing-prototypes -o napi-busy-poll-client napi-busy-poll-client.c -L../src/ -luring clang -Werror -D_GNU_SOURCE -I../src/include/ -g -O3 -Wall -Wextra -Werror -Wmissing-prototypes -o napi-busy-poll-server napi-busy-poll-server.c -L../src/ -luring napi-busy-poll-client.c:78:6: error: no previous prototype for function 'printUsage' [-Werror,-Wmissing-prototypes]
void printUsage(const char *name)

       ^
  napi-busy-poll-client.c:78:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void printUsage(const char *name)
  ^
  static
  napi-busy-poll-client.c:102:6: error: no previous prototype for function 'printError' [-Werror,-Wmissing-prototypes]
  void printError(const char *msg, int opt)
       ^
  napi-busy-poll-client.c:102:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void printError(const char *msg, int opt)
  ^
  static
  napi-busy-poll-client.c:108:6: error: no previous prototype for function 'setProcessScheduler' [-Werror,-Wmissing-prototypes]
  void setProcessScheduler(void)
       ^
  napi-busy-poll-client.c:108:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void setProcessScheduler(void)
  ^
  static
  napi-busy-poll-client.c:118:8: error: no previous prototype for function 'diffTimespec' [-Werror,-Wmissing-prototypes]
  double diffTimespec(const struct timespec *time1, const struct timespec *time0)
         ^
  napi-busy-poll-client.c:118:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  double diffTimespec(const struct timespec *time1, const struct timespec *time0)
  ^
  static
  napi-busy-poll-client.c:124:10: error: no previous prototype for function 'encodeUserData' [-Werror,-Wmissing-prototypes]
  uint64_t encodeUserData(char type, int fd)
           ^
  napi-busy-poll-client.c:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  uint64_t encodeUserData(char type, int fd)
  ^
  static
  napi-busy-poll-client.c:129:6: error: no previous prototype for function 'decodeUserData' [-Werror,-Wmissing-prototypes]
  void decodeUserData(uint64_t data, char *type, int *fd)
       ^
  napi-busy-poll-client.c:129:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void decodeUserData(uint64_t data, char *type, int *fd)
  ^
  static
  napi-busy-poll-client.c:135:13: error: no previous prototype for function 'opTypeToStr' [-Werror,-Wmissing-prototypes]
  const char *opTypeToStr(char type)
              ^
  napi-busy-poll-client.c:135:7: note: declare 'static' if the function is not intended to be used outside of this translation unit
  const char *opTypeToStr(char type)
        ^
  static
  napi-busy-poll-client.c:159:6: error: no previous prototype for function 'reportNapi' [-Werror,-Wmissing-prototypes]
  void reportNapi(struct ctx *ctx)
       ^
  napi-busy-poll-client.c:159:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void reportNapi(struct ctx *ctx)
  ^
  static
  napi-busy-poll-client.c:173:6: error: no previous prototype for function 'sendPing' [-Werror,-Wmissing-prototypes]
  void sendPing(struct ctx *ctx)
       ^
  napi-busy-poll-client.c:173:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void sendPing(struct ctx *ctx)
  ^
  static
  napi-busy-poll-client.c:183:6: error: no previous prototype for function 'receivePing' [-Werror,-Wmissing-prototypes]
  void receivePing(struct ctx *ctx)
       ^
  napi-busy-poll-client.c:183:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void receivePing(struct ctx *ctx)
  ^
  static
  napi-busy-poll-client.c:191:6: error: no previous prototype for function 'recordRTT' [-Werror,-Wmissing-prototypes]
  void recordRTT(struct ctx *ctx)
       ^
  napi-busy-poll-client.c:191:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void recordRTT(struct ctx *ctx)
  ^
  static
  napi-busy-poll-client.c:203:6: error: no previous prototype for function 'printStats' [-Werror,-Wmissing-prototypes]
  void printStats(struct ctx *ctx)
       ^
  napi-busy-poll-client.c:203:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void printStats(struct ctx *ctx)
  ^
  static
  napi-busy-poll-client.c:230:5: error: no previous prototype for function 'completion' [-Werror,-Wmissing-prototypes]
  int completion(struct ctx *ctx, struct io_uring_cqe *cqe)
      ^
  napi-busy-poll-client.c:230:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  int completion(struct ctx *ctx, struct io_uring_cqe *cqe)
  ^
  static
  13 errors generated.
  make[1]: *** [Makefile:38: napi-busy-poll-client] Error 1
  make[1]: *** Waiting for unfinished jobs....
  napi-busy-poll-server.c:78:6: error: no previous prototype for function 'printUsage' [-Werror,-Wmissing-prototypes]
  void printUsage(const char *name)
       ^
  napi-busy-poll-server.c:78:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void printUsage(const char *name)
  ^
  static
  napi-busy-poll-server.c:104:6: error: no previous prototype for function 'printError' [-Werror,-Wmissing-prototypes]
  void printError(const char *msg, int opt)
       ^
  napi-busy-poll-server.c:104:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void printError(const char *msg, int opt)
  ^
  static
  napi-busy-poll-server.c:110:6: error: no previous prototype for function 'setProcessScheduler' [-Werror,-Wmissing-prototypes]
  void setProcessScheduler()
       ^
  napi-busy-poll-server.c:110:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void setProcessScheduler()
  ^
  static
  napi-busy-poll-server.c:120:10: error: no previous prototype for function 'encodeUserData' [-Werror,-Wmissing-prototypes]
  uint64_t encodeUserData(char type, int fd)
           ^
  napi-busy-poll-server.c:120:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  uint64_t encodeUserData(char type, int fd)
  ^
  static
  napi-busy-poll-server.c:125:6: error: no previous prototype for function 'decodeUserData' [-Werror,-Wmissing-prototypes]
  void decodeUserData(uint64_t data, char *type, int *fd)
       ^
  napi-busy-poll-server.c:125:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void decodeUserData(uint64_t data, char *type, int *fd)
  ^
  static
  napi-busy-poll-server.c:131:13: error: no previous prototype for function 'opTypeToStr' [-Werror,-Wmissing-prototypes]
  const char *opTypeToStr(char type)
              ^
  napi-busy-poll-server.c:131:7: note: declare 'static' if the function is not intended to be used outside of this translation unit
  const char *opTypeToStr(char type)
        ^
  static
  napi-busy-poll-server.c:155:6: error: no previous prototype for function 'reportNapi' [-Werror,-Wmissing-prototypes]
  void reportNapi(struct ctx *ctx)
       ^
  napi-busy-poll-server.c:155:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void reportNapi(struct ctx *ctx)
  ^
  static
  napi-busy-poll-server.c:169:6: error: no previous prototype for function 'sendPing' [-Werror,-Wmissing-prototypes]
  void sendPing(struct ctx *ctx)
       ^
  napi-busy-poll-server.c:169:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void sendPing(struct ctx *ctx)
  ^
  static
  napi-busy-poll-server.c:178:6: error: no previous prototype for function 'receivePing' [-Werror,-Wmissing-prototypes]
  void receivePing(struct ctx *ctx)
       ^
  napi-busy-poll-server.c:178:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
  void receivePing(struct ctx *ctx)
  ^
  static
  napi-busy-poll-server.c:193:6: error: no previous prototype for function 'completion' [-Werror,-Wmissing-prototypes]
  void completion(struct ctx *ctx, struct io_uring_cqe *cqe)
       ^

napi-busy-poll-server.c:193:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void completion(struct ctx *ctx, struct io_uring_cqe *cqe)
^
static
10 errors generated.
make[1]: *** [Makefile:38: napi-busy-poll-server] Error 1
make: *** [Makefile:12: all] Error 2
make[1]: Leaving directory '/home/runner/work/liburing/liburing/examples'
Error: Process completed with exit code 2.

Signature · 1 line
Ammar Faizi
#5 lore raw

Re: [PATCH v5 3/4] liburing: add example programs for napi busy poll

In reply to Stefan Roesch
Quoted 10 lines · Stefan Roesch

This adds two example programs to test the napi busy poll functionality. It consists of a client program and a server program. To get a napi id, the client and the server program need to be run on different hosts.

To test the napi busy poll timeout, the -t needs to be specified. A reasonable value for the busy poll timeout is 100. By specifying the busy poll timeout on the server and the client the best results are accomplished.

Also, please fix your indentation. You have random indentation all over the places.

Applying: liburing: add example programs for napi busy poll .git/rebase-apply/patch:258: space before tab in indent.

          	avgRTT += ctx->rtt[i];
  .git/rebase-apply/patch:322: trailing whitespace.
  	int flag;
  .git/rebase-apply/patch:346: space before tab in indent.
                  	opt.sq_poll = true;
  .git/rebase-apply/patch:382: space before tab in indent.
          	fprintf(stderr, "inet_pton error for %s\n", optarg);
  .git/rebase-apply/patch:391: space before tab in indent.
          	fprintf(stderr, "socket() failed: (%d) %s\n", errno, strerror(errno));

warning: squelched 6 whitespace errors
warning: 11 lines add whitespace errors.

Signature · 1 line
Ammar Faizi
#6 lore raw

PATCH v5 4/4 liburing: update changelog with new feature

In reply to Stefan Roesch

Add a new entry to the changelog file for the napi busy poll feature.

---
 CHANGELOG | 3 +++
 1 file changed, 3 insertions(+)
CHANGELOG +3 -0
index 09511af..1db0269 100644
@@ -1,3 +1,6 @@
+liburing-2.4 release
+- Support for napi busy polling
+
 liburing-2.3 release
 
 - Support non-libc build for aarch64.
Signature · 1 line
2.30.2