Message ID | 20181210171318.16998-23-vgoyal@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | virtio-fs: shared file system for virtual machines | expand |
Hi Vivek, I love your patch! Perhaps something to improve: [auto build test WARNING on fuse/for-next] [also build test WARNING on v4.20-rc6] [cannot apply to next-20181210] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Vivek-Goyal/virtio-fs-shared-file-system-for-virtual-machines/20181211-103034 base: https://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git for-next config: arm-allmodconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=arm All warnings (new ones prefixed by >>): In file included from include/linux/kernel.h:14:0, from include/linux/list.h:9, from include/linux/wait.h:7, from include/linux/wait_bit.h:8, from include/linux/fs.h:6, from fs/fuse/virtio_fs.c:7: fs/fuse/virtio_fs.c: In function 'virtio_fs_direct_access': >> fs/fuse/virtio_fs.c:454:11: warning: format '%ld' expects argument of type 'long int', but argument 4 has type 'size_t {aka unsigned int}' [-Wformat=] pr_debug("virtio_fs_direct_access(): called. nr_pages=%ld max_nr_pages=%ld\n", nr_pages, max_nr_pages); ^ include/linux/printk.h:292:21: note: in definition of macro 'pr_fmt' #define pr_fmt(fmt) fmt ^~~ include/linux/printk.h:340:2: note: in expansion of macro 'dynamic_pr_debug' dynamic_pr_debug(fmt, ##__VA_ARGS__) ^~~~~~~~~~~~~~~~ >> fs/fuse/virtio_fs.c:454:2: note: in expansion of macro 'pr_debug' pr_debug("virtio_fs_direct_access(): called. nr_pages=%ld max_nr_pages=%ld\n", nr_pages, max_nr_pages); ^~~~~~~~ In file included from include/linux/printk.h:336:0, from include/linux/kernel.h:14, from include/linux/list.h:9, from include/linux/wait.h:7, from include/linux/wait_bit.h:8, from include/linux/fs.h:6, from fs/fuse/virtio_fs.c:7: fs/fuse/virtio_fs.c: In function 'virtio_fs_setup_dax': fs/fuse/virtio_fs.c:617:22: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 6 has type 'phys_addr_t {aka unsigned int}' [-Wformat=] dev_dbg(&vdev->dev, "%s: cache kaddr 0x%px phys_addr 0x%llx len %llx\n", ^ include/linux/dynamic_debug.h:135:39: note: in definition of macro 'dynamic_dev_dbg' __dynamic_dev_dbg(&descriptor, dev, fmt, \ ^~~ include/linux/device.h:1463:23: note: in expansion of macro 'dev_fmt' dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__) ^~~~~~~ fs/fuse/virtio_fs.c:617:2: note: in expansion of macro 'dev_dbg' dev_dbg(&vdev->dev, "%s: cache kaddr 0x%px phys_addr 0x%llx len %llx\n", ^~~~~~~ vim +454 fs/fuse/virtio_fs.c 442 443 /* Map a window offset to a page frame number. The window offset will have 444 * been produced by .iomap_begin(), which maps a file offset to a window 445 * offset. 446 */ 447 static long virtio_fs_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, 448 long nr_pages, void **kaddr, pfn_t *pfn) 449 { 450 struct virtio_fs *fs = dax_get_private(dax_dev); 451 phys_addr_t offset = PFN_PHYS(pgoff); 452 size_t max_nr_pages = fs->window_len/PAGE_SIZE - pgoff; 453 > 454 pr_debug("virtio_fs_direct_access(): called. nr_pages=%ld max_nr_pages=%ld\n", nr_pages, max_nr_pages); 455 456 if (kaddr) 457 *kaddr = fs->window_kaddr + offset; 458 if (pfn) 459 *pfn = phys_to_pfn_t(fs->window_phys_addr + offset, 460 PFN_DEV | PFN_MAP); 461 return nr_pages > max_nr_pages ? max_nr_pages : nr_pages; 462 } 463 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Vivek, I love your patch! Yet something to improve: [auto build test ERROR on fuse/for-next] [also build test ERROR on v4.20-rc6] [cannot apply to next-20181214] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Vivek-Goyal/virtio-fs-shared-file-system-for-virtual-machines/20181211-103034 base: https://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git for-next config: nds32-defconfig (attached as .config) compiler: nds32le-linux-gcc (GCC) 6.4.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=6.4.0 make.cross ARCH=nds32 All errors (new ones prefixed by >>): fs/fuse/inode.o: In function `fuse_fill_super_common': >> inode.c:(.text+0x1c00): undefined reference to `dax_read_lock' inode.c:(.text+0x1c04): undefined reference to `dax_read_lock' >> inode.c:(.text+0x1c22): undefined reference to `dax_direct_access' inode.c:(.text+0x1c26): undefined reference to `dax_direct_access' >> inode.c:(.text+0x1c32): undefined reference to `dax_read_unlock' inode.c:(.text+0x1c36): undefined reference to `dax_read_unlock' --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index b9880be690bd..f0775d76e31f 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -46,6 +46,10 @@ /** Number of page pointers embedded in fuse_req */ #define FUSE_REQ_INLINE_PAGES 1 +/* Default memory range size, 2MB */ +#define FUSE_DAX_MEM_RANGE_SZ (2*1024*1024) +#define FUSE_DAX_MEM_RANGE_PAGES (FUSE_DAX_MEM_RANGE_SZ/PAGE_SIZE) + /** List of active connections */ extern struct list_head fuse_conn_list; @@ -83,6 +87,9 @@ struct fuse_forget_link { /** Translation information for file offsets to DAX window offsets */ struct fuse_dax_mapping { + /* Will connect in fc->free_ranges to keep track of free memory */ + struct list_head list; + /** Position in DAX window */ u64 window_offset; @@ -816,6 +823,13 @@ struct fuse_conn { /** DAX device, non-NULL if DAX is supported */ struct dax_device *dax_dev; + + /* + * DAX Window Free Ranges. TODO: This might not be best place to store + * this free list + */ + unsigned long nr_free_ranges; + struct list_head free_ranges; }; static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index d2afce377fd4..403360e352d8 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -22,6 +22,8 @@ #include <linux/exportfs.h> #include <linux/posix_acl.h> #include <linux/pid_namespace.h> +#include <linux/dax.h> +#include <linux/pfn_t.h> MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); MODULE_DESCRIPTION("Filesystem in Userspace"); @@ -607,6 +609,69 @@ static void fuse_pqueue_init(struct fuse_pqueue *fpq) fpq->connected = 1; } +static void fuse_free_dax_mem_ranges(struct list_head *mem_list) +{ + struct fuse_dax_mapping *range, *temp; + + /* Free All allocated elements */ + list_for_each_entry_safe(range, temp, mem_list, list) { + list_del(&range->list); + kfree(range); + } +} + +static int fuse_dax_mem_range_init(struct fuse_conn *fc, + struct dax_device *dax_dev) +{ + long nr_pages, nr_ranges; + void *kaddr; + pfn_t pfn; + struct fuse_dax_mapping *range; + LIST_HEAD(mem_ranges); + phys_addr_t phys_addr; + int ret = 0, id; + size_t dax_size = -1; + unsigned long allocated_ranges = 0, i; + + id = dax_read_lock(); + nr_pages = dax_direct_access(dax_dev, 0, PHYS_PFN(dax_size), &kaddr, + &pfn); + dax_read_unlock(id); + if (nr_pages < 0) { + pr_debug("dax_direct_access() returned %ld\n", nr_pages); + return nr_pages; + } + + phys_addr = pfn_t_to_phys(pfn); + nr_ranges = nr_pages/FUSE_DAX_MEM_RANGE_PAGES; + printk("fuse_dax_mem_range_init(): dax mapped %ld pages. nr_ranges=%ld\n", nr_pages, nr_ranges); + + for (i = 0; i < nr_ranges; i++) { + range = kzalloc(sizeof(struct fuse_dax_mapping), GFP_KERNEL); + if (!range) { + pr_debug("memory allocation for mem_range failed.\n"); + ret = -ENOMEM; + goto out_err; + } + /* TODO: This offset only works if virtio-fs driver is not + * having some memory hidden at the beginning. This needs + * better handling + */ + range->window_offset = i * FUSE_DAX_MEM_RANGE_SZ; + range->length = FUSE_DAX_MEM_RANGE_SZ; + list_add_tail(&range->list, &mem_ranges); + allocated_ranges++; + } + + list_replace_init(&mem_ranges, &fc->free_ranges); + fc->nr_free_ranges = allocated_ranges; + return 0; +out_err: + /* Free All allocated elements */ + fuse_free_dax_mem_ranges(&mem_ranges); + return ret; +} + void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns, struct dax_device *dax_dev, const struct fuse_iqueue_ops *fiq_ops, void *fiq_priv) @@ -636,6 +701,7 @@ void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns, fc->pid_ns = get_pid_ns(task_active_pid_ns(current)); fc->dax_dev = dax_dev; fc->user_ns = get_user_ns(user_ns); + INIT_LIST_HEAD(&fc->free_ranges); } EXPORT_SYMBOL_GPL(fuse_conn_init); @@ -644,6 +710,8 @@ void fuse_conn_put(struct fuse_conn *fc) if (refcount_dec_and_test(&fc->count)) { if (fc->destroy_req) fuse_request_free(fc->destroy_req); + if (fc->dax_dev) + fuse_free_dax_mem_ranges(&fc->free_ranges); put_pid_ns(fc->pid_ns); put_user_ns(fc->user_ns); fc->release(fc); @@ -1136,9 +1204,17 @@ int fuse_fill_super_common(struct super_block *sb, fuse_conn_init(fc, sb->s_user_ns, dax_dev, fiq_ops, fiq_priv); fc->release = fuse_free_conn; + if (dax_dev) { + err = fuse_dax_mem_range_init(fc, dax_dev); + if (err) { + pr_debug("fuse_dax_mem_range_init() returned %d\n", err); + goto err_put_conn; + } + } + fud = fuse_dev_alloc(fc); if (!fud) - goto err_put_conn; + goto err_free_ranges; fc->dev = sb->s_dev; fc->sb = sb; @@ -1211,6 +1287,9 @@ int fuse_fill_super_common(struct super_block *sb, dput(root_dentry); err_dev_free: fuse_dev_free(fud); + err_free_ranges: + if (dax_dev) + fuse_free_dax_mem_ranges(&fc->free_ranges); err_put_conn: fuse_conn_put(fc); sb->s_fs_info = NULL; diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index ef1469b38a6d..c79c9a885253 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -451,6 +451,8 @@ static long virtio_fs_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, phys_addr_t offset = PFN_PHYS(pgoff); size_t max_nr_pages = fs->window_len/PAGE_SIZE - pgoff; + pr_debug("virtio_fs_direct_access(): called. nr_pages=%ld max_nr_pages=%ld\n", nr_pages, max_nr_pages); + if (kaddr) *kaddr = fs->window_kaddr + offset; if (pfn)
Divide the dax memory range into fixed size ranges (2MB for now) and put them in a list. This will track free ranges. Once an inode requires a free range, we will take one from here and put it in interval-tree of ranges assigned to inode. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> --- fs/fuse/fuse_i.h | 14 +++++++++ fs/fuse/inode.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++- fs/fuse/virtio_fs.c | 2 ++ 3 files changed, 96 insertions(+), 1 deletion(-)