diff --git a/cray-xpmem.pc.in b/cray-xpmem.pc.in index d634f17..70ce504 100644 --- a/cray-xpmem.pc.in +++ b/cray-xpmem.pc.in @@ -1,12 +1,8 @@ - +prefix=@prefix@ +exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ -default_bindir=@default_bindir@ -default_fomdir=@default_fomdir@ -default_prefix=@default_prefix@ -default_shlibdir=@default_shlibdir@ - Cflags: -I${includedir} Description: XPMEM Libs: -L${libdir} -lxpmem diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 0000000..6a4066d --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,9 @@ +*.debhelper.log +*.substvars +.debhelper/ +autoreconf.* +debhelper-build-stamp +files +libxpmem0/ +libxpmem-dev/ +tmp/ diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..0794c7a --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +xpmem-lib (2.6.4.0.20221220-1) unstable; urgency=medium + + * Initial release. + + -- Tzafrir Cohen Mon, 13 Feb 2023 17:50:36 +0200 diff --git a/debian/clean b/debian/clean new file mode 100644 index 0000000..d7606b8 --- /dev/null +++ b/debian/clean @@ -0,0 +1,3 @@ +kernel/Kbuild +kernel/Makefile +kernel/xpmem diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..328803b --- /dev/null +++ b/debian/control @@ -0,0 +1,30 @@ +Source: xpmem-lib +Priority: optional +Maintainer: Tzafrir Cohen +Build-Depends: debhelper-compat (= 11) +Standards-Version: 4.4.1 +Section: libs +Homepage: https://github.com/openucx/xpmem/ +#Vcs-Browser: https://salsa.debian.org/debian/xpmem-lib +#Vcs-Git: https://salsa.debian.org/debian/xpmem-lib.git + +Package: libxpmem-dev +Section: libdevel +Architecture: any +Multi-Arch: same +Depends: libxpmem0 (= ${binary:Version}), ${misc:Depends} +Description: libxpmem - development headers + XPMEM is a Linux kernel module that enables a process to map the + memory of another process into its virtual address space. + . + This package includes development headers for the userspace library. + +Package: libxpmem0 +Architecture: any +Multi-Arch: same +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: libxpmem - userspace library of XPMEM + XPMEM is a Linux kernel module that enables a process to map the + memory of another process into its virtual address space. + . + This package includes the userspace library. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..a3b2a75 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,31 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: xpmem +Source: https://github.com/openucx/xpmem/ + +Files: * +Copyright: 2004-2007, Silicon Graphics, Inc. + 2010, 2012, Cray Inc. + 2014-2017, Los Alamos National Security, LLC. All rights + 2017-2020, ARM, Inc. + 2019, Google, LLC. + 2019, Nathan Hjelm. +License: GPL-2 + This file is subject to the terms and conditions of the GNU General Public + License. See the file "COPYING" in the main directory of this archive + for more details. + . + On Debian systems you can find a copy of the GNU General Public License + version 2 at /usr/share/common-licenses/GPL-2 . + +Files: lib/* include/* +Copyright: + 2004-2007, Silicon Graphics, Inc. + 2009 Cray, Inc. + 2016 Nathan Hjelm +License: LGPL-2.1 + This file is subject to the terms and conditions of the GNU Lesser General Public + License. See the file "COPYING.LESSER" in the main directory of this archive + for more details. + . + On Debian systems you can find a copy of the GNU General Public License + version 2 at /usr/share/common-licenses/LGPL-2.1 . diff --git a/debian/libxpmem-dev.install b/debian/libxpmem-dev.install new file mode 100644 index 0000000..5d16539 --- /dev/null +++ b/debian/libxpmem-dev.install @@ -0,0 +1,3 @@ +usr/include/* +usr/lib/*/libxpmem*.so +usr/lib/*/pkgconfig/cray-xpmem.pc diff --git a/debian/libxpmem0.install b/debian/libxpmem0.install new file mode 100644 index 0000000..2d3647a --- /dev/null +++ b/debian/libxpmem0.install @@ -0,0 +1 @@ +usr/lib/*/libxpmem*.so.* diff --git a/debian/libxpmem0.symbols b/debian/libxpmem0.symbols new file mode 100644 index 0000000..375b824 --- /dev/null +++ b/debian/libxpmem0.symbols @@ -0,0 +1,10 @@ +libxpmem.so.0 libxpmem0 #MINVER# + xpmem_attach@Base 2.6.4.0.20221220 + xpmem_detach@Base 2.6.4.0.20221220 + xpmem_get@Base 2.6.4.0.20221220 + xpmem_init@Base 2.6.4.0.20221220 + xpmem_ioctl@Base 2.6.4.0.20221220 + xpmem_make@Base 2.6.4.0.20221220 + xpmem_release@Base 2.6.4.0.20221220 + xpmem_remove@Base 2.6.4.0.20221220 + xpmem_version@Base 2.6.4.0.20221220 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..3bee7bf --- /dev/null +++ b/debian/rules @@ -0,0 +1,26 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + + +# see FEATURE AREAS in dpkg-buildflags(1) +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# see ENVIRONMENT in dpkg-buildflags(1) +# package maintainers to append CFLAGS +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# package maintainers to append LDFLAGS +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + + +%: + dh $@ + +# Skip cleaning in the kernel/ that is part of the dist set. +# We delete some files from there using debian/clean as well. +override_dh_auto_clean: + dh_auto_clean -- DIST_SUBDIRS='$$(SUBDIRS)' + +override_dh_auto_configure: + dh_auto_configure -- --disable-kernel-module diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/upstream/metadata b/debian/upstream/metadata new file mode 100644 index 0000000..c469144 --- /dev/null +++ b/debian/upstream/metadata @@ -0,0 +1,3 @@ +Repository: https://github.com/openucx/xpmem.git +Repository-Browse: https://github.com/openucx/xpmem/ +Bug-Database: https://github.com/openucx/xpmem/issues diff --git a/kernel/xpmem_attach.c b/kernel/xpmem_attach.c index 69e7ae5..0070c8f 100644 --- a/kernel/xpmem_attach.c +++ b/kernel/xpmem_attach.c @@ -494,18 +494,18 @@ xpmem_attach(struct file *file, xpmem_apid_t apid, off_t offset, size_t size, /* check if a segment is already attached in the requested area */ if (flags & MAP_FIXED) { struct vm_area_struct *existing_vma; + struct vma_iterator vmi; - xpmem_mmap_write_lock(current->mm); - existing_vma = find_vma_intersection(current->mm, vaddr, - vaddr + size); - xpmem_mmap_write_unlock(current->mm); - for ( ; existing_vma && existing_vma->vm_start < vaddr + size - ; existing_vma = existing_vma->vm_next) { + xpmem_mmap_read_lock(current->mm); + vma_iter_init(&vmi, current->mm, vaddr); + for_each_vma_range(vmi, existing_vma, vaddr + size) { if (xpmem_is_vm_ops_set(existing_vma)) { + xpmem_mmap_read_unlock(current->mm); ret = -EINVAL; goto out_3; } } + xpmem_mmap_read_unlock(current->mm); } at_vaddr = vm_mmap(file, vaddr, size, prot_flags, flags, offset); diff --git a/kernel/xpmem_mmu_notifier.c b/kernel/xpmem_mmu_notifier.c index 4bb8b83..08ee47c 100644 --- a/kernel/xpmem_mmu_notifier.c +++ b/kernel/xpmem_mmu_notifier.c @@ -78,8 +78,10 @@ xpmem_invalidate_range(struct mmu_notifier *mn, unsigned long start = mnr->start; unsigned long end = mnr->end; #endif + unsigned long curr = start; struct xpmem_thread_group *seg_tg; struct vm_area_struct *vma; + struct vma_iterator vmi; seg_tg = container_of(mn, struct xpmem_thread_group, mmu_not); @@ -99,22 +101,14 @@ xpmem_invalidate_range(struct mmu_notifier *mn, if (offset_in_page(end) != 0) end += PAGE_SIZE - offset_in_page(end); - /* NTH: Changes to the tlb code should have removed the need for gathering * the mmu here. There is not any state that needs to be restored */ - vma = find_vma_intersection(mm, start, end); - if (vma == NULL) { - xpmem_invalidate_PTEs_range(seg_tg, start, end); - return; - } - - for ( ; vma && vma->vm_start < end; vma = vma->vm_next) { - unsigned long vm_start; + vma_iter_init(&vmi, mm, start); + for_each_vma_range(vmi, vma, end) { unsigned long vm_end; - /* - * If the vma is XPMEM-attached memory, bail out. XPMEM handles + /* Skip XPMEM-attached memory. XPMEM handles * this case outside of the MMU notifier functions and we don't * want xpmem_invalidate_range() to perform the operations a * second time and screw up page counts, etc. We can't block in @@ -123,19 +117,19 @@ xpmem_invalidate_range(struct mmu_notifier *mn, * kernel can't rearrange the address space while a MMU notifier * callout is occurring. */ - if (xpmem_is_vm_ops_set(vma)) + if (!xpmem_is_vm_ops_set(vma)) continue; - vm_start = max(vma->vm_start, start); - if (vm_start >= vma->vm_end) - continue; - - vm_end = min(vma->vm_end, end); - if (vm_end <= vma->vm_start) - continue; - - xpmem_invalidate_PTEs_range(seg_tg, vm_start, vm_end); + /* If found an xpmem-attached VMA, invalidate the range + * before its start and position 'curr' after its end */ + vm_end = min(vma->vm_start, end); + if (curr < vm_end) + xpmem_invalidate_PTEs_range(seg_tg, curr, vm_end); + curr = min(vma->vm_end, end); } + + if (curr < end) + xpmem_invalidate_PTEs_range(seg_tg, curr, end); } #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) diff --git a/kernel/xpmem_pfn.c b/kernel/xpmem_pfn.c index ae48506..7766c3b 100644 --- a/kernel/xpmem_pfn.c +++ b/kernel/xpmem_pfn.c @@ -29,8 +29,12 @@ #define num_of_pages(v, s) \ (((offset_in_page(v) + (s)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT) -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) -#define PDE_DATA(inode) ((PDE(inode)->data)) +#ifdef HAVE_NO_PDE_DATA_FUNC +#ifdef HAVE_PDE_DATA_MACRO +#define pde_data(inode) PDE_DATA(inode) +#else +#define pde_data(inode) ((PDE(inode)->data)) +#endif #endif #if CONFIG_HUGETLB_PAGE @@ -52,6 +56,10 @@ #error Unsuported architecture #endif +#ifndef task_is_stopped +#define task_is_stopped(task) ((task)->state == TASK_STOPPED) +#endif + static pte_t * xpmem_hugetlb_pte(pte_t *pte, struct mm_struct *mm, u64 vaddr, u64 *offset) { @@ -562,7 +570,7 @@ xpmem_is_thread_group_stopped(struct xpmem_thread_group *tg) rcu_read_lock(); do { if (!(task->flags & PF_EXITING) && - task->state != TASK_STOPPED) { + !task_is_stopped(task)) { rcu_read_unlock(); return 0; } @@ -627,7 +635,7 @@ xpmem_unpin_procfs_show(struct seq_file *seq, void *offset) static int xpmem_unpin_procfs_open(struct inode *inode, struct file *file) { - return single_open(file, xpmem_unpin_procfs_show, PDE_DATA(inode)); + return single_open(file, xpmem_unpin_procfs_show, pde_data(inode)); } #if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0) diff --git a/kernel/xpmem_private.h b/kernel/xpmem_private.h index a28809f..d6d6742 100644 --- a/kernel/xpmem_private.h +++ b/kernel/xpmem_private.h @@ -344,6 +344,22 @@ static inline struct xpmem_thread_group *__xpmem_tg_ref_by_tgid_nolock(pid_t tgi #define xpmem_mmap_read_trylock(_mm) mmap_read_trylock(_mm) #endif +#if (!HAVE_DECL_VMA_ITER_INIT) +struct vma_iterator { + struct mm_struct *mm; + unsigned long start; +}; + +#define vma_iter_init(_vmi, _mm, _start) \ + (_vmi)->mm = _mm; \ + (_vmi)->start = _start; + +#define for_each_vma_range(_vmi, _vma, _end) \ + for ((_vma) = find_vma_intersection((_vmi).mm, (_vmi).start, (_end)); \ + (_vma) && (_vma)->vm_start < (_end); \ + (_vma) = (_vma)->vm_next) +#endif + extern struct xpmem_thread_group *xpmem_tg_ref_by_segid(xpmem_segid_t); extern struct xpmem_thread_group *xpmem_tg_ref_by_apid(xpmem_apid_t); extern void xpmem_tg_deref(struct xpmem_thread_group *); diff --git a/m4/ac_path_kernel_source.m4 b/m4/ac_path_kernel_source.m4 index 2eb50bf..b4bc1f5 100644 --- a/m4/ac_path_kernel_source.m4 +++ b/m4/ac_path_kernel_source.m4 @@ -102,8 +102,8 @@ AC_DEFUN([AC_KERNEL_CHECKS], -e s/sparc64.*/sparc/ \ -e s/s390x/s390/) save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="-include $kerneldir/include/linux/compiler_types.h \ - -include $kerneldir/include/linux/kconfig.h \ + CPPFLAGS="-include $kerneldir/include/linux/kconfig.h \ + -include $kerneldir/include/linux/compiler.h \ -D__KERNEL__ \ -I$kerneldir/include \ -I$kerneldir/include/uapi \ @@ -116,6 +116,15 @@ AC_DEFUN([AC_KERNEL_CHECKS], AC_CHECK_MEMBERS([struct task_struct.cpus_mask], [], [], [[#include ]]) + AC_CHECK_DECL(pde_data, [], [ + AC_DEFINE([HAVE_NO_PDE_DATA_FUNC], 1, [Have pde_data()]) + AC_CHECK_DECL(PDE_DATA, [ + AC_DEFINE([HAVE_PDE_DATA_MACRO], 1, [Have PDE_DATA()]) + ], [], [[#include ]]) + ], [[#include ]]) + + AC_CHECK_DECLS([vma_iter_init], [], [], [[#include ]]) + CPPFLAGS="$save_CPPFLAGS" ] )