[Virtio-fs] [PATCH 2/2] virtiofs: add dmap flags to differentiate write mapping from read mapping
Liu Bo
bo.liu at linux.alibaba.com
Wed May 8 18:48:06 UTC 2019
On Wed, May 08, 2019 at 11:27:04AM -0400, Vivek Goyal wrote:
> On Tue, May 07, 2019 at 01:58:11PM +0800, Liu Bo wrote:
> > There're 2 problems in dax rw path which were found by [1][2],
> >
> > a) setupmapping always sends a RW mapping message to virtiofs daemon side
> > no matter it's doing reads or writes, the end result is that guest reads
> > on a mapping will cause a write page fault on host, which is unnecessary.
> >
> > b) After a successful setupmapping, it doesn't guarantee the following
> > writes can land on host, e.g. page fault on host may fail because of
> > ENOSPC.
> >
> > This is trying to solve the problems by
> > a) marking a dmap as RO or RW to indicate it's being used for reads or
> > writes,
> > b) setting up a RO dmap for reads
> > c) setting up a RW dmap for writes
> > d) using an existing dmap for reads if it's availalbe in the interval tree
> > e) converting an existing dmap from RO to RW for writes if it's available
> > in the interval tree
> >
> > The downside of the above approach is write amplification.
>
> Another downside of using fallocate() is performance overhead. I wrote
> a problem to do small 16K file extending writes and measure total time
> with and without fallocate. Fallocate version seems to be much slower.
>
> With fallocate()
> ===============
> # ./file-extending-writes /mnt/virtio-fs/foo.txt
> 16384 extending writes took 14 secs and 647210 us
> 16384 extending writes took 11 secs and 571941 us
> 16384 extending writes took 11 secs and 981329 us
>
> With dax + direct write (FUSE_WRITE)
> ==============================
> # ./file-extending-writes /mnt/virtio-fs/foo.txt
> 16384 extending writes took 2 secs and 477642 us
> 16384 extending writes took 2 secs and 352413 us
> 16384 extending writes took 2 secs and 347223 us
>
> I ran your test script as well and that does not show much difference.
> I think part of the problem is that every write launches new xfs_io
> process. So overhead of launching process, opening fd again hides the
> fallocate overhead.
It's so weird, with the below C test, I couldn't reproduce the huge
difference of w/ or w/o fallocate.
=================================
mount -t virtio_fs atest /mnt/test/ -otag=myfs-2,rootmode=040000,user_id=0,group_id=0,dax
- w/
[root at debug010000002015 virtiofs]
$ ./a.out /mnt/test/foobar
16384 extending writes took 2 secs and 407494 us
16384 extending writes took 2 secs and 368892 us
16384 extending writes took 2 secs and 347208 us
[root at debug010000002015 virtiofs]
$ ./a.out /mnt/test/foobar
16384 extending writes took 2 secs and 306272 us
16384 extending writes took 2 secs and 364296 us
16384 extending writes took 2 secs and 354999 us
[root at debug010000002015 virtiofs]
$ ./a.out /mnt/test/foobar
16384 extending writes took 2 secs and 363470 us
16384 extending writes took 2 secs and 742043 us
16384 extending writes took 2 secs and 527137 us
- w/o (Revert "fuse, dax: Do not use dax for file extnding writes" +
Revert "virtiofsd: do fallocate for setupmapping requests with write flag")
[root at debug010000002015 virtiofs]
$ ./a.out /mnt/test/foobar
16384 extending writes took 2 secs and 331097 us
16384 extending writes took 2 secs and 298868 us
16384 extending writes took 2 secs and 337858 us
[root at debug010000002015 virtiofs]
$ ./a.out /mnt/test/foobar
16384 extending writes took 2 secs and 319989 us
16384 extending writes took 2 secs and 519414 us
16384 extending writes took 2 secs and 436929 us
[root at debug010000002015 virtiofs]
$ ./a.out /mnt/test/foobar
16384 extending writes took 2 secs and 365331 us
16384 extending writes took 2 secs and 353973 us
16384 extending writes took 2 secs and 354729 us
=================================
thanks,
-liubo
>
> Here is my C program.
>
> ===========================================================
> #include <stdio.h>
> #include <stdlib.h>
> #include <errno.h>
> #include <string.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <unistd.h>
> #include <sys/time.h>
>
> void drop_caches(void)
> {
> system("sync");
> system("echo 3 > /proc/sys/vm/drop_caches");
> }
>
> void run_test(int fd)
> {
> int nr_writes = 16 * 1024;
> struct timeval tv_start, tv_end, tv_elapsed;
> char *buf = "Hello";
> int buf_len = strlen(buf);
> ssize_t written = 0;
> int i;
>
> drop_caches();
>
> /* Extend file in a loop */
> gettimeofday(&tv_start, NULL);
> for (i = 0; i < nr_writes; i++) {
> written += write(fd, buf, buf_len);
> if (written == -1) {
> fprintf(stderr, "Failed to write %d bytes:%s,"
> " errorno=%d\n", strlen(buf), strerror(errno),
> errno);
> exit(1);
> }
> }
> gettimeofday(&tv_end, NULL);
> timersub(&tv_end, &tv_start, &tv_elapsed);
> printf("%d extending writes took %d secs and %d us\n", nr_writes, tv_elapsed.tv_sec, tv_elapsed.tv_usec);
> }
>
> int main(int argc, char *argv[])
> {
> int fd, flags = 0;
> mode_t mode = 0;
> int i, nr_runs = 3;
>
> if (argc != 2) {
> printf("Usage:%s <file-to-open>\n", argv[0]);
> exit(1);
> }
>
> fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND | O_TRUNC);
> if (fd == -1) {
> fprintf(stderr, "Failed to open file %s:%s, errorno=%d\n",
> argv[0], strerror(errno), errno);
> exit(1);
> }
>
> for(i = 0; i < nr_runs; i++)
> run_test(fd);
> close(fd);
> }
>
> ==========================================================================
More information about the Virtio-fs
mailing list