mbox series

[RFC,0/7] io_uring lseek

Message ID 20230726102603.155522-1-hao.xu@linux.dev (mailing list archive)
Headers show
Series io_uring lseek | expand

Message

Hao Xu July 26, 2023, 10:25 a.m. UTC
From: Hao Xu <howeyxu@tencent.com>

This series adds lseek for io_uring, the motivation to import this
syscall is in previous io_uring getdents patchset, we lack a way to
rewind the file cursor when it goes to the end of file. Another reason
is lseek is a common syscall, it's good for coding consistency when
users use io_uring as their main loop.

Patch 1 is code clean for iomap
Patch 2 adds IOMAP_NOWAIT logic for iomap lseek
Patch 3 adds a nowait parameter to for IOMAP_NOWAIT control
Patch 4 adds llseek_nowait() for file_operations so that specific
        filesystem can implement it for nowait lseek
Patch 5 adds llseek_nowait() implementation for xfs
Patch 6 adds a new vfs wrapper for io_uring use
Patch 7 is the main io_uring lseek implementation

Note, this series depends on the previous io_uring getdents series.

This is marked RFC since there is (at least) an issue to be discussed:
The work in this series is mainly to reslove a problem that the current
llseek() in struct file_operations doesn't have a place to deliver
nowait info, and adding an argument to it results in update for llseek
implementation of all filesystems (35 functions), so here I introduce
a new llseek_nowait() as a workaround.

For performance, it has about 20%~30% improvement on iops.
The test program is just like the one for io_uring getdents, here is the
link to it: https://github.com/HowHsu/liburing/blob/llseek/test/lseek.c
- Each test runs about 30000 async requests/sync syscalls
- Each test runs 100 times and get the average value.
- offset is randomly generated value
- the file is a 1M all zero file

[howeyxu@~]$ python3 run_lseek.py
test args:  seek mode:SEEK_SET, offset: 334772
Average of  sync :  0.012300650000000002
Average of  iouring :  0.008528009999999999
30.67%

[howeyxu@~]$ python3 run_lseek.py
test args:  seek mode:SEEK_CUR, offset: 389292
Average of  sync :  0.012736129999999995
Average of  iouring :  0.00928725
27.08%

[howeyxu@~]$ python3 run_lseek.py
test args:  seek mode:SEEK_END, offset: 281141
Average of  sync :  0.01221595
Average of  iouring :  0.008442890000000003
30.89%

[howeyxu@~]$ python3 run_lseek.py
test args:  seek mode:SEEK_DATA, offset: 931103
Average of  sync :  0.015496230000000005
Average of  iouring :  0.012341509999999998
20.36%

[howeyxu@~]$ python3 run_lseek.py
test args:  seek mode:SEEK_HOLE, offset: 430194
Average of  sync :  0.01555663000000001
Average of  iouring :  0.012064940000000003
22.45%
 

Hao Xu (7):
  iomap: merge iomap_seek_hole() and iomap_seek_data()
  xfs: add nowait support for xfs_seek_iomap_begin()
  add nowait parameter for iomap_seek()
  add llseek_nowait() for struct file_operations
  add llseek_nowait support for xfs
  add vfs_lseek_nowait()
  add lseek for io_uring

 fs/ext4/file.c                |  9 ++---
 fs/gfs2/inode.c               |  4 +--
 fs/iomap/seek.c               | 42 ++++++-----------------
 fs/read_write.c               | 18 ++++++++++
 fs/xfs/xfs_file.c             | 34 ++++++++++++++++---
 fs/xfs/xfs_iomap.c            |  4 ++-
 include/linux/fs.h            |  4 +++
 include/linux/iomap.h         |  6 ++--
 include/uapi/linux/io_uring.h |  1 +
 io_uring/fs.c                 | 63 +++++++++++++++++++++++++++++++++++
 io_uring/fs.h                 |  3 ++
 io_uring/opdef.c              |  8 +++++
 12 files changed, 145 insertions(+), 51 deletions(-)


base-commit: 4a4b046082eca8ae90b654d772fccc30e9f23f4d

Comments

Christian Brauner July 26, 2023, 1:22 p.m. UTC | #1
On Wed, Jul 26, 2023 at 06:25:56PM +0800, Hao Xu wrote:
> From: Hao Xu <howeyxu@tencent.com>
> 
> This series adds lseek for io_uring, the motivation to import this
> syscall is in previous io_uring getdents patchset, we lack a way to
> rewind the file cursor when it goes to the end of file. Another reason
> is lseek is a common syscall, it's good for coding consistency when
> users use io_uring as their main loop.

While I understand this it is a time consuming review to make sure
things work correctly. So before we get this thing going we better get
getdents correct first.

> 
> Patch 1 is code clean for iomap
> Patch 2 adds IOMAP_NOWAIT logic for iomap lseek
> Patch 3 adds a nowait parameter to for IOMAP_NOWAIT control
> Patch 4 adds llseek_nowait() for file_operations so that specific
>         filesystem can implement it for nowait lseek
> Patch 5 adds llseek_nowait() implementation for xfs
> Patch 6 adds a new vfs wrapper for io_uring use
> Patch 7 is the main io_uring lseek implementation
> 
> Note, this series depends on the previous io_uring getdents series.
> 
> This is marked RFC since there is (at least) an issue to be discussed:
> The work in this series is mainly to reslove a problem that the current
> llseek() in struct file_operations doesn't have a place to deliver
> nowait info, and adding an argument to it results in update for llseek
> implementation of all filesystems (35 functions), so here I introduce
> a new llseek_nowait() as a workaround.

My intuition would be to update all filesystems. Adding new inode
operations always starts as a temporary thing and then we live with two
different methods for the next years or possibly forever.

But it'd be good to hear what others think.
Hao Xu July 27, 2023, 12:30 p.m. UTC | #2
On 7/26/23 18:25, Hao Xu wrote:
> From: Hao Xu <howeyxu@tencent.com>
> 
> This series adds lseek for io_uring, the motivation to import this
> syscall is in previous io_uring getdents patchset, we lack a way to
> rewind the file cursor when it goes to the end of file. Another reason
> is lseek is a common syscall, it's good for coding consistency when
> users use io_uring as their main loop.
> 
> Patch 1 is code clean for iomap
> Patch 2 adds IOMAP_NOWAIT logic for iomap lseek
> Patch 3 adds a nowait parameter to for IOMAP_NOWAIT control
> Patch 4 adds llseek_nowait() for file_operations so that specific
>          filesystem can implement it for nowait lseek
> Patch 5 adds llseek_nowait() implementation for xfs
> Patch 6 adds a new vfs wrapper for io_uring use
> Patch 7 is the main io_uring lseek implementation
> 
> Note, this series depends on the previous io_uring getdents series.
> 
> This is marked RFC since there is (at least) an issue to be discussed:
> The work in this series is mainly to reslove a problem that the current
> llseek() in struct file_operations doesn't have a place to deliver
> nowait info, and adding an argument to it results in update for llseek
> implementation of all filesystems (35 functions), so here I introduce
> a new llseek_nowait() as a workaround.
> 
> For performance, it has about 20%~30% improvement on iops.
> The test program is just like the one for io_uring getdents, here is the
> link to it: https://github.com/HowHsu/liburing/blob/llseek/test/lseek.c
> - Each test runs about 30000 async requests/sync syscalls
> - Each test runs 100 times and get the average value.
> - offset is randomly generated value
> - the file is a 1M all zero file
> 
> [howeyxu@~]$ python3 run_lseek.py
> test args:  seek mode:SEEK_SET, offset: 334772
> Average of  sync :  0.012300650000000002
> Average of  iouring :  0.008528009999999999
> 30.67%
> 
> [howeyxu@~]$ python3 run_lseek.py
> test args:  seek mode:SEEK_CUR, offset: 389292
> Average of  sync :  0.012736129999999995
> Average of  iouring :  0.00928725
> 27.08%
> 
> [howeyxu@~]$ python3 run_lseek.py
> test args:  seek mode:SEEK_END, offset: 281141
> Average of  sync :  0.01221595
> Average of  iouring :  0.008442890000000003
> 30.89%
> 
> [howeyxu@~]$ python3 run_lseek.py
> test args:  seek mode:SEEK_DATA, offset: 931103
> Average of  sync :  0.015496230000000005
> Average of  iouring :  0.012341509999999998
> 20.36%
> 
> [howeyxu@~]$ python3 run_lseek.py
> test args:  seek mode:SEEK_HOLE, offset: 430194
> Average of  sync :  0.01555663000000001
> Average of  iouring :  0.012064940000000003
> 22.45%
>   
> 
> Hao Xu (7):
>    iomap: merge iomap_seek_hole() and iomap_seek_data()
>    xfs: add nowait support for xfs_seek_iomap_begin()
>    add nowait parameter for iomap_seek()
>    add llseek_nowait() for struct file_operations
>    add llseek_nowait support for xfs
>    add vfs_lseek_nowait()
>    add lseek for io_uring
> 
>   fs/ext4/file.c                |  9 ++---
>   fs/gfs2/inode.c               |  4 +--
>   fs/iomap/seek.c               | 42 ++++++-----------------
>   fs/read_write.c               | 18 ++++++++++
>   fs/xfs/xfs_file.c             | 34 ++++++++++++++++---
>   fs/xfs/xfs_iomap.c            |  4 ++-
>   include/linux/fs.h            |  4 +++
>   include/linux/iomap.h         |  6 ++--
>   include/uapi/linux/io_uring.h |  1 +
>   io_uring/fs.c                 | 63 +++++++++++++++++++++++++++++++++++
>   io_uring/fs.h                 |  3 ++
>   io_uring/opdef.c              |  8 +++++
>   12 files changed, 145 insertions(+), 51 deletions(-)
> 
> 
> base-commit: 4a4b046082eca8ae90b654d772fccc30e9f23f4d

Hi folks,
I'll leave this patchset here before the io_uring getdents is merged,
then come back and update this one.

Thanks,
Hao