Date: Mon, 18 Sep 2017 13:17:23 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r323703 - in head/sys/compat/linuxkpi/common: include/linux src Message-ID: <201709181317.v8IDHNiT052409@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Mon Sep 18 13:17:23 2017 New Revision: 323703 URL: https://svnweb.freebsd.org/changeset/base/323703 Log: Add support for shared memory functions to the LinuxKPI. Obtained from: kmacy @ MFC after: 1 week Sponsored by: Mellanox Technologies Modified: head/sys/compat/linuxkpi/common/include/linux/fs.h head/sys/compat/linuxkpi/common/src/linux_page.c Modified: head/sys/compat/linuxkpi/common/include/linux/fs.h ============================================================================== --- head/sys/compat/linuxkpi/common/include/linux/fs.h Mon Sep 18 08:46:07 2017 (r323702) +++ head/sys/compat/linuxkpi/common/include/linux/fs.h Mon Sep 18 13:17:23 2017 (r323703) @@ -2,7 +2,7 @@ * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. - * Copyright (c) 2013-2016 Mellanox Technologies, Ltd. + * Copyright (c) 2013-2017 Mellanox Technologies, Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -287,5 +287,26 @@ noop_llseek(struct linux_file *file, loff_t offset, in return (file->_file->f_offset); } + +/* Shared memory support */ +unsigned long linux_invalidate_mapping_pages(vm_object_t, pgoff_t, pgoff_t); +struct page *linux_shmem_read_mapping_page_gfp(vm_object_t, int, gfp_t); +struct linux_file *linux_shmem_file_setup(const char *, loff_t, unsigned long); +void linux_shmem_truncate_range(vm_object_t, loff_t, loff_t); + +#define invalidate_mapping_pages(...) \ + linux_invalidate_mapping_pages(__VA_ARGS__) + +#define shmem_read_mapping_page(...) \ + linux_shmem_read_mapping_page_gfp(__VA_ARGS__, 0) + +#define shmem_read_mapping_page_gfp(...) \ + linux_shmem_read_mapping_page_gfp(__VA_ARGS__) + +#define shmem_file_setup(...) \ + linux_shmem_file_setup(__VA_ARGS__) + +#define shmem_truncate_range(...) \ + linux_shmem_truncate_range(__VA_ARGS__) #endif /* _LINUX_FS_H_ */ Modified: head/sys/compat/linuxkpi/common/src/linux_page.c ============================================================================== --- head/sys/compat/linuxkpi/common/src/linux_page.c Mon Sep 18 08:46:07 2017 (r323702) +++ head/sys/compat/linuxkpi/common/src/linux_page.c Mon Sep 18 13:17:23 2017 (r323703) @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include <linux/gfp.h> #include <linux/mm.h> #include <linux/preempt.h> +#include <linux/fs.h> #if defined(__amd64__) || defined(__aarch64__) || defined(__riscv) #define LINUXKPI_HAVE_DMAP @@ -288,4 +289,108 @@ int is_vmalloc_addr(const void *addr) { return (vtoslab((vm_offset_t)addr & ~UMA_SLAB_MASK) != NULL); +} + +struct page * +linux_shmem_read_mapping_page_gfp(vm_object_t obj, int pindex, gfp_t gfp) +{ + vm_page_t page; + int rv; + + if ((gfp & GFP_NOWAIT) != 0) + panic("GFP_NOWAIT is unimplemented"); + + VM_OBJECT_WLOCK(obj); + page = vm_page_grab(obj, pindex, VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY | + VM_ALLOC_WIRED); + if (page->valid != VM_PAGE_BITS_ALL) { + vm_page_xbusy(page); + if (vm_pager_has_page(obj, pindex, NULL, NULL)) { + rv = vm_pager_get_pages(obj, &page, 1, NULL, NULL); + if (rv != VM_PAGER_OK) { + vm_page_lock(page); + vm_page_unwire(page, PQ_NONE); + vm_page_free(page); + vm_page_unlock(page); + VM_OBJECT_WUNLOCK(obj); + return (ERR_PTR(-EINVAL)); + } + MPASS(page->valid == VM_PAGE_BITS_ALL); + } else { + pmap_zero_page(page); + page->valid = VM_PAGE_BITS_ALL; + page->dirty = 0; + } + vm_page_xunbusy(page); + } + vm_page_lock(page); + vm_page_hold(page); + vm_page_unlock(page); + VM_OBJECT_WUNLOCK(obj); + return (page); +} + +struct linux_file * +linux_shmem_file_setup(const char *name, loff_t size, unsigned long flags) +{ + struct fileobj { + struct linux_file file __aligned(sizeof(void *)); + struct vnode vnode __aligned(sizeof(void *)); + }; + struct fileobj *fileobj; + struct linux_file *filp; + struct vnode *vp; + int error; + + fileobj = kzalloc(sizeof(*fileobj), GFP_KERNEL); + if (fileobj == NULL) { + error = -ENOMEM; + goto err_0; + } + filp = &fileobj->file; + vp = &fileobj->vnode; + + filp->f_count = 1; + filp->f_vnode = vp; + filp->f_shmem = vm_pager_allocate(OBJT_DEFAULT, NULL, size, + VM_PROT_READ | VM_PROT_WRITE, 0, curthread->td_ucred); + if (filp->f_shmem == NULL) { + error = -ENOMEM; + goto err_1; + } + return (filp); +err_1: + kfree(filp); +err_0: + return (ERR_PTR(error)); +} + +static vm_ooffset_t +linux_invalidate_mapping_pages_sub(vm_object_t obj, vm_pindex_t start, + vm_pindex_t end, int flags) +{ + int start_count, end_count; + + VM_OBJECT_WLOCK(obj); + start_count = obj->resident_page_count; + vm_object_page_remove(obj, start, end, flags); + end_count = obj->resident_page_count; + VM_OBJECT_WUNLOCK(obj); + return (start_count - end_count); +} + +unsigned long +linux_invalidate_mapping_pages(vm_object_t obj, pgoff_t start, pgoff_t end) +{ + + return (linux_invalidate_mapping_pages_sub(obj, start, end, OBJPR_CLEANONLY)); +} + +void +linux_shmem_truncate_range(vm_object_t obj, loff_t lstart, loff_t lend) +{ + vm_pindex_t start = OFF_TO_IDX(lstart + PAGE_SIZE - 1); + vm_pindex_t end = OFF_TO_IDX(lend + 1); + + (void) linux_invalidate_mapping_pages_sub(obj, start, end, 0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201709181317.v8IDHNiT052409>