virtio-fs: shared file system for virtual machines
Subsystems (4)
Vivek Goyal
maintainerv3 cover virtio-fs: shared file system for virtual machines
Hi,
Here are the V3 patches for virtio-fs filesystem. This time I have broken the patch series in two parts. This is first part which does not contain DAX support. Second patch series will contain the patches for DAX support.
I have also dropped RFC tag from first patch series as we believe its in good enough shape that it should get a consideration for inclusion upstream.
These patches apply on top of 5.3-rc5 kernel and are also available here.
https://github.com/rhvgoyal/linux/commits/vivek-5.3-aug-21-2019
Patches for V1 and V2 were posted here.
https://lwn.net/ml/linux-fsdevel/[email protected]/
http://lkml.iu.edu/hypermail/linux/kernel/1905.1/07232.html
More information about the project can be found here.
Changes from V2
===============
- Various bug fixes and performance improvements.
HOWTO
======
We have put instructions on how to use it here.
Some Performance Numbers
========================
I have basically run bunch of fio jobs to get a sense of speed of various operations. I wrote a simple wrapper script to run fio jobs 3 times and take their average and report it. These scripts are available here.
https://github.com/rhvgoyal/virtiofs-tests
I set up a directory on ramfs on host and exported that directory inside guest using virtio-9p and virtio-fs and ran tests inside guests. Ran tests with cache=none both for virtio-9p and virtio-fs so that no caching happens in guest. For virtio-fs, I ran an additional set of tests with dax enabled. Dax is not part of first patch series but I included results here because dax seems to get the maximum performance advantage and its shows the real potential of virtio-fs.
Test Setup
-----------
- A fedora 28 host with 32G RAM, 2 sockets (6 cores per socket, 2 threads per core)
- Using ramfs on host as backing store. 4 fio files of 2G each.
- Created a VM with 16 VCPUS and 8GB memory. An 8GB cache window (for dax mmap).
Test Results
------------
- Results in three configurations have been reported. 9p (cache=none), virtio-fs (cache=none) and virtio-fs (cache=none + dax).
There are other caching modes as well but to me cache=none seemed most interesting for now because it does not cache anything in guest and provides strong coherence. Other modes which provide less strong coherence and hence are faster are yet to be benchmarked.
- Three fio ioengines psync, libaio and mmap have been used.
- I/O Workload of randread, radwrite, seqread and seqwrite have been run.
- Each file size is 2G. Block size 4K. iodepth=16
- "multi" means same operation was done with 4 jobs and each job is operating on a file of size 2G.
- Some results are "0 (KiB/s)". That means that particular operation is not supported in that configuration.
NAME I/O Operation BW(Read/Write)
9p-cache-none seqread-psync 27(MiB/s) virtiofs-cache-none seqread-psync 35(MiB/s) virtiofs-dax-cache-none seqread-psync 245(MiB/s)
9p-cache-none seqread-psync-multi 117(MiB/s) virtiofs-cache-none seqread-psync-multi 162(MiB/s) virtiofs-dax-cache-none seqread-psync-multi 894(MiB/s)
9p-cache-none seqread-mmap 24(MiB/s) virtiofs-cache-none seqread-mmap 0(KiB/s) virtiofs-dax-cache-none seqread-mmap 168(MiB/s)
9p-cache-none seqread-mmap-multi 115(MiB/s) virtiofs-cache-none seqread-mmap-multi 0(KiB/s) virtiofs-dax-cache-none seqread-mmap-multi 614(MiB/s)
9p-cache-none seqread-libaio 26(MiB/s) virtiofs-cache-none seqread-libaio 139(MiB/s) virtiofs-dax-cache-none seqread-libaio 160(MiB/s)
9p-cache-none seqread-libaio-multi 129(MiB/s) virtiofs-cache-none seqread-libaio-multi 142(MiB/s) virtiofs-dax-cache-none seqread-libaio-multi 577(MiB/s)
9p-cache-none randread-psync 29(MiB/s) virtiofs-cache-none randread-psync 34(MiB/s) virtiofs-dax-cache-none randread-psync 256(MiB/s)
9p-cache-none randread-psync-multi 139(MiB/s) virtiofs-cache-none randread-psync-multi 153(MiB/s) virtiofs-dax-cache-none randread-psync-multi 245(MiB/s)
9p-cache-none randread-mmap 22(MiB/s) virtiofs-cache-none randread-mmap 0(KiB/s) virtiofs-dax-cache-none randread-mmap 162(MiB/s)
9p-cache-none randread-mmap-multi 111(MiB/s) virtiofs-cache-none randread-mmap-multi 0(KiB/s) virtiofs-dax-cache-none randread-mmap-multi 215(MiB/s)
9p-cache-none randread-libaio 26(MiB/s) virtiofs-cache-none randread-libaio 135(MiB/s) virtiofs-dax-cache-none randread-libaio 157(MiB/s)
9p-cache-none randread-libaio-multi 133(MiB/s) virtiofs-cache-none randread-libaio-multi 245(MiB/s) virtiofs-dax-cache-none randread-libaio-multi 163(MiB/s)
9p-cache-none seqwrite-psync 28(MiB/s) virtiofs-cache-none seqwrite-psync 34(MiB/s) virtiofs-dax-cache-none seqwrite-psync 203(MiB/s)
9p-cache-none seqwrite-psync-multi 128(MiB/s) virtiofs-cache-none seqwrite-psync-multi 155(MiB/s) virtiofs-dax-cache-none seqwrite-psync-multi 717(MiB/s)
9p-cache-none seqwrite-mmap 0(KiB/s) virtiofs-cache-none seqwrite-mmap 0(KiB/s) virtiofs-dax-cache-none seqwrite-mmap 165(MiB/s)
9p-cache-none seqwrite-mmap-multi 0(KiB/s) virtiofs-cache-none seqwrite-mmap-multi 0(KiB/s) virtiofs-dax-cache-none seqwrite-mmap-multi 511(MiB/s)
9p-cache-none seqwrite-libaio 27(MiB/s) virtiofs-cache-none seqwrite-libaio 128(MiB/s) virtiofs-dax-cache-none seqwrite-libaio 141(MiB/s)
9p-cache-none seqwrite-libaio-multi 119(MiB/s) virtiofs-cache-none seqwrite-libaio-multi 242(MiB/s) virtiofs-dax-cache-none seqwrite-libaio-multi 505(MiB/s)
9p-cache-none randwrite-psync 27(MiB/s) virtiofs-cache-none randwrite-psync 34(MiB/s) virtiofs-dax-cache-none randwrite-psync 189(MiB/s)
9p-cache-none randwrite-psync-multi 137(MiB/s) virtiofs-cache-none randwrite-psync-multi 150(MiB/s) virtiofs-dax-cache-none randwrite-psync-multi 233(MiB/s)
9p-cache-none randwrite-mmap 0(KiB/s) virtiofs-cache-none randwrite-mmap 0(KiB/s) virtiofs-dax-cache-none randwrite-mmap 120(MiB/s)
9p-cache-none randwrite-mmap-multi 0(KiB/s) virtiofs-cache-none randwrite-mmap-multi 0(KiB/s) virtiofs-dax-cache-none randwrite-mmap-multi 200(MiB/s)
9p-cache-none randwrite-libaio 25(MiB/s) virtiofs-cache-none randwrite-libaio 124(MiB/s) virtiofs-dax-cache-none randwrite-libaio 131(MiB/s)
9p-cache-none randwrite-libaio-multi 125(MiB/s) virtiofs-cache-none randwrite-libaio-multi 241(MiB/s) virtiofs-dax-cache-none randwrite-libaio-multi 163(MiB/s)
Conclusions
===========
- In general virtio-fs seems faster than virtio-9p. Using dax makes it really interesting.
Note:
Right now dax window is 8G and max fio file size is 8G as well (4 files of 2G each). That means everything fits into dax window and no reclaim is needed. Dax window reclaim logic is slower and if file size is bigger than dax window size, performance slows down.
Description from previous postings
==================================
Design Overview
===============
With the goal of designing something with better performance and local file system semantics, a bunch of ideas were proposed.
- Use fuse protocol (instead of 9p) for communication between guest and host. Guest kernel will be fuse client and a fuse server will run on host to serve the requests.
- For data access inside guest, mmap portion of file in QEMU address space and guest accesses this memory using dax. That way guest page cache is bypassed and there is only one copy of data (on host). This will also enable mmap(MAP_SHARED) between guests.
- For metadata coherency, there is a shared memory region which contains version number associated with metadata and any guest changing metadata updates version number and other guests refresh metadata on next access. This is yet to be implemented.
How virtio-fs differs from existing approaches
==============================================
The unique idea behind virtio-fs is to take advantage of the co-location of the virtual machine and hypervisor to avoid communication (vmexits).
DAX allows file contents to be accessed without communication with the hypervisor. The shared memory region for metadata avoids communication in the common case where metadata is unchanged.
By replacing expensive communication with cheaper shared memory accesses, we expect to achieve better performance than approaches based on network file system protocols. In addition, this also makes it easier to achieve local file system semantics (coherency).
These techniques are not applicable to network file system protocols since the communications channel is bypassed by taking advantage of shared memory on a local machine. This is why we decided to build virtio-fs rather than focus on 9P or NFS.
Caching Modes
=============
Like virtio-9p, different caching modes are supported which determine the coherency level as well. The “cache=FOO” and “writeback” options control the level of coherence between the guest and host filesystems.
- cache=none
metadata, data and pathname lookup are not cached in guest. They are always fetched from host and any changes are immediately pushed to host.
- cache=always
metadata, data and pathname lookup are cached in guest and never expire.
- cache=auto
metadata and pathname lookup cache expires after a configured amount of time (default is 1 second). Data is cached while the file is open (close to open consistency).
- writeback/no_writeback
These options control the writeback strategy. If writeback is disabled, then normal writes will immediately be synchronized with the host fs. If writeback is enabled, then writes may be cached in the guest until the file is closed or an fsync(2) performed. This option has no effect on mmap-ed writes or writes going through the DAX mechanism.
Thanks
Vivek
Miklos Szeredi (2):
fuse: delete dentry if timeout is zero
fuse: Use default_file_splice_read for direct IO
Stefan Hajnoczi (6):
fuse: export fuse_end_request()
fuse: export fuse_len_args()
fuse: export fuse_get_unique()
fuse: extract fuse_fill_super_common()
fuse: add fuse_iqueue_ops callbacks
virtio_fs: add skeleton virtio_fs.ko module
Vivek Goyal (5):
fuse: Export fuse_send_init_request()
Export fuse_dequeue_forget() function
fuse: Separate fuse device allocation and installation in fuse_conn
virtio-fs: Do not provide abort interface in fusectl init/do_mounts.c: add virtio_fs root fs support
fs/fuse/Kconfig | 11 + fs/fuse/Makefile | 1 + fs/fuse/control.c | 4 +- fs/fuse/cuse.c | 4 +- fs/fuse/dev.c | 89 ++- fs/fuse/dir.c | 26 +- fs/fuse/file.c | 15 +- fs/fuse/fuse_i.h | 120 +++- fs/fuse/inode.c | 203 +++--- fs/fuse/virtio_fs.c | 1061 +++++++++++++++++++++++++++++++ fs/splice.c | 3 +- include/linux/fs.h | 2 + include/uapi/linux/virtio_fs.h | 41 ++ include/uapi/linux/virtio_ids.h | 1 + init/do_mounts.c | 10 + 15 files changed, 1462 insertions(+), 129 deletions(-) create mode 100644 fs/fuse/virtio_fs.c create mode 100644 include/uapi/linux/virtio_fs.h
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 1/13 fuse: delete dentry if timeout is zero
From: Miklos Szeredi <[email protected]>
Don't hold onto dentry in lru list if need to re-lookup it anyway at next access.
More advanced version of this patch would periodically flush out dentries from the lru which have gone stale.
--- fs/fuse/dir.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-)
fs/fuse/dir.c +23 -3
@@ -29,12 +29,26 @@ union fuse_dentry {struct rcu_head rcu; }; -static inline void fuse_dentry_settime (struct dentry *entry,u64 time) +static void fuse_dentry_settime (struct dentry *dentry,u64 time) { - ((union fuse_dentry *) entry->d_fsdata)->time = time; +/* +* Mess with DCACHE_OP_DELETE because dput() will be faster without it. +* Don't care about races, either way it's just an optimization +*/ +if ((time && (dentry->d_flags &DCACHE_OP_DELETE )) || + (!time && !(dentry->d_flags &DCACHE_OP_DELETE ))) { +spin_lock (&dentry->d_lock); +if (time) + dentry->d_flags &= ~DCACHE_OP_DELETE ; +else + dentry->d_flags |=DCACHE_OP_DELETE ; +spin_unlock (&dentry->d_lock); + } + + ((union fuse_dentry *) dentry->d_fsdata)->time = time; } -static inline u64 fuse_dentry_time (struct dentry *entry) +static inline u64 fuse_dentry_time (const struct dentry *entry) {return ((union fuse_dentry *) entry->d_fsdata)->time; }
@@ -255,8 +269,14 @@ static void fuse_dentry_release(struct dentry *dentry)kfree_rcu (fd, rcu); } +static int fuse_dentry_delete (const struct dentry *dentry) +{ +return time_before64 (fuse_dentry_time (dentry),get_jiffies_64 ()); +} +const struct dentry_operations fuse_dentry_operations = { .d_revalidate = fuse_dentry_revalidate, + .d_delete = fuse_dentry_delete, .d_init = fuse_dentry_init, .d_release = fuse_dentry_release, };
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 2/13 fuse: Use default_file_splice_read for direct IO
In reply to Vivek GoyalFrom: Miklos Szeredi <[email protected]>
--- fs/fuse/file.c | 15 ++++++++++++++- fs/splice.c | 3 ++- include/linux/fs.h | 2 ++ 3 files changed, 18 insertions(+), 2 deletions(-)
fs/fuse/file.c +14 -1
@@ -2172,6 +2172,19 @@ static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)return 0 ; } +static ssize_t fuse_file_splice_read (struct file *in,loff_t *ppos, +struct pipe_inode_info *pipe,size_t len, +unsigned int flags) +{ +struct fuse_file *ff = in->private_data; + +if (ff->open_flags &FOPEN_DIRECT_IO ) +return default_file_splice_read (in, ppos, pipe, len, flags); +else +return generic_file_splice_read (in, ppos, pipe, len, flags); + +} +static int convert_fuse_file_lock (struct fuse_conn *fc,const struct fuse_file_lock *ffl,struct file_lock *fl)
@@ -3228,7 +3241,7 @@ static const struct file_operations fuse_file_operations = { .fsync = fuse_fsync, .lock = fuse_file_lock, .flock = fuse_file_flock, - .splice_read = generic_file_splice_read, + .splice_read = fuse_file_splice_read, .splice_write = iter_file_splice_write, .unlocked_ioctl = fuse_file_ioctl, .compat_ioctl = fuse_file_compat_ioctl,
fs/splice.c +2 -1
@@ -362,7 +362,7 @@ static ssize_t kernel_readv(struct file *file, const struct kvec *vec,return res; } -static ssize_t default_file_splice_read (struct file *in,loff_t *ppos, +ssize_t default_file_splice_read (struct file *in,loff_t *ppos,struct pipe_inode_info *pipe,size_t len,unsigned int flags) {
@@ -426,6 +426,7 @@ static ssize_t default_file_splice_read(struct file *in, loff_t *ppos,iov_iter_advance (&to, copied);/* truncates and discards */ return res; } +EXPORT_SYMBOL (default_file_splice_read);/* * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos'
include/linux/fs.h +2 -0
@@ -3062,6 +3062,8 @@ extern void block_sync_page(struct page *page);/* fs/splice.c */ extern ssize_t generic_file_splice_read (struct file *,loff_t *,struct pipe_inode_info *,size_t ,unsigned int ); +extern ssize_t default_file_splice_read (struct file *,loff_t *, +struct pipe_inode_info *,size_t ,unsigned int );extern ssize_t iter_file_splice_write (struct pipe_inode_info *,struct file *,loff_t *,size_t ,unsigned int ); extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe,
Signature · 1 line
2.20.1
Miklos Szeredi
maintainerRe: [PATCH 02/13] fuse: Use default_file_splice_read for direct IO
Quoted 2 lines · Vivek Goyal
From: Miklos Szeredi <[email protected]>
Nice patch, except I have no idea why I did this. Splice with FOPEN_DIRECT_IO seems to work fine without it.
Anyway, I'll just drop this, unless someone has an idea why it is actually needed.
Thanks,
Miklos
Vivek Goyal
maintainerRe: [PATCH 02/13] fuse: Use default_file_splice_read for direct IO
Quoted 6 lines · Miklos Szeredi
Quoted 2 lines · Vivek Goyal
From: Miklos Szeredi <[email protected]>
Nice patch, except I have no idea why I did this. Splice with
FOPEN_DIRECT_IOseems to work fine without it.
I don't know either. I took it because it was there in one of the branches you were doing development on.
Quoted 3 lines
Anyway, I'll just drop this, unless someone has an idea why it is actually needed.
Sure, drop this patch. If need be, we can dig it up later.
Thanks
Vivek
Vivek Goyal
maintainerPATCH v3 3/13 fuse: export fuse_end_request()
In reply to Vivek GoyalFrom: Stefan Hajnoczi <[email protected]>
virtio-fs will need to complete requests from outside fs/fuse/dev.c. Make the symbol visible.
--- fs/fuse/dev.c | 19 ++++++++++--------- fs/fuse/fuse_i.h | 5 +++++ 2 files changed, 15 insertions(+), 9 deletions(-)
fs/fuse/dev.c +10 -9
@@ -427,7 +427,7 @@ static void flush_bg_queue(struct fuse_conn *fc)* the 'end' callback is called if given, else the reference to the * request is released */ -static void request_end (struct fuse_conn *fc,struct fuse_req *req) +void fuse_request_end (struct fuse_conn *fc,struct fuse_req *req) {struct fuse_iqueue *fiq = &fc->iq;
@@ -480,6 +480,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) put_request:fuse_put_request (fc, req); } +EXPORT_SYMBOL_GPL (fuse_request_end);static int queue_interrupt (struct fuse_iqueue *fiq,struct fuse_req *req) {
@@ -567,12 +568,12 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) req->in.h.unique =fuse_get_unique (fiq);queue_request (fiq, req);/* acquire extra reference, since request is still needed -after request_end() */ +after fuse_request_end() */ __fuse_get_request (req);spin_unlock (&fiq->waitq.lock);request_wait_answer (fc, req); -/* Pairs with smp_wmb() in request_end() */ +/* Pairs with smp_wmb() in fuse_request_end() */ smp_rmb (); } }
@@ -1302,7 +1303,7 @@ __releases(fiq->waitq.lock)* the pending list and copies request data to userspace buffer. If * no reply is needed (FORGET) or request has been aborted or there * was an error during the copying then it's finished by calling -* request_end(). Otherwise add it to the processing list, and set +* fuse_request_end(). Otherwise add it to the processing list, and set * the 'sent' flag. */ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
@@ -1362,7 +1363,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,/* SETXATTR is special, since it may contain too large data */ if (in->h.opcode ==FUSE_SETXATTR ) req->out.h.error = -E2BIG ; -request_end (fc, req); +fuse_request_end (fc, req); goto restart; }spin_lock (&fpq->lock);
@@ -1405,7 +1406,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,if (!test_bit (FR_PRIVATE , &req->flags))list_del_init (&req->list);spin_unlock (&fpq->lock); -request_end (fc, req); +fuse_request_end (fc, req);return err; err_unlock:
@@ -1913,7 +1914,7 @@ static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,* the write buffer. The request is then searched on the processing * list by the unique ID found in the header. If found, then remove * it from the list and copy the rest of the buffer to the request. -* The request is finished by calling request_end() +* The request is finished by calling fuse_request_end(). */ static ssize_t fuse_dev_do_write (struct fuse_dev *fud,struct fuse_copy_state *cs,size_t nbytes)
@@ -2000,7 +2001,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,list_del_init (&req->list);spin_unlock (&fpq->lock); -request_end (fc, req); +fuse_request_end (fc, req); out:return err ? err : nbytes;
@@ -2140,7 +2141,7 @@ static void end_requests(struct fuse_conn *fc, struct list_head *head) req->out.h.error = -ECONNABORTED ;clear_bit (FR_SENT , &req->flags);list_del_init (&req->list); -request_end (fc, req); +fuse_request_end (fc, req); } }
fs/fuse/fuse_i.h +5 -0
@@ -956,6 +956,11 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args);void fuse_request_send_background (struct fuse_conn *fc,struct fuse_req *req);bool fuse_request_queue_background (struct fuse_conn *fc,struct fuse_req *req); +/** +* End a finished request +*/ +void fuse_request_end (struct fuse_conn *fc,struct fuse_req *req); +/* Abort all requests */ void fuse_abort_conn (struct fuse_conn *fc);void fuse_wait_aborted (struct fuse_conn *fc);
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 4/13 fuse: export fuse_len_args()
In reply to Vivek GoyalFrom: Stefan Hajnoczi <[email protected]>
virtio-fs will need to query the length of fuse_arg lists. Make the symbol visible.
--- fs/fuse/dev.c | 7 ++++--- fs/fuse/fuse_i.h | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-)
fs/fuse/dev.c +4 -3
@@ -350,7 +350,7 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) }EXPORT_SYMBOL_GPL (fuse_put_request); -static unsigned len_args (unsigned numargs,struct fuse_arg *args) +unsigned fuse_len_args (unsigned numargs,struct fuse_arg *args) {unsigned nbytes =0 ;unsigned i;
@@ -360,6 +360,7 @@ static unsigned len_args(unsigned numargs, struct fuse_arg *args)return nbytes; } +EXPORT_SYMBOL_GPL (fuse_len_args);static u64 fuse_get_unique (struct fuse_iqueue *fiq) {
@@ -375,7 +376,7 @@ static unsigned int fuse_req_hash(u64 unique)static void queue_request (struct fuse_iqueue *fiq,struct fuse_req *req) { req->in.h.len =sizeof (struct fuse_in_header ) + -len_args (req->in.numargs, (struct fuse_arg *) req->in.args); +fuse_len_args (req->in.numargs, (struct fuse_arg *) req->in.args);list_add_tail (&req->list, &fiq->pending);wake_up_locked (&fiq->waitq);kill_fasync (&fiq->fasync,SIGIO ,POLL_IN );
@@ -1894,7 +1895,7 @@ static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,if (out->h.error)return nbytes != reqsize ? -EINVAL :0 ; - reqsize +=len_args (out->numargs, out->args); + reqsize +=fuse_len_args (out->numargs, out->args);if (reqsize < nbytes || (reqsize > nbytes && !out->argvar))return -EINVAL ;
fs/fuse/fuse_i.h +5 -0
@@ -1098,4 +1098,9 @@ int fuse_set_acl(struct inode *inode, struct posix_acl *acl, int type);/* readdir.c */ int fuse_readdir (struct file *file,struct dir_context *ctx); +/** +* Return the number of bytes in an arguments list +*/ +unsigned fuse_len_args (unsigned numargs,struct fuse_arg *args); +#endif /* _FS_FUSE_I_H */
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 5/13 fuse: Export fuse_send_init_request()
In reply to Vivek GoyalThis will be used by virtio-fs to send init request to fuse server after initialization of virt queues.
--- fs/fuse/dev.c | 1 + fs/fuse/fuse_i.h | 1 + fs/fuse/inode.c | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-)
fs/fuse/dev.c +1 -0
@@ -139,6 +139,7 @@ void fuse_request_free(struct fuse_req *req)fuse_req_pages_free (req);kmem_cache_free (fuse_req_cachep, req); } +EXPORT_SYMBOL_GPL (fuse_request_free);void __fuse_get_request (struct fuse_req *req) {
fs/fuse/fuse_i.h +1 -0
@@ -994,6 +994,7 @@ void fuse_conn_put(struct fuse_conn *fc);struct fuse_dev *fuse_dev_alloc (struct fuse_conn *fc);void fuse_dev_free (struct fuse_dev *fud); +void fuse_send_init (struct fuse_conn *fc,struct fuse_req *req);/** * Add connection to control filesystem
fs/fuse/inode.c +2 -1
@@ -955,7 +955,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)wake_up_all (&fc->blocked_waitq); } -static void fuse_send_init (struct fuse_conn *fc,struct fuse_req *req) +void fuse_send_init (struct fuse_conn *fc,struct fuse_req *req) {struct fuse_init_in *arg = &req->misc.init_in;
@@ -985,6 +985,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) req->end = process_init_reply;fuse_request_send_background (fc, req); } +EXPORT_SYMBOL_GPL (fuse_send_init);static void fuse_free_conn (struct fuse_conn *fc) {
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 6/13 fuse: export fuse_get_unique()
In reply to Vivek GoyalFrom: Stefan Hajnoczi <[email protected]>
virtio-fs will need unique IDs for FORGET requests from outside fs/fuse/dev.c. Make the symbol visible.
--- fs/fuse/dev.c | 3 ++- fs/fuse/fuse_i.h | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-)
fs/fuse/dev.c +2 -1
@@ -363,11 +363,12 @@ unsigned fuse_len_args(unsigned numargs, struct fuse_arg *args) }EXPORT_SYMBOL_GPL (fuse_len_args); -static u64 fuse_get_unique (struct fuse_iqueue *fiq) +u64 fuse_get_unique (struct fuse_iqueue *fiq) { fiq->reqctr +=FUSE_REQ_ID_STEP ;return fiq->reqctr; } +EXPORT_SYMBOL_GPL (fuse_get_unique);static unsigned int fuse_req_hash (u64 unique) {
fs/fuse/fuse_i.h +5 -0
@@ -1104,4 +1104,9 @@ int fuse_readdir(struct file *file, struct dir_context *ctx);*/ unsigned fuse_len_args (unsigned numargs,struct fuse_arg *args); +/** +* Get the next unique ID for a request +*/ +u64 fuse_get_unique (struct fuse_iqueue *fiq); +#endif /* _FS_FUSE_I_H */
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 7/13 Export fuse_dequeue_forget() function
In reply to Vivek GoyalFile systems like virtio-fs need to do not have to play directly with forget list data structures. There is a helper function use that instead.
Rename dequeue_forget() to fuse_dequeue_forget() and export it so that stacked filesystems can use it.
--- fs/fuse/dev.c | 9 +++++---- fs/fuse/fuse_i.h | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-)
fs/fuse/dev.c +5 -4
@@ -1185,7 +1185,7 @@ __releases(fiq->waitq.lock)return err ? err : reqsize; } -static struct fuse_forget_link *dequeue_forget (struct fuse_iqueue *fiq, +struct fuse_forget_link *fuse_dequeue_forget (struct fuse_iqueue *fiq,unsigned max,unsigned *countp) {
@@ -1206,6 +1206,7 @@ static struct fuse_forget_link *dequeue_forget(struct fuse_iqueue *fiq,return head; } +EXPORT_SYMBOL (fuse_dequeue_forget); static int fuse_read_single_forget(struct fuse_iqueue *fiq, struct fuse_copy_state *cs,
@@ -1213,7 +1214,7 @@ static int fuse_read_single_forget(struct fuse_iqueue *fiq, __releases(fiq->waitq.lock) {int err; -struct fuse_forget_link *forget =dequeue_forget (fiq,1 ,NULL ); +struct fuse_forget_link *forget =fuse_dequeue_forget (fiq,1 ,NULL );struct fuse_forget_in arg = { .nlookup = forget->forget_one.nlookup, };
@@ -1261,7 +1262,7 @@ __releases(fiq->waitq.lock) } max_forgets = (nbytes - ih.len) /sizeof (struct fuse_forget_one ); - head =dequeue_forget (fiq, max_forgets, &count); + head =fuse_dequeue_forget (fiq, max_forgets, &count);spin_unlock (&fiq->waitq.lock); arg.count = count;
@@ -2231,7 +2232,7 @@ void fuse_abort_conn(struct fuse_conn *fc)clear_bit (FR_PENDING , &req->flags);list_splice_tail_init (&fiq->pending, &to_end);while (forget_pending (fiq)) -kfree (dequeue_forget (fiq,1 ,NULL )); +kfree (fuse_dequeue_forget (fiq,1 ,NULL ));wake_up_all_locked (&fiq->waitq);spin_unlock (&fiq->waitq.lock);kill_fasync (&fiq->fasync,SIGIO ,POLL_IN );
fs/fuse/fuse_i.h +3 -0
@@ -820,6 +820,9 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,struct fuse_forget_link *fuse_alloc_forget (void ); +struct fuse_forget_link *fuse_dequeue_forget (struct fuse_iqueue *fiq, +unsigned max,unsigned *countp); +/* Used by READDIRPLUS */ void fuse_force_forget (struct file *file,u64 nodeid);
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 8/13 fuse: extract fuse_fill_super_common()
In reply to Vivek GoyalFrom: Stefan Hajnoczi <[email protected]>
fuse_fill_super() includes code to process the fd= option and link the struct fuse_dev to the fd's struct file. In virtio-fs there is no file descriptor because /dev/fuse is not used.
This patch extracts fuse_fill_super_common() so that both classic fuse and virtio-fs can share the code to initialize a mount.
parse_fuse_opt() is also extracted so that the fuse_fill_super_common() caller has access to the mount options. This allows classic fuse to handle the fd= option outside fuse_fill_super_common().
--- fs/fuse/fuse_i.h | 33 ++++++++++++ fs/fuse/inode.c | 137 ++++++++++++++++++++++++----------------------- 2 files changed, 103 insertions(+), 67 deletions(-)
fs/fuse/fuse_i.h +33 -0
@@ -60,6 +60,25 @@ extern struct mutex fuse_mutex;extern unsigned max_user_bgreq;extern unsigned max_user_congthresh; +/** Mount options */ +struct fuse_mount_data { +int fd; +unsigned rootmode; +kuid_t user_id; +kgid_t group_id; +unsigned fd_present:1 ; +unsigned rootmode_present:1 ; +unsigned user_id_present:1 ; +unsigned group_id_present:1 ; +unsigned default_permissions:1 ; +unsigned allow_other:1 ; +unsigned max_read; +unsigned blksize; + +/* fuse_dev pointer to fill in, should contain NULL on entry */ +void **fudptr; +}; +/* One forget request */ struct fuse_forget_link {struct fuse_forget_one forget_one;
@@ -999,6 +1018,20 @@ struct fuse_dev *fuse_dev_alloc(struct fuse_conn *fc);void fuse_dev_free (struct fuse_dev *fud);void fuse_send_init (struct fuse_conn *fc,struct fuse_req *req); +/** +* Parse a mount options string +*/ +int parse_fuse_opt (char *opt,struct fuse_mount_data *d,int is_bdev, +struct user_namespace *user_ns); + +/** +* Fill in superblock and initialize fuse connection +* @sb: partially-initialized superblock to fill in +* @mount_data: mount parameters +*/ +int fuse_fill_super_common (struct super_block *sb, +struct fuse_mount_data *mount_data); +/** * Add connection to control filesystem */
fs/fuse/inode.c +70 -67
235 lines not on this page · raw message
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 9/13 fuse: add fuse_iqueue_ops callbacks
In reply to Vivek GoyalFrom: Stefan Hajnoczi <[email protected]>
The /dev/fuse device uses fiq->waitq and fasync to signal that requests are available. These mechanisms do not apply to virtio-fs. This patch introduces callbacks so alternative behavior can be used.
Note that queue_interrupt() changes along these lines:
spin_lock(&fiq->waitq.lock);
wake_up_locked(&fiq->waitq);
+ kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
spin_unlock(&fiq->waitq.lock);
- kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
Since queue_request() and queue_forget() also call kill_fasync() inside the spinlock this should be safe.
--- fs/fuse/cuse.c | 2 +- fs/fuse/dev.c | 50 ++++++++++++++++++++++++++++++++---------------- fs/fuse/fuse_i.h | 48 +++++++++++++++++++++++++++++++++++++++++++++- fs/fuse/inode.c | 16 ++++++++++++---- 4 files changed, 94 insertions(+), 22 deletions(-)
fs/fuse/cuse.c +1 -1
@@ -504,7 +504,7 @@ static int cuse_channel_open(struct inode *inode, struct file *file)* Limit the cuse channel to requests that can * be represented in file->f_cred->user_ns. */ -fuse_conn_init (&cc->fc, file->f_cred->user_ns); +fuse_conn_init (&cc->fc, file->f_cred->user_ns, &fuse_dev_fiq_ops,NULL ); fud =fuse_dev_alloc (&cc->fc);if (!fud) {
fs/fuse/dev.c +34 -16
98 lines not on this page · raw message
fs/fuse/fuse_i.h +47 -1
72 lines not on this page · raw message
fs/fuse/inode.c +12 -4
@@ -565,7 +565,9 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)return 0 ; } -static void fuse_iqueue_init (struct fuse_iqueue *fiq) +static void fuse_iqueue_init (struct fuse_iqueue *fiq, +const struct fuse_iqueue_ops *ops, +void *priv) {memset (fiq,0 ,sizeof (struct fuse_iqueue ));init_waitqueue_head (&fiq->waitq);
@@ -573,6 +575,8 @@ static void fuse_iqueue_init(struct fuse_iqueue *fiq)INIT_LIST_HEAD (&fiq->interrupts); fiq->forget_list_tail = &fiq->forget_list_head; fiq->connected =1 ; + fiq->ops = ops; + fiq->priv = priv; }static void fuse_pqueue_init (struct fuse_pqueue *fpq)
@@ -586,7 +590,8 @@ static void fuse_pqueue_init(struct fuse_pqueue *fpq) fpq->connected =1 ; } -void fuse_conn_init (struct fuse_conn *fc,struct user_namespace *user_ns) +void fuse_conn_init (struct fuse_conn *fc,struct user_namespace *user_ns, +const struct fuse_iqueue_ops *fiq_ops,void *fiq_priv) {memset (fc,0 ,sizeof (*fc));spin_lock_init (&fc->lock);
@@ -596,7 +601,7 @@ void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns)atomic_set (&fc->dev_count,1 );init_waitqueue_head (&fc->blocked_waitq);init_waitqueue_head (&fc->reserved_req_waitq); -fuse_iqueue_init (&fc->iq); +fuse_iqueue_init (&fc->iq, fiq_ops, fiq_priv);INIT_LIST_HEAD (&fc->bg_queue);INIT_LIST_HEAD (&fc->entry);INIT_LIST_HEAD (&fc->devices);
@@ -1110,7 +1115,8 @@ int fuse_fill_super_common(struct super_block *sb,if (!fc) goto err; -fuse_conn_init (fc, sb->s_user_ns); +fuse_conn_init (fc, sb->s_user_ns, mount_data->fiq_ops, + mount_data->fiq_priv); fc->release = fuse_free_conn; fud =fuse_dev_alloc (fc);
@@ -1212,6 +1218,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) goto err_fput;__set_bit (FR_BACKGROUND , &init_req->flags); + d.fiq_ops = &fuse_dev_fiq_ops; + d.fiq_priv =NULL ; d.fudptr = &file->private_data; err =fuse_fill_super_common (sb, &d);if (err <0 )
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 10/13 fuse: Separate fuse device allocation and installation in fuse_conn
In reply to Vivek GoyalAs of now fuse_dev_alloc() both allocates a fuse device and installs it in fuse_conn list. fuse_dev_alloc() can fail if fuse_device allocation fails.
virtio-fs needs to initialize multiple fuse devices (one per virtio queue). It initializes one fuse device as part of call to fuse_fill_super_common() and rest of the devices are allocated and installed after that.
But, we can't affort to fail after calling fuse_fill_super_common() as we don't have a way to undo all the actions done by fuse_fill_super_common(). So to avoid failures after the call to fuse_fill_super_common(), pre-allocate all fuse devices early and install them into fuse connection later.
This patch provides two separate helpers for fuse device allocation and fuse device installation in fuse_conn.
--- fs/fuse/cuse.c | 2 +- fs/fuse/dev.c | 2 +- fs/fuse/fuse_i.h | 4 +++- fs/fuse/inode.c | 25 ++++++++++++++++++++----- 4 files changed, 25 insertions(+), 8 deletions(-)
fs/fuse/cuse.c +1 -1
@@ -506,7 +506,7 @@ static int cuse_channel_open(struct inode *inode, struct file *file)*/ fuse_conn_init (&cc->fc, file->f_cred->user_ns, &fuse_dev_fiq_ops,NULL ); - fud =fuse_dev_alloc (&cc->fc); + fud =fuse_dev_alloc_install (&cc->fc);if (!fud) {kfree (cc);return -ENOMEM ;
fs/fuse/dev.c +1 -1
@@ -2319,7 +2319,7 @@ static int fuse_device_clone(struct fuse_conn *fc, struct file *new)if (new->private_data)return -EINVAL ; - fud =fuse_dev_alloc (fc); + fud =fuse_dev_alloc_install (fc);if (!fud)return -ENOMEM ;
fs/fuse/fuse_i.h +3 -1
@@ -1060,7 +1060,9 @@ void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns,*/ void fuse_conn_put (struct fuse_conn *fc); -struct fuse_dev *fuse_dev_alloc (struct fuse_conn *fc); +struct fuse_dev *fuse_dev_alloc_install (struct fuse_conn *fc); +struct fuse_dev *fuse_dev_alloc (void ); +void fuse_dev_install (struct fuse_dev *fud,struct fuse_conn *fc);void fuse_dev_free (struct fuse_dev *fud);void fuse_send_init (struct fuse_conn *fc,struct fuse_req *req);
fs/fuse/inode.c +20 -5
@@ -1024,8 +1024,7 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)return 0 ; } -struct fuse_dev *fuse_dev_alloc (struct fuse_conn *fc) -{ +struct fuse_dev *fuse_dev_alloc (void ) {struct fuse_dev *fud;struct list_head *pq;
@@ -1040,16 +1039,32 @@ struct fuse_dev *fuse_dev_alloc(struct fuse_conn *fc) } fud->pq.processing = pq; - fud->fc =fuse_conn_get (fc);fuse_pqueue_init (&fud->pq); +return fud; +} +EXPORT_SYMBOL_GPL (fuse_dev_alloc); + +void fuse_dev_install (struct fuse_dev *fud,struct fuse_conn *fc) { + fud->fc =fuse_conn_get (fc);spin_lock (&fc->lock);list_add_tail (&fud->entry, &fc->devices);spin_unlock (&fc->lock); +} +EXPORT_SYMBOL_GPL (fuse_dev_install); +struct fuse_dev *fuse_dev_alloc_install (struct fuse_conn *fc) +{ +struct fuse_dev *fud; + + fud =fuse_dev_alloc (); +if (!fud) +return NULL ; + +fuse_dev_install (fud, fc);return fud; } -EXPORT_SYMBOL_GPL (fuse_dev_alloc); +EXPORT_SYMBOL_GPL (fuse_dev_alloc_install);void fuse_dev_free (struct fuse_dev *fud) {
@@ -1119,7 +1134,7 @@ int fuse_fill_super_common(struct super_block *sb, mount_data->fiq_priv); fc->release = fuse_free_conn; - fud =fuse_dev_alloc (fc); + fud =fuse_dev_alloc_install (fc);if (!fud) goto err_put_conn;
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 11/13 virtio_fs: add skeleton virtio_fs.ko module
In reply to Vivek GoyalFrom: Stefan Hajnoczi <[email protected]>
Add a basic file system module for virtio-fs.
--- fs/fuse/Kconfig | 11 + fs/fuse/Makefile | 1 + fs/fuse/fuse_i.h | 12 + fs/fuse/inode.c | 27 +- fs/fuse/virtio_fs.c | 1060 +++++++++++++++++++++++++++++++ include/uapi/linux/virtio_fs.h | 41 ++ include/uapi/linux/virtio_ids.h | 1 + 7 files changed, 1142 insertions(+), 11 deletions(-) create mode 100644 fs/fuse/virtio_fs.c create mode 100644 include/uapi/linux/virtio_fs.h
fs/fuse/Kconfig +11 -0
@@ -27,3 +27,14 @@ config CUSE If you want to develop or use a userspace character device based on CUSE, answer Y or M. + +config VIRTIO_FS + tristate "Virtio Filesystem" + depends on FUSE_FS + select VIRTIO + help + The Virtio Filesystem allows guests to mount file systems from the + host. + + If you want to share files between guests or with the host, answer Y + or M.
fs/fuse/Makefile +1 -0
@@ -5,5 +5,6 @@ obj-$(CONFIG_FUSE_FS) += fuse.o obj-$(CONFIG_CUSE) += cuse.o +obj-$(CONFIG_VIRTIO_FS) += virtio_fs.o fuse-objs := dev.o dir.o file.o inode.o control.o xattr.o acl.o readdir.o
fs/fuse/fuse_i.h +12 -0
@@ -72,6 +72,7 @@ struct fuse_mount_data { unsigned group_id_present:1; unsigned default_permissions:1; unsigned allow_other:1; + unsigned destroy:1;unsigned max_read;unsigned blksize;
@@ -469,6 +470,9 @@ struct fuse_req {/** Request is stolen from fuse_file->reserved_req */ struct file *stolen_file; + +/** virtio-fs's physically contiguous buffer for in and out args */ +void *argbuf; };struct fuse_iqueue ;
@@ -1080,6 +1084,13 @@ int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev,int fuse_fill_super_common (struct super_block *sb,struct fuse_mount_data *mount_data); +/** +* Disassociate fuse connection from superblock and kill the superblock +* +* Calls kill_anon_super(), use with do not use with bdev mounts. +*/ +void fuse_kill_sb_anon (struct super_block *sb); +/** * Add connection to control filesystem */
@@ -1192,5 +1203,6 @@ unsigned fuse_len_args(unsigned numargs, struct fuse_arg *args);* Get the next unique ID for a request */ u64 fuse_get_unique (struct fuse_iqueue *fiq); +void fuse_free_conn (struct fuse_conn *fc);#endif /* _FS_FUSE_I_H */
fs/fuse/inode.c +16 -11
@@ -978,11 +978,12 @@ void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) }EXPORT_SYMBOL_GPL (fuse_send_init); -static void fuse_free_conn (struct fuse_conn *fc) +void fuse_free_conn (struct fuse_conn *fc) {WARN_ON (!list_empty (&fc->devices));kfree_rcu (fc, rcu); } +EXPORT_SYMBOL_GPL (fuse_free_conn);static int fuse_bdi_init (struct fuse_conn *fc,struct super_block *sb) {
@@ -1125,14 +1126,16 @@ int fuse_fill_super_common(struct super_block *sb,if (sb->s_user_ns != &init_user_ns) sb->s_xattr = fuse_no_acl_xattr_handlers; - fc =kmalloc (sizeof (*fc),GFP_KERNEL ); - err = -ENOMEM ; -if (!fc) - goto err; - -fuse_conn_init (fc, sb->s_user_ns, mount_data->fiq_ops, - mount_data->fiq_priv); - fc->release = fuse_free_conn; + fc =get_fuse_conn_super (sb); +if (!fc) { + fc =kmalloc (sizeof (*fc),GFP_KERNEL ); + err = -ENOMEM ; +if (!fc) + goto err; +fuse_conn_init (fc, sb->s_user_ns, mount_data->fiq_ops, + mount_data->fiq_priv); + fc->release = fuse_free_conn; + } fud =fuse_dev_alloc_install (fc);if (!fud)
@@ -1167,7 +1170,7 @@ int fuse_fill_super_common(struct super_block *sb,/* Root dentry doesn't have .d_revalidate */ sb->s_d_op = &fuse_dentry_operations; -if (is_bdev) { +if (mount_data->destroy) { fc->destroy_req =fuse_request_alloc (0 );if (!fc->destroy_req) goto err_put_root;
@@ -1236,6 +1239,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) d.fiq_ops = &fuse_dev_fiq_ops; d.fiq_priv =NULL ; d.fudptr = &file->private_data; + d.destroy = is_bdev; err =fuse_fill_super_common (sb, &d);if (err <0 ) goto err_free_init_req;
@@ -1279,11 +1283,12 @@ static void fuse_sb_destroy(struct super_block *sb) } } -static void fuse_kill_sb_anon (struct super_block *sb) +void fuse_kill_sb_anon (struct super_block *sb) {fuse_sb_destroy (sb);kill_anon_super (sb); } +EXPORT_SYMBOL_GPL (fuse_kill_sb_anon);static struct file_system_type fuse_fs_type = { .owner =THIS_MODULE ,
fs/fuse/virtio_fs.c new file +1060 -0
1,060 lines not on this page · raw message
include/uapi/linux/virtio_fs.h new file +41 -0
41 lines not on this page · raw message
include/uapi/linux/virtio_ids.h +1 -0
@@ -44,6 +44,7 @@#define VIRTIO_ID_VSOCK 19/* virtio vsock transport */ #define VIRTIO_ID_CRYPTO 20/* virtio crypto */ #define VIRTIO_ID_IOMMU 23/* virtio IOMMU */ +#define VIRTIO_ID_FS 26/* virtio filesystem */ #define VIRTIO_ID_PMEM 27/* virtio pmem */ #endif /* _LINUX_VIRTIO_IDS_H */
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 12/13 virtio-fs: Do not provide abort interface in fusectl
In reply to Vivek Goyalvirtio-fs does not support aborting requests which are being processed. That is requests which have been sent to fuse daemon on host.
So do not provide "abort" interface for virtio-fs in fusectl.
--- fs/fuse/control.c | 4 ++-- fs/fuse/fuse_i.h | 4 ++++ fs/fuse/inode.c | 1 + fs/fuse/virtio_fs.c | 1 + 4 files changed, 8 insertions(+), 2 deletions(-)
fs/fuse/control.c +2 -2
@@ -279,8 +279,8 @@ int fuse_ctl_add_conn(struct fuse_conn *fc)if (!fuse_ctl_add_dentry (parent, fc,"waiting" ,S_IFREG |0400 ,1 ,NULL , &fuse_ctl_waiting_ops) || - !fuse_ctl_add_dentry (parent, fc,"abort" ,S_IFREG |0200 ,1 , -NULL , &fuse_ctl_abort_ops) || + (!fc->no_abort && !fuse_ctl_add_dentry (parent, fc,"abort" , +S_IFREG |0200 ,1 ,NULL , &fuse_ctl_abort_ops)) || !fuse_ctl_add_dentry (parent, fc,"max_background" ,S_IFREG |0600 ,1 ,NULL , &fuse_conn_max_background_ops) || !fuse_ctl_add_dentry(parent, fc, "congestion_threshold",
fs/fuse/fuse_i.h +4 -0
@@ -73,6 +73,7 @@ struct fuse_mount_data { unsigned default_permissions:1; unsigned allow_other:1; unsigned destroy:1; + unsigned no_abort:1;unsigned max_read;unsigned blksize;
@@ -789,6 +790,9 @@ struct fuse_conn {/** Does the filesystem support copy_file_range? */ unsigned no_copy_file_range:1; +/** Do not create abort file in fuse control fs */ + unsigned no_abort:1; +/** The number of requests waiting for completion */ atomic_t num_waiting;
fs/fuse/inode.c +1 -0
@@ -1157,6 +1157,7 @@ int fuse_fill_super_common(struct super_block *sb, fc->user_id = mount_data->user_id; fc->group_id = mount_data->group_id; fc->max_read =max_t (unsigned,4096 , mount_data->max_read); + fc->no_abort = mount_data->no_abort;/* Used by get_root_inode() */ sb->s_fs_info = fc;
fs/fuse/virtio_fs.c +1 -0
@@ -886,6 +886,7 @@ static int virtio_fs_fill_super(struct super_block *sb, char *opts, d->fudptr = (void **)&fs->vqs[VQ_REQUEST ].fud; d->destroy = true;/* Send destroy request on unmount */ + d->no_abort =1 ; err =fuse_fill_super_common (sb, d);if (err <0 ) goto err_free_init_req;
Signature · 1 line
2.20.1
Vivek Goyal
maintainerPATCH v3 13/13 init/do_mounts.c: add virtio_fs root fs support
In reply to Vivek GoyalIt is useful to mount the root file system via virtio_fs. During testing a monolithic kernel is more convenient than an initramfs but we'll need to teach the kernel how to boot directly from virtio_fs.
--- init/do_mounts.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
init/do_mounts.c +10 -0
@@ -554,6 +554,16 @@ void __init mount_root(void)change_floppy ("root floppy" ); }#endif +#ifdef CONFIG_VIRTIO_FS +if (root_fs_names && !strcmp (root_fs_names,"virtio_fs" )) { +if (!do_mount_root (root_device_name,"virtio_fs" , + root_mountflags, root_mount_data)) +return ; + +panic ("VFS: Unable to mount root fs \"%s\" from virtio_fs" , + root_device_name); + } +#endif #ifdef CONFIG_BLOCK {int err =create_dev ("/dev/root" ,ROOT_DEV );
Signature · 1 line
2.20.1
Miklos Szeredi
maintainerQuoted 11 lines · Vivek Goyal
Hi,
Here are the V3 patches for virtio-fs filesystem. This time I have broken the patch series in two parts. This is first part which does not contain DAX support. Second patch series will contain the patches for DAX support.
I have also dropped RFC tag from first patch series as we believe its in good enough shape that it should get a consideration for inclusion upstream.
Pushed out to
git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git#for-next
Major changes compared to patchset:
- renamed to "virtiofs". Filesystem names don't usually have
underscore before "fs" postfix.
- removed option parsing completely. Virtiofs config is fixed to "-o
rootmode=040000,user_id=0,group_id=0,allow_other,default_permissions". Does this sound reasonable?
There are miscellaneous changes, so needs to be thoroughly tested.
I think we also need something in "Documentation/filesystems/virtiofs.rst" which describes the design (how request gets to userspace and back) and how to set up the server, etc... Stefan, Vivek can you do something like that?
Thanks,
Miklos
Vivek Goyal
maintainerQuoted 9 lines · Miklos Szeredi
Quoted 8 lines · Vivek Goyal
Hi,
Here are the V3 patches for virtio-fs filesystem. This time I have broken the patch series in two parts. This is first part which does not contain DAX support. Second patch series will contain the patches for DAX support.
Quoted 8 lines
Quoted 3 lines
I have also dropped RFC tag from first patch series as we believe its in good enough shape that it should get a consideration for inclusion upstream.
Pushed out to
git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git#for-next
Awesome.
Quoted 5 lines
Major changes compared to patchset:
- renamed to "virtiofs". Filesystem names don't usually have
underscore before "fs" postfix.
Sound good to me.
Quoted 3 lines
- removed option parsing completely. Virtiofs config is fixed to "-o
rootmode=040000,user_id=0,group_id=0,allow_other,default_permissions". Does this sound reasonable?
These are the options we are using now and looks like they make lot of sense for virtiofs. I guess if somebody needs a different configuration later we can introduce option parsing and override these defaults.
Quoted 2 lines
There are miscellaneous changes, so needs to be thoroughly tested.
I will test these.
Quoted 5 lines
I think we also need something in "
Documentation/filesystems/virtiofs.rst" which describes the design (how request gets to userspace and back) and how to set up the server, etc... Stefan, Vivek can you do something like that?
Sure, I will write up something and take Stefan's input as well.
Thanks
Vivek
Stefan Hajnoczi
maintainerQuoted 1 line · Miklos Szeredi
On Wed, Aug 21, 2019 at 7:38 PM Vivek Goyal <[email protected]> wrote:
Thanks!
Quoted 3 lines
- removed option parsing completely. Virtiofs config is fixed to "-o
rootmode=040000,user_id=0,group_id=0,allow_other,default_permissions". Does this sound reasonable?
That simplifies things for users and I've never seen a need to change these options in virtio-fs. If we need the control for some reason in the future we can add options back in again.
Quoted 4 lines
I think we also need something in "
Documentation/filesystems/virtiofs.rst" which describes the design (how request gets to userspace and back) and how to set up the server, etc... Stefan, Vivek can you do something like that?
Sure. I'll send a patch.
Stefan
Vivek Goyal
maintainerQuoted 9 lines · Miklos Szeredi
Quoted 8 lines · Vivek Goyal
Hi,
Here are the V3 patches for virtio-fs filesystem. This time I have broken the patch series in two parts. This is first part which does not contain DAX support. Second patch series will contain the patches for DAX support.
Quoted 8 lines
Quoted 3 lines
I have also dropped RFC tag from first patch series as we believe its in good enough shape that it should get a consideration for inclusion upstream.
Pushed out to
git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git#for-next
Hi Miklos,
Compilation of virtio-fs as module fails. While it works if compiled as non-module.
fs/fuse/virtio_fs.c: In function ‘copy_args_to_argbuf’:fs/fuse/virtio_fs.c:255:5: error: ‘struct fuse_req’ has no member named ‘argbuf’
req->argbuf = kmalloc(len, GFP_ATOMIC);
It can't find req->argbuf.
I noticed that you have put ifdef around argbuf.
#ifdef CONFIG_VIRTIO_FS
/** virtio-fs's physically contiguous buffer for in and out args */
void *argbuf;#endif
It should have worked. Not sure why it is not working.
Vivek
Miklos Szeredi
maintainerQuoted 6 lines · Vivek Goyal
#ifdef CONFIG_VIRTIO_FS /** virtio-fs's physically contiguous buffer for in and out args */ void *argbuf;#endif
It should have worked. Not sure why it is not working.
Needs to be changed to
#if IS_ENABLED(CONFIG_VIRTIO_FS)
Pushed out fixed version.
Thanks,
Miklos
Vivek Goyal
maintainerQuoted 7 lines · Miklos Szeredi
Quoted 5 lines · Vivek Goyal
#ifdef CONFIG_VIRTIO_FS /** virtio-fs's physically contiguous buffer for in and out args */ void *argbuf;#endif
Quoted 7 lines
Quoted 1 line
It should have worked. Not sure why it is not working.
Needs to be changed to
#if
IS_ENABLED(CONFIG_VIRTIO_FS)Pushed out fixed version.
Cool. That works. Faced another compilation error with "make allmodconfig" config file.
HDRINST usr/include/linux/virtio_fs.h
error: include/uapi/linux/virtio_fs.h: missing "WITH Linux-syscall-note" for SPDX-License-Identifier make[1]: *** [scripts/Makefile.headersinst:66: usr/include/linux/virtio_fs.h] Error 1
Looks like include/uapi/linux/virtio_fs.h needs following.
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
Vivek
Miklos Szeredi
maintainerReview
Quoted 11 lines · Vivek Goyal
Cool. That works. Faced another compilation error with "make allmodconfig" config file.
HDRINST
usr/include/linux/virtio_fs.h
error:include/uapi/linux/virtio_fs.h: missing "WITH Linux-syscall-note" for SPDX-License-Identifier make[1]: *** [scripts/Makefile.headersinst:66:usr/include/linux/virtio_fs.h] Error 1Looks like
include/uapi/linux/virtio_fs.hneeds following.(quoted diff) +1
-1-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
Fixed and pushed.
Thanks,
Miklos
Vivek Goyal
maintainerOn Thu, Aug 29, 2019 at 11:28:27AM +0200, Miklos Szeredi wrote:
[..]
Quoted 1 line
There are miscellaneous changes, so needs to be thoroughly tested.
Hi Miklos,
First round of tests passed. Ran pjdfstests, blogbench and bunch of fio jobs and everyting looks good.
Thanks
Vivek
Miklos Szeredi
maintainerQuoted 10 lines · Vivek Goyal
On Thu, Aug 29, 2019 at 11:28:27AM +0200, Miklos Szeredi wrote:
[..]
Quoted 1 line
There are miscellaneous changes, so needs to be thoroughly tested.
Hi Miklos,
First round of tests passed. Ran pjdfstests, blogbench and bunch of fio jobs and everyting looks good.
fsx-linux with cache=always revealed a couple of bugs in the argpages case. Pushed fixes for those too.
Thanks,
Miklos
Miklos Szeredi
maintainer[Cc: [email protected], "Michael S. Tsirkin" <[email protected]>, Jason Wang <[email protected]>]
It'd be nice to have an ACK for this from the virtio maintainers.
Thanks,
Miklos
Quoted 304 lines · Vivek Goyal
Hi,
Here are the V3 patches for virtio-fs filesystem. This time I have broken the patch series in two parts. This is first part which does not contain DAX support. Second patch series will contain the patches for DAX support.
I have also dropped RFC tag from first patch series as we believe its in good enough shape that it should get a consideration for inclusion upstream.
These patches apply on top of 5.3-rc5 kernel and are also available here.
https://github.com/rhvgoyal/linux/commits/vivek-5.3-aug-21-2019
Patches for V1 and V2 were posted here.
https://lwn.net/ml/linux-fsdevel/[email protected]/
http://lkml.iu.edu/hypermail/linux/kernel/1905.1/07232.htmlMore information about the project can be found here.
Changes from V2
===============
- Various bug fixes and performance improvements.HOWTO
======
We have put instructions on how to use it here.Some Performance Numbers
========================
I have basically run bunch of fio jobs to get a sense of speed of various operations. I wrote a simple wrapper script to run fio jobs 3 times and take their average and report it. These scripts are available here.https://github.com/rhvgoyal/virtiofs-tests
I set up a directory on ramfs on host and exported that directory inside guest using virtio-9p and virtio-fs and ran tests inside guests. Ran tests with cache=none both for virtio-9p and virtio-fs so that no caching happens in guest. For virtio-fs, I ran an additional set of tests with dax enabled. Dax is not part of first patch series but I included results here because dax seems to get the maximum performance advantage and its shows the real potential of virtio-fs.
Test Setup
-----------
- A fedora 28 host with 32G RAM, 2 sockets (6 cores per socket, 2 threads per core)- Using ramfs on host as backing store. 4 fio files of 2G each.
- Created a VM with 16 VCPUS and 8GB memory. An 8GB cache window (for dax mmap).
Test Results
------------
- Results in three configurations have been reported. 9p (cache=none), virtio-fs (cache=none) and virtio-fs (cache=none + dax).There are other caching modes as well but to me cache=none seemed most interesting for now because it does not cache anything in guest and provides strong coherence. Other modes which provide less strong coherence and hence are faster are yet to be benchmarked.
- Three fio ioengines psync, libaio and mmap have been used.
- I/O Workload of randread, radwrite, seqread and seqwrite have been run.
- Each file size is 2G. Block size 4K. iodepth=16
- "multi" means same operation was done with 4 jobs and each job is operating on a file of size 2G.
- Some results are "0 (KiB/s)". That means that particular operation is not supported in that configuration.
NAME I/O Operation BW(Read/Write)
9p-cache-none seqread-psync 27(MiB/s) virtiofs-cache-none seqread-psync 35(MiB/s) virtiofs-dax-cache-none seqread-psync 245(MiB/s)9p-cache-none seqread-psync-multi 117(MiB/s) virtiofs-cache-none seqread-psync-multi 162(MiB/s) virtiofs-dax-cache-none seqread-psync-multi 894(MiB/s)9p-cache-none seqread-mmap 24(MiB/s) virtiofs-cache-none seqread-mmap 0(KiB/s) virtiofs-dax-cache-none seqread-mmap 168(MiB/s)9p-cache-none seqread-mmap-multi 115(MiB/s) virtiofs-cache-none seqread-mmap-multi 0(KiB/s) virtiofs-dax-cache-none seqread-mmap-multi 614(MiB/s)9p-cache-none seqread-libaio 26(MiB/s) virtiofs-cache-none seqread-libaio 139(MiB/s) virtiofs-dax-cache-none seqread-libaio 160(MiB/s)9p-cache-none seqread-libaio-multi 129(MiB/s) virtiofs-cache-none seqread-libaio-multi 142(MiB/s) virtiofs-dax-cache-none seqread-libaio-multi 577(MiB/s)9p-cache-none randread-psync 29(MiB/s) virtiofs-cache-none randread-psync 34(MiB/s) virtiofs-dax-cache-none randread-psync 256(MiB/s)9p-cache-none randread-psync-multi 139(MiB/s) virtiofs-cache-none randread-psync-multi 153(MiB/s) virtiofs-dax-cache-none randread-psync-multi 245(MiB/s)9p-cache-none randread-mmap 22(MiB/s) virtiofs-cache-none randread-mmap 0(KiB/s) virtiofs-dax-cache-none randread-mmap 162(MiB/s)9p-cache-none randread-mmap-multi 111(MiB/s) virtiofs-cache-none randread-mmap-multi 0(KiB/s) virtiofs-dax-cache-none randread-mmap-multi 215(MiB/s)9p-cache-none randread-libaio 26(MiB/s) virtiofs-cache-none randread-libaio 135(MiB/s) virtiofs-dax-cache-none randread-libaio 157(MiB/s)9p-cache-none randread-libaio-multi 133(MiB/s) virtiofs-cache-none randread-libaio-multi 245(MiB/s) virtiofs-dax-cache-none randread-libaio-multi 163(MiB/s)9p-cache-none seqwrite-psync 28(MiB/s) virtiofs-cache-none seqwrite-psync 34(MiB/s) virtiofs-dax-cache-none seqwrite-psync 203(MiB/s)9p-cache-none seqwrite-psync-multi 128(MiB/s) virtiofs-cache-none seqwrite-psync-multi 155(MiB/s) virtiofs-dax-cache-none seqwrite-psync-multi 717(MiB/s)9p-cache-none seqwrite-mmap 0(KiB/s) virtiofs-cache-none seqwrite-mmap 0(KiB/s) virtiofs-dax-cache-none seqwrite-mmap 165(MiB/s)9p-cache-none seqwrite-mmap-multi 0(KiB/s) virtiofs-cache-none seqwrite-mmap-multi 0(KiB/s) virtiofs-dax-cache-none seqwrite-mmap-multi 511(MiB/s)9p-cache-none seqwrite-libaio 27(MiB/s) virtiofs-cache-none seqwrite-libaio 128(MiB/s) virtiofs-dax-cache-none seqwrite-libaio 141(MiB/s)9p-cache-none seqwrite-libaio-multi 119(MiB/s) virtiofs-cache-none seqwrite-libaio-multi 242(MiB/s) virtiofs-dax-cache-none seqwrite-libaio-multi 505(MiB/s)9p-cache-none randwrite-psync 27(MiB/s) virtiofs-cache-none randwrite-psync 34(MiB/s) virtiofs-dax-cache-none randwrite-psync 189(MiB/s)9p-cache-none randwrite-psync-multi 137(MiB/s) virtiofs-cache-none randwrite-psync-multi 150(MiB/s) virtiofs-dax-cache-none randwrite-psync-multi 233(MiB/s)9p-cache-none randwrite-mmap 0(KiB/s) virtiofs-cache-none randwrite-mmap 0(KiB/s) virtiofs-dax-cache-none randwrite-mmap 120(MiB/s)9p-cache-none randwrite-mmap-multi 0(KiB/s) virtiofs-cache-none randwrite-mmap-multi 0(KiB/s) virtiofs-dax-cache-none randwrite-mmap-multi 200(MiB/s)9p-cache-none randwrite-libaio 25(MiB/s) virtiofs-cache-none randwrite-libaio 124(MiB/s) virtiofs-dax-cache-none randwrite-libaio 131(MiB/s)9p-cache-none randwrite-libaio-multi 125(MiB/s) virtiofs-cache-none randwrite-libaio-multi 241(MiB/s) virtiofs-dax-cache-none randwrite-libaio-multi 163(MiB/s)Conclusions
===========
- In general virtio-fs seems faster than virtio-9p. Using dax makes it really interesting.Note:
Right now dax window is 8G and max fio file size is 8G as well (4 files of 2G each). That means everything fits into dax window and no reclaim is needed. Dax window reclaim logic is slower and if file size is bigger than dax window size, performance slows down.Description from previous postings
==================================Design Overview
===============
With the goal of designing something with better performance and local file system semantics, a bunch of ideas were proposed.- Use fuse protocol (instead of 9p) for communication between guest and host. Guest kernel will be fuse client and a fuse server will run on host to serve the requests.
- For data access inside guest, mmap portion of file in QEMU address space and guest accesses this memory using dax. That way guest page cache is bypassed and there is only one copy of data (on host). This will also enable
mmap(MAP_SHARED)between guests.- For metadata coherency, there is a shared memory region which contains version number associated with metadata and any guest changing metadata updates version number and other guests refresh metadata on next access. This is yet to be implemented.
How virtio-fs differs from existing approaches
==============================================
The unique idea behind virtio-fs is to take advantage of the co-location of the virtual machine and hypervisor to avoid communication (vmexits).DAX allows file contents to be accessed without communication with the hypervisor. The shared memory region for metadata avoids communication in the common case where metadata is unchanged.
By replacing expensive communication with cheaper shared memory accesses, we expect to achieve better performance than approaches based on network file system protocols. In addition, this also makes it easier to achieve local file system semantics (coherency).
These techniques are not applicable to network file system protocols since the communications channel is bypassed by taking advantage of shared memory on a local machine. This is why we decided to build virtio-fs rather than focus on 9P or NFS.
Caching Modes
=============
Like virtio-9p, different caching modes are supported which determine the coherency level as well. The “cache=FOO” and “writeback” options control the level of coherence between the guest and host filesystems.- cache=none
metadata, data and pathname lookup are not cached in guest. They are always fetched from host and any changes are immediately pushed to host.- cache=always
metadata, data and pathname lookup are cached in guest and never expire.- cache=auto
metadata and pathname lookup cache expires after a configured amount of time (default is 1 second). Data is cached while the file is open (close to open consistency).- writeback/no_writeback
These options control the writeback strategy. If writeback is disabled, then normal writes will immediately be synchronized with the host fs. If writeback is enabled, then writes may be cached in the guest until the file is closed or an fsync(2) performed. This option has no effect on mmap-ed writes or writes going through the DAX mechanism.Thanks
VivekMiklos Szeredi (2):
fuse: delete dentry if timeout is zero
fuse: Usedefault_file_splice_readfor direct IOStefan Hajnoczi (6):
fuse: exportfuse_end_request()
fuse: exportfuse_len_args()
fuse: exportfuse_get_unique()
fuse: extractfuse_fill_super_common()
fuse: addfuse_iqueue_opscallbacks
virtio_fs: add skeleton virtio_fs.ko moduleVivek Goyal (5):
fuse: Exportfuse_send_init_request()
Exportfuse_dequeue_forget()function
fuse: Separate fuse device allocation and installation infuse_conn
virtio-fs: Do not provide abort interface in fusectlinit/do_mounts.c: addvirtio_fsroot fs supportfs/fuse/Kconfig | 11 + fs/fuse/Makefile | 1 + fs/fuse/control.c | 4 +- fs/fuse/cuse.c | 4 +- fs/fuse/dev.c | 89 ++- fs/fuse/dir.c | 26 +- fs/fuse/file.c | 15 +- fs/fuse/fuse_i.h | 120 +++- fs/fuse/inode.c | 203 +++--- fs/fuse/virtio_fs.c | 1061 +++++++++++++++++++++++++++++++ fs/splice.c | 3 +- include/linux/fs.h | 2 + include/uapi/linux/virtio_fs.h | 41 ++ include/uapi/linux/virtio_ids.h | 1 + init/do_mounts.c | 10 + 15 files changed, 1462 insertions(+), 129 deletions(-) create mode 100644 fs/fuse/virtio_fs.c create mode 100644 include/uapi/linux/virtio_fs.h--
2.20.1
Michael S. Tsirkin
maintainerQuoted 7 lines · Miklos Szeredi
[Cc: [email protected], "Michael S. Tsirkin" <[email protected]>, Jason Wang <[email protected]>]
It'd be nice to have an ACK for this from the virtio maintainers.
Thanks,
Miklos
Can the patches themselves be posted to the relevant list(s) please? If possible, please also include "v3" in all patches so they are easier to find.
I poked at
https://lwn.net/ml/linux-kernel/[email protected]/
specifically
https://lwn.net/ml/linux-kernel/[email protected]/
and things like:
+ /* TODO lock */
give me pause.
Cleanup generally seems broken to me - what pauses the FS
What about the rest of TODOs in that file?
use of usleep is hacky - can't we do better e.g. with a completion?
Some typos - e.g. "reuests".
Quoted 294 lines · Vivek Goyal
Quoted 292 lines
Hi,
Here are the V3 patches for virtio-fs filesystem. This time I have broken the patch series in two parts. This is first part which does not contain DAX support. Second patch series will contain the patches for DAX support.
I have also dropped RFC tag from first patch series as we believe its in good enough shape that it should get a consideration for inclusion upstream.
These patches apply on top of 5.3-rc5 kernel and are also available here.
https://github.com/rhvgoyal/linux/commits/vivek-5.3-aug-21-2019
Patches for V1 and V2 were posted here.
https://lwn.net/ml/linux-fsdevel/[email protected]/
http://lkml.iu.edu/hypermail/linux/kernel/1905.1/07232.htmlMore information about the project can be found here.
Changes from V2
===============
- Various bug fixes and performance improvements.HOWTO
======
We have put instructions on how to use it here.Some Performance Numbers
========================
I have basically run bunch of fio jobs to get a sense of speed of various operations. I wrote a simple wrapper script to run fio jobs 3 times and take their average and report it. These scripts are available here.https://github.com/rhvgoyal/virtiofs-tests
I set up a directory on ramfs on host and exported that directory inside guest using virtio-9p and virtio-fs and ran tests inside guests. Ran tests with cache=none both for virtio-9p and virtio-fs so that no caching happens in guest. For virtio-fs, I ran an additional set of tests with dax enabled. Dax is not part of first patch series but I included results here because dax seems to get the maximum performance advantage and its shows the real potential of virtio-fs.
Test Setup
-----------
- A fedora 28 host with 32G RAM, 2 sockets (6 cores per socket, 2 threads per core)- Using ramfs on host as backing store. 4 fio files of 2G each.
- Created a VM with 16 VCPUS and 8GB memory. An 8GB cache window (for dax mmap).
Test Results
------------
- Results in three configurations have been reported. 9p (cache=none), virtio-fs (cache=none) and virtio-fs (cache=none + dax).There are other caching modes as well but to me cache=none seemed most interesting for now because it does not cache anything in guest and provides strong coherence. Other modes which provide less strong coherence and hence are faster are yet to be benchmarked.
- Three fio ioengines psync, libaio and mmap have been used.
- I/O Workload of randread, radwrite, seqread and seqwrite have been run.
- Each file size is 2G. Block size 4K. iodepth=16
- "multi" means same operation was done with 4 jobs and each job is operating on a file of size 2G.
- Some results are "0 (KiB/s)". That means that particular operation is not supported in that configuration.
NAME I/O Operation BW(Read/Write)
9p-cache-none seqread-psync 27(MiB/s) virtiofs-cache-none seqread-psync 35(MiB/s) virtiofs-dax-cache-none seqread-psync 245(MiB/s)9p-cache-none seqread-psync-multi 117(MiB/s) virtiofs-cache-none seqread-psync-multi 162(MiB/s) virtiofs-dax-cache-none seqread-psync-multi 894(MiB/s)9p-cache-none seqread-mmap 24(MiB/s) virtiofs-cache-none seqread-mmap 0(KiB/s) virtiofs-dax-cache-none seqread-mmap 168(MiB/s)9p-cache-none seqread-mmap-multi 115(MiB/s) virtiofs-cache-none seqread-mmap-multi 0(KiB/s) virtiofs-dax-cache-none seqread-mmap-multi 614(MiB/s)9p-cache-none seqread-libaio 26(MiB/s) virtiofs-cache-none seqread-libaio 139(MiB/s) virtiofs-dax-cache-none seqread-libaio 160(MiB/s)9p-cache-none seqread-libaio-multi 129(MiB/s) virtiofs-cache-none seqread-libaio-multi 142(MiB/s) virtiofs-dax-cache-none seqread-libaio-multi 577(MiB/s)9p-cache-none randread-psync 29(MiB/s) virtiofs-cache-none randread-psync 34(MiB/s) virtiofs-dax-cache-none randread-psync 256(MiB/s)9p-cache-none randread-psync-multi 139(MiB/s) virtiofs-cache-none randread-psync-multi 153(MiB/s) virtiofs-dax-cache-none randread-psync-multi 245(MiB/s)9p-cache-none randread-mmap 22(MiB/s) virtiofs-cache-none randread-mmap 0(KiB/s) virtiofs-dax-cache-none randread-mmap 162(MiB/s)9p-cache-none randread-mmap-multi 111(MiB/s) virtiofs-cache-none randread-mmap-multi 0(KiB/s) virtiofs-dax-cache-none randread-mmap-multi 215(MiB/s)9p-cache-none randread-libaio 26(MiB/s) virtiofs-cache-none randread-libaio 135(MiB/s) virtiofs-dax-cache-none randread-libaio 157(MiB/s)9p-cache-none randread-libaio-multi 133(MiB/s) virtiofs-cache-none randread-libaio-multi 245(MiB/s) virtiofs-dax-cache-none randread-libaio-multi 163(MiB/s)9p-cache-none seqwrite-psync 28(MiB/s) virtiofs-cache-none seqwrite-psync 34(MiB/s) virtiofs-dax-cache-none seqwrite-psync 203(MiB/s)9p-cache-none seqwrite-psync-multi 128(MiB/s) virtiofs-cache-none seqwrite-psync-multi 155(MiB/s) virtiofs-dax-cache-none seqwrite-psync-multi 717(MiB/s)9p-cache-none seqwrite-mmap 0(KiB/s) virtiofs-cache-none seqwrite-mmap 0(KiB/s) virtiofs-dax-cache-none seqwrite-mmap 165(MiB/s)9p-cache-none seqwrite-mmap-multi 0(KiB/s) virtiofs-cache-none seqwrite-mmap-multi 0(KiB/s) virtiofs-dax-cache-none seqwrite-mmap-multi 511(MiB/s)9p-cache-none seqwrite-libaio 27(MiB/s) virtiofs-cache-none seqwrite-libaio 128(MiB/s) virtiofs-dax-cache-none seqwrite-libaio 141(MiB/s)9p-cache-none seqwrite-libaio-multi 119(MiB/s) virtiofs-cache-none seqwrite-libaio-multi 242(MiB/s) virtiofs-dax-cache-none seqwrite-libaio-multi 505(MiB/s)9p-cache-none randwrite-psync 27(MiB/s) virtiofs-cache-none randwrite-psync 34(MiB/s) virtiofs-dax-cache-none randwrite-psync 189(MiB/s)9p-cache-none randwrite-psync-multi 137(MiB/s) virtiofs-cache-none randwrite-psync-multi 150(MiB/s) virtiofs-dax-cache-none randwrite-psync-multi 233(MiB/s)9p-cache-none randwrite-mmap 0(KiB/s) virtiofs-cache-none randwrite-mmap 0(KiB/s) virtiofs-dax-cache-none randwrite-mmap 120(MiB/s)9p-cache-none randwrite-mmap-multi 0(KiB/s) virtiofs-cache-none randwrite-mmap-multi 0(KiB/s) virtiofs-dax-cache-none randwrite-mmap-multi 200(MiB/s)9p-cache-none randwrite-libaio 25(MiB/s) virtiofs-cache-none randwrite-libaio 124(MiB/s) virtiofs-dax-cache-none randwrite-libaio 131(MiB/s)9p-cache-none randwrite-libaio-multi 125(MiB/s) virtiofs-cache-none randwrite-libaio-multi 241(MiB/s) virtiofs-dax-cache-none randwrite-libaio-multi 163(MiB/s)Conclusions
===========
- In general virtio-fs seems faster than virtio-9p. Using dax makes it really interesting.Note:
Right now dax window is 8G and max fio file size is 8G as well (4 files of 2G each). That means everything fits into dax window and no reclaim is needed. Dax window reclaim logic is slower and if file size is bigger than dax window size, performance slows down.Description from previous postings
==================================Design Overview
===============
With the goal of designing something with better performance and local file system semantics, a bunch of ideas were proposed.- Use fuse protocol (instead of 9p) for communication between guest and host. Guest kernel will be fuse client and a fuse server will run on host to serve the requests.
- For data access inside guest, mmap portion of file in QEMU address space and guest accesses this memory using dax. That way guest page cache is bypassed and there is only one copy of data (on host). This will also enable
mmap(MAP_SHARED)between guests.- For metadata coherency, there is a shared memory region which contains version number associated with metadata and any guest changing metadata updates version number and other guests refresh metadata on next access. This is yet to be implemented.
How virtio-fs differs from existing approaches
==============================================
The unique idea behind virtio-fs is to take advantage of the co-location of the virtual machine and hypervisor to avoid communication (vmexits).DAX allows file contents to be accessed without communication with the hypervisor. The shared memory region for metadata avoids communication in the common case where metadata is unchanged.
By replacing expensive communication with cheaper shared memory accesses, we expect to achieve better performance than approaches based on network file system protocols. In addition, this also makes it easier to achieve local file system semantics (coherency).
These techniques are not applicable to network file system protocols since the communications channel is bypassed by taking advantage of shared memory on a local machine. This is why we decided to build virtio-fs rather than focus on 9P or NFS.
Caching Modes
=============
Like virtio-9p, different caching modes are supported which determine the coherency level as well. The “cache=FOO” and “writeback” options control the level of coherence between the guest and host filesystems.- cache=none
metadata, data and pathname lookup are not cached in guest. They are always fetched from host and any changes are immediately pushed to host.- cache=always
metadata, data and pathname lookup are cached in guest and never expire.- cache=auto
metadata and pathname lookup cache expires after a configured amount of time (default is 1 second). Data is cached while the file is open (close to open consistency).- writeback/no_writeback
These options control the writeback strategy. If writeback is disabled, then normal writes will immediately be synchronized with the host fs. If writeback is enabled, then writes may be cached in the guest until the file is closed or an fsync(2) performed. This option has no effect on mmap-ed writes or writes going through the DAX mechanism.Thanks
VivekMiklos Szeredi (2):
fuse: delete dentry if timeout is zero
fuse: Usedefault_file_splice_readfor direct IOStefan Hajnoczi (6):
fuse: exportfuse_end_request()
fuse: exportfuse_len_args()
fuse: exportfuse_get_unique()
fuse: extractfuse_fill_super_common()
fuse: addfuse_iqueue_opscallbacks
virtio_fs: add skeleton virtio_fs.ko moduleVivek Goyal (5):
fuse: Exportfuse_send_init_request()
Exportfuse_dequeue_forget()function
fuse: Separate fuse device allocation and installation infuse_conn
virtio-fs: Do not provide abort interface in fusectlinit/do_mounts.c: addvirtio_fsroot fs supportfs/fuse/Kconfig | 11 + fs/fuse/Makefile | 1 + fs/fuse/control.c | 4 +- fs/fuse/cuse.c | 4 +- fs/fuse/dev.c | 89 ++- fs/fuse/dir.c | 26 +- fs/fuse/file.c | 15 +- fs/fuse/fuse_i.h | 120 +++- fs/fuse/inode.c | 203 +++--- fs/fuse/virtio_fs.c | 1061 +++++++++++++++++++++++++++++++
Quoted 8 lines
Quoted 8 lines
fs/splice.c | 3 +- include/linux/fs.h | 2 + include/uapi/linux/virtio_fs.h | 41 ++ include/uapi/linux/virtio_ids.h | 1 + init/do_mounts.c | 10 + 15 files changed, 1462 insertions(+), 129 deletions(-) create mode 100644 fs/fuse/virtio_fs.c create mode 100644 include/uapi/linux/virtio_fs.h
Don't the new files need a MAINTAINERS entry?
I think we want [email protected] to be copied.
Quoted 4 lines
Quoted 4 lines
--
2.20.1
Miklos Szeredi
maintainerQuoted 3 lines · Michael S. Tsirkin
Can the patches themselves be posted to the relevant list(s) please? If possible, please also include "v3" in all patches so they are easier to find.
I'll post a v4.
Quoted 11 lines
I poked at
https://lwn.net/ml/linux-kernel/[email protected]/
specifically
https://lwn.net/ml/linux-kernel/[email protected]/
and things like:
+ /* TODO lock */
give me pause.Cleanup generally seems broken to me - what pauses the FS
What about the rest of TODOs in that file?
AFAICS, some of those are QOI issues, and some are long term performance items. I see no blockers or things that would pose a security concern.
That said, it would be nice to get rid of them at some point.
Quoted 2 lines
use of usleep is hacky - can't we do better e.g. with a completion?
Yes. I have a different implementation, but was planning to leave this one in until the dust settles.
Quoted 1 line
Some typos - e.g. "reuests".
Fixed.
Quoted 19 lines
Quoted 10 lines
Quoted 10 lines
fs/fuse/Kconfig | 11 + fs/fuse/Makefile | 1 + fs/fuse/control.c | 4 +- fs/fuse/cuse.c | 4 +- fs/fuse/dev.c | 89 ++- fs/fuse/dir.c | 26 +- fs/fuse/file.c | 15 +- fs/fuse/fuse_i.h | 120 +++- fs/fuse/inode.c | 203 +++--- fs/fuse/virtio_fs.c | 1061 +++++++++++++++++++++++++++++++Quoted 8 lines
Quoted 8 lines
fs/splice.c | 3 +- include/linux/fs.h | 2 + include/uapi/linux/virtio_fs.h | 41 ++ include/uapi/linux/virtio_ids.h | 1 + init/do_mounts.c | 10 + 15 files changed, 1462 insertions(+), 129 deletions(-) create mode 100644 fs/fuse/virtio_fs.c create mode 100644 include/uapi/linux/virtio_fs.h
Quoted 3 lines
Don't the new files need a
MAINTAINERSentry?
I think we want [email protected] to be copied.
Yep.
Stefan, do you want to formally maintain this file?
Thanks,
Miklos
Stefan Hajnoczi
maintainerQuoted 20 lines · Miklos Szeredi
Quoted 19 lines · Michael S. Tsirkin
Quoted 18 lines
Quoted 18 lines
fs/fuse/Kconfig | 11 + fs/fuse/Makefile | 1 + fs/fuse/control.c | 4 +- fs/fuse/cuse.c | 4 +- fs/fuse/dev.c | 89 ++- fs/fuse/dir.c | 26 +- fs/fuse/file.c | 15 +- fs/fuse/fuse_i.h | 120 +++- fs/fuse/inode.c | 203 +++--- fs/fuse/virtio_fs.c | 1061 +++++++++++++++++++++++++++++++ fs/splice.c | 3 +- include/linux/fs.h | 2 + include/uapi/linux/virtio_fs.h | 41 ++ include/uapi/linux/virtio_ids.h | 1 + init/do_mounts.c | 10 + 15 files changed, 1462 insertions(+), 129 deletions(-) create mode 100644 fs/fuse/virtio_fs.c create mode 100644 include/uapi/linux/virtio_fs.h
Quoted 7 lines
Quoted 3 lines
Don't the new files need a
MAINTAINERSentry?
I think we want [email protected] to be copied.Yep.
Stefan, do you want to formally maintain this file?
Vivek has been doing most of the kernel work lately and I would suggest that he acts as maintainer.
But I'm happy to be added if you want two people or if Vivek is unwilling.
Stefan
Stefan Hajnoczi
maintainerQuoted 20 lines · Miklos Szeredi
Quoted 19 lines · Michael S. Tsirkin
Quoted 18 lines
Quoted 18 lines
fs/fuse/Kconfig | 11 + fs/fuse/Makefile | 1 + fs/fuse/control.c | 4 +- fs/fuse/cuse.c | 4 +- fs/fuse/dev.c | 89 ++- fs/fuse/dir.c | 26 +- fs/fuse/file.c | 15 +- fs/fuse/fuse_i.h | 120 +++- fs/fuse/inode.c | 203 +++--- fs/fuse/virtio_fs.c | 1061 +++++++++++++++++++++++++++++++ fs/splice.c | 3 +- include/linux/fs.h | 2 + include/uapi/linux/virtio_fs.h | 41 ++ include/uapi/linux/virtio_ids.h | 1 + init/do_mounts.c | 10 + 15 files changed, 1462 insertions(+), 129 deletions(-) create mode 100644 fs/fuse/virtio_fs.c create mode 100644 include/uapi/linux/virtio_fs.h
Quoted 7 lines
Quoted 3 lines
Don't the new files need a
MAINTAINERSentry?
I think we want [email protected] to be copied.Yep.
Stefan, do you want to formally maintain this file?
Vivek has been doing most of the kernel work lately and I would suggest that he acts as maintainer.
But I'm happy to be added if you want two people or if Vivek is unwilling.
Stefan
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Vivek Goyal
maintainerOn Tue, Sep 03, 2019 at 04:31:38AM -0400, Michael S. Tsirkin wrote:
[..]
Quoted 4 lines
(quoted diff) +1
-0+ /* TODO lock */give me pause.
Cleanup generally seems broken to me - what pauses the FS
I am looking into device removal aspect of it now. Thinking of adding a reference count to virtiofs device and possibly also a bit flag to indicate if device is still alive. That way, we should be able to cleanup device more gracefully.
Quoted 2 lines
What about the rest of TODOs in that file?
I will also take a closer look at TODOs now. Better device cleanup path might get rid of some of them. Some of them might not be valid anymore.
Quoted 3 lines
use of usleep is hacky - can't we do better e.g. with a completion?
Agreed.
Thanks
Vivek
Michael S. Tsirkin
maintainerQuoted 6 lines · Vivek Goyal
On Tue, Sep 03, 2019 at 04:31:38AM -0400, Michael S. Tsirkin wrote:
[..]
Quoted 3 lines
(quoted diff) +1
-0+ /* TODO lock */give me pause.
Quoted 6 lines
Quoted 1 line
Cleanup generally seems broken to me - what pauses the FS
I am looking into device removal aspect of it now. Thinking of adding a reference count to virtiofs device and possibly also a bit flag to indicate if device is still alive. That way, we should be able to cleanup device more gracefully.
Generally, the way to cleanup things is to first disconnect device from linux so linux won't send new requests, wait for old ones to finish.
Quoted 14 lines
Quoted 2 lines
What about the rest of TODOs in that file?
I will also take a closer look at TODOs now. Better device cleanup path might get rid of some of them. Some of them might not be valid anymore.
Quoted 3 lines
use of usleep is hacky - can't we do better e.g. with a completion?
Agreed.
Thanks
Vivek
Vivek Goyal
maintainerQuoted 14 lines · Michael S. Tsirkin
Quoted 6 lines · Vivek Goyal
On Tue, Sep 03, 2019 at 04:31:38AM -0400, Michael S. Tsirkin wrote:
[..]
Quoted 3 lines
(quoted diff) +1
-0+ /* TODO lock */give me pause.
Quoted 6 lines
Quoted 1 line
Cleanup generally seems broken to me - what pauses the FS
I am looking into device removal aspect of it now. Thinking of adding a reference count to virtiofs device and possibly also a bit flag to indicate if device is still alive. That way, we should be able to cleanup device more gracefully.
Quoted 2 lines
Generally, the way to cleanup things is to first disconnect device from linux so linux won't send new requests, wait for old ones to finish.
I was thinking of following.
- Set a flag on device to indicate device is dead and not queue new requests. Device removal call can set this flag.
- Return errors when fs code tries to queue new request.
- Drop device creation reference in device removal path. If device is mounted at the time of removal, that reference will still be active and device state will not be cleaned up in kernel yet.
- User unmounts the fs, and that will drop last reference to device and will lead to cleanup of in kernel state of the device.
Does that sound reasonable.
Vivek
Michael S. Tsirkin
maintainerQuoted 29 lines · Vivek Goyal
Quoted 14 lines · Michael S. Tsirkin
Quoted 6 lines · Vivek Goyal
On Tue, Sep 03, 2019 at 04:31:38AM -0400, Michael S. Tsirkin wrote:
[..]
Quoted 3 lines
(quoted diff) +1
-0+ /* TODO lock */give me pause.
Quoted 6 lines
Quoted 1 line
Cleanup generally seems broken to me - what pauses the FS
I am looking into device removal aspect of it now. Thinking of adding a reference count to virtiofs device and possibly also a bit flag to indicate if device is still alive. That way, we should be able to cleanup device more gracefully.
Quoted 2 lines
Generally, the way to cleanup things is to first disconnect device from linux so linux won't send new requests, wait for old ones to finish.
I was thinking of following.
- Set a flag on device to indicate device is dead and not queue new requests. Device removal call can set this flag.
- Return errors when fs code tries to queue new request.
- Drop device creation reference in device removal path. If device is mounted at the time of removal, that reference will still be active and device state will not be cleaned up in kernel yet.
Quoted 6 lines
- User unmounts the fs, and that will drop last reference to device and will lead to cleanup of in kernel state of the device.
Does that sound reasonable.
Vivek
Just we aware of the fact that virtio device, all vqs etc will be gone by the time remove returns.
Signature · 1 line
MST
Michael S. Tsirkin
maintainerQuoted 29 lines · Vivek Goyal
Quoted 14 lines · Michael S. Tsirkin
Quoted 6 lines · Vivek Goyal
On Tue, Sep 03, 2019 at 04:31:38AM -0400, Michael S. Tsirkin wrote:
[..]
Quoted 3 lines
(quoted diff) +1
-0+ /* TODO lock */give me pause.
Quoted 6 lines
Quoted 1 line
Cleanup generally seems broken to me - what pauses the FS
I am looking into device removal aspect of it now. Thinking of adding a reference count to virtiofs device and possibly also a bit flag to indicate if device is still alive. That way, we should be able to cleanup device more gracefully.
Quoted 2 lines
Generally, the way to cleanup things is to first disconnect device from linux so linux won't send new requests, wait for old ones to finish.
I was thinking of following.
- Set a flag on device to indicate device is dead and not queue new requests. Device removal call can set this flag.
- Return errors when fs code tries to queue new request.
- Drop device creation reference in device removal path. If device is mounted at the time of removal, that reference will still be active and device state will not be cleaned up in kernel yet.
Quoted 6 lines
- User unmounts the fs, and that will drop last reference to device and will lead to cleanup of in kernel state of the device.
Does that sound reasonable.
Vivek
Just we aware of the fact that virtio device, all vqs etc will be gone by the time remove returns.
Signature · 1 line
MST
Vivek Goyal
maintainerQuoted 14 lines · Michael S. Tsirkin
Quoted 6 lines · Vivek Goyal
On Tue, Sep 03, 2019 at 04:31:38AM -0400, Michael S. Tsirkin wrote:
[..]
Quoted 3 lines
(quoted diff) +1
-0+ /* TODO lock */give me pause.
Quoted 6 lines
Quoted 1 line
Cleanup generally seems broken to me - what pauses the FS
I am looking into device removal aspect of it now. Thinking of adding a reference count to virtiofs device and possibly also a bit flag to indicate if device is still alive. That way, we should be able to cleanup device more gracefully.
Quoted 2 lines
Generally, the way to cleanup things is to first disconnect device from linux so linux won't send new requests, wait for old ones to finish.
I was thinking of following.
- Set a flag on device to indicate device is dead and not queue new requests. Device removal call can set this flag.
- Return errors when fs code tries to queue new request.
- Drop device creation reference in device removal path. If device is mounted at the time of removal, that reference will still be active and device state will not be cleaned up in kernel yet.
- User unmounts the fs, and that will drop last reference to device and will lead to cleanup of in kernel state of the device.
Does that sound reasonable.
Vivek
Michael S. Tsirkin
maintainerQuoted 6 lines · Vivek Goyal
On Tue, Sep 03, 2019 at 04:31:38AM -0400, Michael S. Tsirkin wrote:
[..]
Quoted 3 lines
(quoted diff) +1
-0+ /* TODO lock */give me pause.
Quoted 6 lines
Quoted 1 line
Cleanup generally seems broken to me - what pauses the FS
I am looking into device removal aspect of it now. Thinking of adding a reference count to virtiofs device and possibly also a bit flag to indicate if device is still alive. That way, we should be able to cleanup device more gracefully.
Generally, the way to cleanup things is to first disconnect device from linux so linux won't send new requests, wait for old ones to finish.
Quoted 14 lines
Quoted 2 lines
What about the rest of TODOs in that file?
I will also take a closer look at TODOs now. Better device cleanup path might get rid of some of them. Some of them might not be valid anymore.
Quoted 3 lines
use of usleep is hacky - can't we do better e.g. with a completion?
Agreed.
Thanks
Vivek
Vivek Goyal
maintainerOn Tue, Sep 03, 2019 at 04:31:38AM -0400, Michael S. Tsirkin wrote:
[..]
Quoted 4 lines
(quoted diff) +1
-0+ /* TODO lock */give me pause.
Cleanup generally seems broken to me - what pauses the FS
I am looking into device removal aspect of it now. Thinking of adding a reference count to virtiofs device and possibly also a bit flag to indicate if device is still alive. That way, we should be able to cleanup device more gracefully.
Quoted 2 lines
What about the rest of TODOs in that file?
I will also take a closer look at TODOs now. Better device cleanup path might get rid of some of them. Some of them might not be valid anymore.
Quoted 3 lines
use of usleep is hacky - can't we do better e.g. with a completion?
Agreed.
Thanks
Vivek
Michael S. Tsirkin
maintainerQuoted 7 lines · Miklos Szeredi
[Cc: [email protected], "Michael S. Tsirkin" <[email protected]>, Jason Wang <[email protected]>]
It'd be nice to have an ACK for this from the virtio maintainers.
Thanks,
Miklos
Can the patches themselves be posted to the relevant list(s) please? If possible, please also include "v3" in all patches so they are easier to find.
I poked at
https://lwn.net/ml/linux-kernel/[email protected]/
specifically
https://lwn.net/ml/linux-kernel/[email protected]/
and things like:
+ /* TODO lock */
give me pause.
Cleanup generally seems broken to me - what pauses the FS
What about the rest of TODOs in that file?
use of usleep is hacky - can't we do better e.g. with a completion?
Some typos - e.g. "reuests".
Quoted 294 lines · Vivek Goyal
Quoted 292 lines
Hi,
Here are the V3 patches for virtio-fs filesystem. This time I have broken the patch series in two parts. This is first part which does not contain DAX support. Second patch series will contain the patches for DAX support.
I have also dropped RFC tag from first patch series as we believe its in good enough shape that it should get a consideration for inclusion upstream.
These patches apply on top of 5.3-rc5 kernel and are also available here.
https://github.com/rhvgoyal/linux/commits/vivek-5.3-aug-21-2019
Patches for V1 and V2 were posted here.
https://lwn.net/ml/linux-fsdevel/[email protected]/
http://lkml.iu.edu/hypermail/linux/kernel/1905.1/07232.htmlMore information about the project can be found here.
Changes from V2
===============
- Various bug fixes and performance improvements.HOWTO
======
We have put instructions on how to use it here.Some Performance Numbers
========================
I have basically run bunch of fio jobs to get a sense of speed of various operations. I wrote a simple wrapper script to run fio jobs 3 times and take their average and report it. These scripts are available here.https://github.com/rhvgoyal/virtiofs-tests
I set up a directory on ramfs on host and exported that directory inside guest using virtio-9p and virtio-fs and ran tests inside guests. Ran tests with cache=none both for virtio-9p and virtio-fs so that no caching happens in guest. For virtio-fs, I ran an additional set of tests with dax enabled. Dax is not part of first patch series but I included results here because dax seems to get the maximum performance advantage and its shows the real potential of virtio-fs.
Test Setup
-----------
- A fedora 28 host with 32G RAM, 2 sockets (6 cores per socket, 2 threads per core)- Using ramfs on host as backing store. 4 fio files of 2G each.
- Created a VM with 16 VCPUS and 8GB memory. An 8GB cache window (for dax mmap).
Test Results
------------
- Results in three configurations have been reported. 9p (cache=none), virtio-fs (cache=none) and virtio-fs (cache=none + dax).There are other caching modes as well but to me cache=none seemed most interesting for now because it does not cache anything in guest and provides strong coherence. Other modes which provide less strong coherence and hence are faster are yet to be benchmarked.
- Three fio ioengines psync, libaio and mmap have been used.
- I/O Workload of randread, radwrite, seqread and seqwrite have been run.
- Each file size is 2G. Block size 4K. iodepth=16
- "multi" means same operation was done with 4 jobs and each job is operating on a file of size 2G.
- Some results are "0 (KiB/s)". That means that particular operation is not supported in that configuration.
NAME I/O Operation BW(Read/Write)
9p-cache-none seqread-psync 27(MiB/s) virtiofs-cache-none seqread-psync 35(MiB/s) virtiofs-dax-cache-none seqread-psync 245(MiB/s)9p-cache-none seqread-psync-multi 117(MiB/s) virtiofs-cache-none seqread-psync-multi 162(MiB/s) virtiofs-dax-cache-none seqread-psync-multi 894(MiB/s)9p-cache-none seqread-mmap 24(MiB/s) virtiofs-cache-none seqread-mmap 0(KiB/s) virtiofs-dax-cache-none seqread-mmap 168(MiB/s)9p-cache-none seqread-mmap-multi 115(MiB/s) virtiofs-cache-none seqread-mmap-multi 0(KiB/s) virtiofs-dax-cache-none seqread-mmap-multi 614(MiB/s)9p-cache-none seqread-libaio 26(MiB/s) virtiofs-cache-none seqread-libaio 139(MiB/s) virtiofs-dax-cache-none seqread-libaio 160(MiB/s)9p-cache-none seqread-libaio-multi 129(MiB/s) virtiofs-cache-none seqread-libaio-multi 142(MiB/s) virtiofs-dax-cache-none seqread-libaio-multi 577(MiB/s)9p-cache-none randread-psync 29(MiB/s) virtiofs-cache-none randread-psync 34(MiB/s) virtiofs-dax-cache-none randread-psync 256(MiB/s)9p-cache-none randread-psync-multi 139(MiB/s) virtiofs-cache-none randread-psync-multi 153(MiB/s) virtiofs-dax-cache-none randread-psync-multi 245(MiB/s)9p-cache-none randread-mmap 22(MiB/s) virtiofs-cache-none randread-mmap 0(KiB/s) virtiofs-dax-cache-none randread-mmap 162(MiB/s)9p-cache-none randread-mmap-multi 111(MiB/s) virtiofs-cache-none randread-mmap-multi 0(KiB/s) virtiofs-dax-cache-none randread-mmap-multi 215(MiB/s)9p-cache-none randread-libaio 26(MiB/s) virtiofs-cache-none randread-libaio 135(MiB/s) virtiofs-dax-cache-none randread-libaio 157(MiB/s)9p-cache-none randread-libaio-multi 133(MiB/s) virtiofs-cache-none randread-libaio-multi 245(MiB/s) virtiofs-dax-cache-none randread-libaio-multi 163(MiB/s)9p-cache-none seqwrite-psync 28(MiB/s) virtiofs-cache-none seqwrite-psync 34(MiB/s) virtiofs-dax-cache-none seqwrite-psync 203(MiB/s)9p-cache-none seqwrite-psync-multi 128(MiB/s) virtiofs-cache-none seqwrite-psync-multi 155(MiB/s) virtiofs-dax-cache-none seqwrite-psync-multi 717(MiB/s)9p-cache-none seqwrite-mmap 0(KiB/s) virtiofs-cache-none seqwrite-mmap 0(KiB/s) virtiofs-dax-cache-none seqwrite-mmap 165(MiB/s)9p-cache-none seqwrite-mmap-multi 0(KiB/s) virtiofs-cache-none seqwrite-mmap-multi 0(KiB/s) virtiofs-dax-cache-none seqwrite-mmap-multi 511(MiB/s)9p-cache-none seqwrite-libaio 27(MiB/s) virtiofs-cache-none seqwrite-libaio 128(MiB/s) virtiofs-dax-cache-none seqwrite-libaio 141(MiB/s)9p-cache-none seqwrite-libaio-multi 119(MiB/s) virtiofs-cache-none seqwrite-libaio-multi 242(MiB/s) virtiofs-dax-cache-none seqwrite-libaio-multi 505(MiB/s)9p-cache-none randwrite-psync 27(MiB/s) virtiofs-cache-none randwrite-psync 34(MiB/s) virtiofs-dax-cache-none randwrite-psync 189(MiB/s)9p-cache-none randwrite-psync-multi 137(MiB/s) virtiofs-cache-none randwrite-psync-multi 150(MiB/s) virtiofs-dax-cache-none randwrite-psync-multi 233(MiB/s)9p-cache-none randwrite-mmap 0(KiB/s) virtiofs-cache-none randwrite-mmap 0(KiB/s) virtiofs-dax-cache-none randwrite-mmap 120(MiB/s)9p-cache-none randwrite-mmap-multi 0(KiB/s) virtiofs-cache-none randwrite-mmap-multi 0(KiB/s) virtiofs-dax-cache-none randwrite-mmap-multi 200(MiB/s)9p-cache-none randwrite-libaio 25(MiB/s) virtiofs-cache-none randwrite-libaio 124(MiB/s) virtiofs-dax-cache-none randwrite-libaio 131(MiB/s)9p-cache-none randwrite-libaio-multi 125(MiB/s) virtiofs-cache-none randwrite-libaio-multi 241(MiB/s) virtiofs-dax-cache-none randwrite-libaio-multi 163(MiB/s)Conclusions
===========
- In general virtio-fs seems faster than virtio-9p. Using dax makes it really interesting.Note:
Right now dax window is 8G and max fio file size is 8G as well (4 files of 2G each). That means everything fits into dax window and no reclaim is needed. Dax window reclaim logic is slower and if file size is bigger than dax window size, performance slows down.Description from previous postings
==================================Design Overview
===============
With the goal of designing something with better performance and local file system semantics, a bunch of ideas were proposed.- Use fuse protocol (instead of 9p) for communication between guest and host. Guest kernel will be fuse client and a fuse server will run on host to serve the requests.
- For data access inside guest, mmap portion of file in QEMU address space and guest accesses this memory using dax. That way guest page cache is bypassed and there is only one copy of data (on host). This will also enable
mmap(MAP_SHARED)between guests.- For metadata coherency, there is a shared memory region which contains version number associated with metadata and any guest changing metadata updates version number and other guests refresh metadata on next access. This is yet to be implemented.
How virtio-fs differs from existing approaches
==============================================
The unique idea behind virtio-fs is to take advantage of the co-location of the virtual machine and hypervisor to avoid communication (vmexits).DAX allows file contents to be accessed without communication with the hypervisor. The shared memory region for metadata avoids communication in the common case where metadata is unchanged.
By replacing expensive communication with cheaper shared memory accesses, we expect to achieve better performance than approaches based on network file system protocols. In addition, this also makes it easier to achieve local file system semantics (coherency).
These techniques are not applicable to network file system protocols since the communications channel is bypassed by taking advantage of shared memory on a local machine. This is why we decided to build virtio-fs rather than focus on 9P or NFS.
Caching Modes
=============
Like virtio-9p, different caching modes are supported which determine the coherency level as well. The “cache=FOO” and “writeback” options control the level of coherence between the guest and host filesystems.- cache=none
metadata, data and pathname lookup are not cached in guest. They are always fetched from host and any changes are immediately pushed to host.- cache=always
metadata, data and pathname lookup are cached in guest and never expire.- cache=auto
metadata and pathname lookup cache expires after a configured amount of time (default is 1 second). Data is cached while the file is open (close to open consistency).- writeback/no_writeback
These options control the writeback strategy. If writeback is disabled, then normal writes will immediately be synchronized with the host fs. If writeback is enabled, then writes may be cached in the guest until the file is closed or an fsync(2) performed. This option has no effect on mmap-ed writes or writes going through the DAX mechanism.Thanks
VivekMiklos Szeredi (2):
fuse: delete dentry if timeout is zero
fuse: Usedefault_file_splice_readfor direct IOStefan Hajnoczi (6):
fuse: exportfuse_end_request()
fuse: exportfuse_len_args()
fuse: exportfuse_get_unique()
fuse: extractfuse_fill_super_common()
fuse: addfuse_iqueue_opscallbacks
virtio_fs: add skeleton virtio_fs.ko moduleVivek Goyal (5):
fuse: Exportfuse_send_init_request()
Exportfuse_dequeue_forget()function
fuse: Separate fuse device allocation and installation infuse_conn
virtio-fs: Do not provide abort interface in fusectlinit/do_mounts.c: addvirtio_fsroot fs supportfs/fuse/Kconfig | 11 + fs/fuse/Makefile | 1 + fs/fuse/control.c | 4 +- fs/fuse/cuse.c | 4 +- fs/fuse/dev.c | 89 ++- fs/fuse/dir.c | 26 +- fs/fuse/file.c | 15 +- fs/fuse/fuse_i.h | 120 +++- fs/fuse/inode.c | 203 +++--- fs/fuse/virtio_fs.c | 1061 +++++++++++++++++++++++++++++++
Quoted 8 lines
Quoted 8 lines
fs/splice.c | 3 +- include/linux/fs.h | 2 + include/uapi/linux/virtio_fs.h | 41 ++ include/uapi/linux/virtio_ids.h | 1 + init/do_mounts.c | 10 + 15 files changed, 1462 insertions(+), 129 deletions(-) create mode 100644 fs/fuse/virtio_fs.c create mode 100644 include/uapi/linux/virtio_fs.h
Don't the new files need a MAINTAINERS entry?
I think we want [email protected] to be copied.
Quoted 4 lines
Quoted 4 lines
--
2.20.1
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization