On Thu, Sep 26, 2019 at 02:39:51PM +0300, Nikolay Borisov wrote:
> Modifying the file position is done on a per-file basis. This renders
> holding the inode lock useless and currently holding it makes the
> performance of concurrent llseek's abysmal.
>
> Fix this by removing calls to inode_lock. This is correct because
> find_desired_extent already includes proper extent locking for the
> range it's going to interrogate for finding a DATA/HOLE region. The
> other two cases SEEK_END/SEEK_CUR are also safe. The latter is
> synchronized by file::f_lock spinlock. SEEK_END is not synchronized
> but atomic, but that's OK since there is not guarantee that SEEK_END
> will always be at the end of the file in the face of tail modifications. For
> more information on locking requirements see ef3d0fd27e90 ("vfs: do (nearly)
> lockless generic_file_llseek")
>
>
> This change brings ~85% performance improvement when doing a lot of
> parallel fseeks. The workload essentially does:
>
> for (d=0; d<num_seek_read; d++)
> {
> /* offset %= 16777216; */
> fseek (f, 256 * d % 16777216, SEEK_SET);
> fread (buffer, 64, 1, f);
> }
>
> Without patch:
>
> num workprocesses = 16
> num fseek/fread = 8000000
> step = 256
> fork 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
>
> real 0m41.412s
> user 0m28.777s
> sys 2m16.510s
>
> With patch:
>
> num workprocesses = 16
> num fseek/fread = 8000000
> step = 256
> fork 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
>
> real 0m11.479s
> user 0m27.629s
> sys 0m18.187s
>
> Signed-off-by: Nikolay Borisov <nborisov@xxxxxxxx>
Reviewed-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
Thanks,
Josef