All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] fast poll multishot mode
@ 2022-05-06  7:00 Hao Xu
  2022-05-06  7:00 ` [PATCH 1/5] io_uring: add IORING_ACCEPT_MULTISHOT for accept Hao Xu
                   ` (6 more replies)
  0 siblings, 7 replies; 37+ messages in thread
From: Hao Xu @ 2022-05-06  7:00 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, Pavel Begunkov, linux-kernel

Let multishot support multishot mode, currently only add accept as its
first comsumer.
theoretical analysis:
  1) when connections come in fast
    - singleshot:
              add accept sqe(userpsace) --> accept inline
                              ^                 |
                              |-----------------|
    - multishot:
             add accept sqe(userspace) --> accept inline
                                              ^     |
                                              |--*--|

    we do accept repeatedly in * place until get EAGAIN

  2) when connections come in at a low pressure
    similar thing like 1), we reduce a lot of userspace-kernel context
    switch and useless vfs_poll()


tests:
Did some tests, which goes in this way:

  server    client(multiple)
  accept    connect
  read      write
  write     read
  close     close

Basically, raise up a number of clients(on same machine with server) to
connect to the server, and then write some data to it, the server will
write those data back to the client after it receives them, and then
close the connection after write return. Then the client will read the
data and then close the connection. Here I test 10000 clients connect
one server, data size 128 bytes. And each client has a go routine for
it, so they come to the server in short time.
test 20 times before/after this patchset, time spent:(unit cycle, which
is the return value of clock())
before:
  1930136+1940725+1907981+1947601+1923812+1928226+1911087+1905897+1941075
  +1934374+1906614+1912504+1949110+1908790+1909951+1941672+1969525+1934984
  +1934226+1914385)/20.0 = 1927633.75
after:
  1858905+1917104+1895455+1963963+1892706+1889208+1874175+1904753+1874112
  +1874985+1882706+1884642+1864694+1906508+1916150+1924250+1869060+1889506
  +1871324+1940803)/20.0 = 1894750.45

(1927633.75 - 1894750.45) / 1927633.75 = 1.65%


A liburing test is here:
https://github.com/HowHsu/liburing/blob/multishot_accept/test/accept.c

v1->v2:
 - re-implement it against the reworked poll code

Hao Xu (5):
  io_uring: add IORING_ACCEPT_MULTISHOT for accept
  io_uring: add REQ_F_APOLL_MULTISHOT for requests
  io_uring: let fast poll support multishot
  io_uring: add a helper for poll clean
  io_uring: implement multishot mode for accept

 fs/io_uring.c                 | 121 ++++++++++++++++++++++++++--------
 include/uapi/linux/io_uring.h |   5 ++
 2 files changed, 100 insertions(+), 26 deletions(-)


base-commit: f2e030dd7aaea5a937a2547dc980fab418fbc5e7
-- 
2.36.0


^ permalink raw reply	[flat|nested] 37+ messages in thread
* Re: [PATCH 3/5] io_uring: let fast poll support multishot
@ 2022-05-08  9:48 kernel test robot
  0 siblings, 0 replies; 37+ messages in thread
From: kernel test robot @ 2022-05-08  9:48 UTC (permalink / raw)
  To: kbuild

[-- Attachment #1: Type: text/plain, Size: 15035 bytes --]

CC: llvm(a)lists.linux.dev
CC: kbuild-all(a)lists.01.org
BCC: lkp(a)intel.com
In-Reply-To: <20220506070102.26032-4-haoxu.linux@gmail.com>
References: <20220506070102.26032-4-haoxu.linux@gmail.com>
TO: Hao Xu <haoxu.linux@gmail.com>

Hi Hao,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on f2e030dd7aaea5a937a2547dc980fab418fbc5e7]

url:    https://github.com/intel-lab-lkp/linux/commits/Hao-Xu/fast-poll-multishot-mode/20220506-150750
base:   f2e030dd7aaea5a937a2547dc980fab418fbc5e7
:::::: branch date: 2 days ago
:::::: commit date: 2 days ago
config: x86_64-randconfig-c007 (https://download.01.org/0day-ci/archive/20220508/202205081710.JNZmSYT9-lkp(a)intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 5e004fb787698440a387750db7f8028e7cb14cfc)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/6001c3e95550875d4328aa2ca8b342c42b0e644e
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Hao-Xu/fast-poll-multishot-mode/20220506-150750
        git checkout 6001c3e95550875d4328aa2ca8b342c42b0e644e
        # save the config file
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 clang-analyzer 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


clang-analyzer warnings: (new ones prefixed by >>)
                           ^
   include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
   #define memset(p, c, s) __fortify_memset_chk(p, c, s,                   \
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
           __underlying_memset(p, c, __fortify_size);                      \
           ^~~~~~~~~~~~~~~~~~~
   include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
   #define __underlying_memset     __builtin_memset
                                   ^~~~~~~~~~~~~~~~
   drivers/acpi/acpica/nsinit.c:168:4: note: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11
                           memset(info.evaluate_info, 0,
                           ^
   include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
   #define memset(p, c, s) __fortify_memset_chk(p, c, s,                   \
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
           __underlying_memset(p, c, __fortify_size);                      \
           ^~~~~~~~~~~~~~~~~~~
   include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
   #define __underlying_memset     __builtin_memset
                                   ^~~~~~~~~~~~~~~~
   drivers/acpi/acpica/nsinit.c:639:3: warning: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
                   memset(info, 0, sizeof(struct acpi_evaluate_info));
                   ^
   include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
   #define memset(p, c, s) __fortify_memset_chk(p, c, s,                   \
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
           __underlying_memset(p, c, __fortify_size);                      \
           ^~~~~~~~~~~~~~~~~~~
   include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
   #define __underlying_memset     __builtin_memset
                                   ^~~~~~~~~~~~~~~~
   drivers/acpi/acpica/nsinit.c:639:3: note: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11
                   memset(info, 0, sizeof(struct acpi_evaluate_info));
                   ^
   include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
   #define memset(p, c, s) __fortify_memset_chk(p, c, s,                   \
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
           __underlying_memset(p, c, __fortify_size);                      \
           ^~~~~~~~~~~~~~~~~~~
   include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
   #define __underlying_memset     __builtin_memset
                                   ^~~~~~~~~~~~~~~~
   Suppressed 17 warnings (17 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
   47 warnings generated.
   fs/aio.c:702:4: warning: Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
                           memcpy(table->table, old->table,
                           ^
   include/linux/fortify-string.h:369:26: note: expanded from macro 'memcpy'
   #define memcpy(p, q, s)  __fortify_memcpy_chk(p, q, s,                  \
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/fortify-string.h:362:2: note: expanded from macro '__fortify_memcpy_chk'
           __underlying_##op(p, q, __fortify_size);                        \
           ^~~~~~~~~~~~~~~~~
   note: expanded from here
   include/linux/fortify-string.h:45:29: note: expanded from macro '__underlying_memcpy'
   #define __underlying_memcpy     __builtin_memcpy
                                   ^~~~~~~~~~~~~~~~
   fs/aio.c:702:4: note: Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11
                           memcpy(table->table, old->table,
                           ^
   include/linux/fortify-string.h:369:26: note: expanded from macro 'memcpy'
   #define memcpy(p, q, s)  __fortify_memcpy_chk(p, q, s,                  \
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/fortify-string.h:362:2: note: expanded from macro '__fortify_memcpy_chk'
           __underlying_##op(p, q, __fortify_size);                        \
           ^~~~~~~~~~~~~~~~~
   note: expanded from here
   include/linux/fortify-string.h:45:29: note: expanded from macro '__underlying_memcpy'
   #define __underlying_memcpy     __builtin_memcpy
                                   ^~~~~~~~~~~~~~~~
   Suppressed 46 warnings (46 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
   100 warnings generated.
   fs/io_uring.c:362:8: warning: Excessive padding in 'struct io_ring_ctx' (220 padding bytes, where 92 is optimal). 
   Optimal fields order: 
   , 
   , 
   , 
   , 
   sq_creds, 
   sq_data, 
   check_cq, 
   locked_free_list, 
   sqd_list, 
   restrictions, 
   sqo_sq_wait, 
   , 
   , 
   locked_free_nr, 
   consider reordering the fields or adding explicit padding members [clang-analyzer-optin.performance.Padding]
   struct io_ring_ctx {
   ~~~~~~~^~~~~~~~~~~~~
   fs/io_uring.c:362:8: note: Excessive padding in 'struct io_ring_ctx' (220 padding bytes, where 92 is optimal). Optimal fields order: , , , , sq_creds, sq_data, check_cq, locked_free_list, sqd_list, restrictions, sqo_sq_wait, , , locked_free_nr, consider reordering the fields or adding explicit padding members
   struct io_ring_ctx {
   ~~~~~~~^~~~~~~~~~~~~
>> fs/io_uring.c:1313:7: warning: Dereference of null pointer (loaded from variable 'locked') [clang-analyzer-core.NullDereference]
           if (!*locked) {
                ^
   fs/io_uring.c:6047:34: note: Passing value via 2nd parameter 'locked'
           ret = io_poll_check_events(req, locked);
                                           ^~~~~~
   fs/io_uring.c:6047:8: note: Calling 'io_poll_check_events'
           ret = io_poll_check_events(req, locked);
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/io_uring.c:5961:6: note: Assuming the condition is true
           if (unlikely(req->task->flags & PF_EXITING))
               ^
   include/linux/compiler.h:78:40: note: expanded from macro 'unlikely'
   # define unlikely(x)    __builtin_expect(!!(x), 0)
                                             ^~~~
   fs/io_uring.c:5961:2: note: Taking false branch
           if (unlikely(req->task->flags & PF_EXITING))
           ^
   fs/io_uring.c:5968:20: note: Assuming the condition is false
                   if (WARN_ON_ONCE(!(v & IO_POLL_REF_MASK)))
                                    ^
   include/asm-generic/bug.h:104:25: note: expanded from macro 'WARN_ON_ONCE'
           int __ret_warn_on = !!(condition);                      \
                                  ^~~~~~~~~
   fs/io_uring.c:5968:7: note: Taking false branch
                   if (WARN_ON_ONCE(!(v & IO_POLL_REF_MASK)))
                       ^
   include/asm-generic/bug.h:105:2: note: expanded from macro 'WARN_ON_ONCE'
           if (unlikely(__ret_warn_on))                            \
           ^
   fs/io_uring.c:5968:3: note: Taking false branch
                   if (WARN_ON_ONCE(!(v & IO_POLL_REF_MASK)))
                   ^
   fs/io_uring.c:5970:7: note: Assuming the condition is false
                   if (v & IO_POLL_CANCEL_FLAG)
                       ^~~~~~~~~~~~~~~~~~~~~~~
   fs/io_uring.c:5970:3: note: Taking false branch
                   if (v & IO_POLL_CANCEL_FLAG)
                   ^
   fs/io_uring.c:5973:7: note: Assuming field 'res' is 0
                   if (!req->cqe.res) {
                       ^~~~~~~~~~~~~
   fs/io_uring.c:5973:3: note: Taking true branch
                   if (!req->cqe.res) {
                   ^
   fs/io_uring.c:5975:21: note: Assuming 'locked' is null
                           unsigned flags = locked ? 0 : IO_URING_F_UNLOCKED;
                                            ^~~~~~
   fs/io_uring.c:5975:21: note: '?' condition is false
   fs/io_uring.c:5977:18: note: Calling 'io_assign_file'
                           if (unlikely(!io_assign_file(req, flags)))
                                         ^
   include/linux/compiler.h:78:42: note: expanded from macro 'unlikely'
   # define unlikely(x)    __builtin_expect(!!(x), 0)
                                               ^
   fs/io_uring.c:7324:6: note: Assuming field 'file' is non-null
           if (req->file || !io_op_defs[req->opcode].needs_file)
               ^~~~~~~~~
   fs/io_uring.c:7324:16: note: Left side of '||' is true
           if (req->file || !io_op_defs[req->opcode].needs_file)
                         ^
   fs/io_uring.c:7325:3: note: Returning without writing to 'req->cqe.res', which participates in a condition later
                   return true;
                   ^
   fs/io_uring.c:5977:18: note: Returning from 'io_assign_file'
                           if (unlikely(!io_assign_file(req, flags)))
                                         ^
   include/linux/compiler.h:78:42: note: expanded from macro 'unlikely'
   # define unlikely(x)    __builtin_expect(!!(x), 0)
                                               ^
   fs/io_uring.c:5977:4: note: Taking false branch
                           if (unlikely(!io_assign_file(req, flags)))
                           ^
   fs/io_uring.c:5983:7: note: Assuming field 'res' is not equal to 0
                   if (req->cqe.res && !(req->apoll_events & EPOLLONESHOT)) {
                       ^~~~~~~~~~~~
   fs/io_uring.c:5983:7: note: Left side of '&&' is true
   fs/io_uring.c:5983:23: note: Assuming the condition is true
                   if (req->cqe.res && !(req->apoll_events & EPOLLONESHOT)) {
                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/io_uring.c:5983:3: note: Taking true branch
                   if (req->cqe.res && !(req->apoll_events & EPOLLONESHOT)) {
                   ^
   fs/io_uring.c:5984:8: note: Assuming the condition is true
                           if (req->flags & REQ_F_APOLL_MULTISHOT) {
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/io_uring.c:5984:4: note: Taking true branch
                           if (req->flags & REQ_F_APOLL_MULTISHOT) {
                           ^
   fs/io_uring.c:5985:26: note: Passing null pointer value via 2nd parameter 'locked'
                                   io_tw_lock(req->ctx, locked);
                                                        ^~~~~~
   fs/io_uring.c:5985:5: note: Calling 'io_tw_lock'
                                   io_tw_lock(req->ctx, locked);
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/io_uring.c:1313:7: note: Dereference of null pointer (loaded from variable 'locked')
           if (!*locked) {
                ^~~~~~~
   fs/io_uring.c:1353:7: warning: Dereference of null pointer [clang-analyzer-core.NullDereference]
           if (!wq_list_empty(&ctx->submit_state.compl_reqs))
                ^

vim +/locked +1313 fs/io_uring.c

f8929630514505 Pavel Begunkov 2022-03-25  1310  
f237c30a5610d3 Pavel Begunkov 2021-08-18  1311  static inline void io_tw_lock(struct io_ring_ctx *ctx, bool *locked)
f237c30a5610d3 Pavel Begunkov 2021-08-18  1312  {
f237c30a5610d3 Pavel Begunkov 2021-08-18 @1313  	if (!*locked) {
f237c30a5610d3 Pavel Begunkov 2021-08-18  1314  		mutex_lock(&ctx->uring_lock);
f237c30a5610d3 Pavel Begunkov 2021-08-18  1315  		*locked = true;
f237c30a5610d3 Pavel Begunkov 2021-08-18  1316  	}
f237c30a5610d3 Pavel Begunkov 2021-08-18  1317  }
f237c30a5610d3 Pavel Begunkov 2021-08-18  1318  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2022-05-08  9:48 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-05-06  7:00 [PATCH v2 0/5] fast poll multishot mode Hao Xu
2022-05-06  7:00 ` [PATCH 1/5] io_uring: add IORING_ACCEPT_MULTISHOT for accept Hao Xu
2022-05-06 14:32   ` Jens Axboe
2022-05-07  4:05     ` Hao Xu
2022-05-06  7:00 ` [PATCH 2/5] io_uring: add REQ_F_APOLL_MULTISHOT for requests Hao Xu
2022-05-06  7:01 ` [PATCH 3/5] io_uring: let fast poll support multishot Hao Xu
2022-05-06 17:19   ` Pavel Begunkov
2022-05-06 22:02     ` Jens Axboe
2022-05-07  6:32       ` Hao Xu
2022-05-07  9:26       ` Pavel Begunkov
2022-05-07  7:08     ` Hao Xu
2022-05-07  9:47       ` Pavel Begunkov
2022-05-07 11:06         ` Hao Xu
2022-05-06 18:02   ` kernel test robot
2022-05-06  7:01 ` [PATCH 4/5] io_uring: add a helper for poll clean Hao Xu
2022-05-06 11:04   ` kernel test robot
2022-05-06 12:47   ` kernel test robot
2022-05-06 14:36   ` Jens Axboe
2022-05-07  6:37     ` Hao Xu
2022-05-06 16:22   ` Pavel Begunkov
2022-05-07  6:43     ` Hao Xu
2022-05-07  9:29       ` Pavel Begunkov
2022-05-06  7:01 ` [PATCH 5/5] io_uring: implement multishot mode for accept Hao Xu
2022-05-06 14:42   ` Jens Axboe
2022-05-07  9:13     ` Hao Xu
2022-05-06 20:50   ` Jens Axboe
2022-05-06 21:29     ` Jens Axboe
2022-05-06  7:36 ` [PATCH v2 0/5] fast poll multishot mode Hao Xu
2022-05-06 14:18   ` Jens Axboe
2022-05-06 16:01     ` Pavel Begunkov
2022-05-06 16:03       ` Jens Axboe
2022-05-06 22:23 ` Jens Axboe
2022-05-06 23:26   ` Jens Axboe
2022-05-07  2:33     ` Jens Axboe
2022-05-07  3:08       ` Jens Axboe
2022-05-07 16:01         ` Hao Xu
  -- strict thread matches above, loose matches on Subject: below --
2022-05-08  9:48 [PATCH 3/5] io_uring: let fast poll support multishot kernel test robot

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.