EXTRA_KCFLAGS="$tmp_flags"
]) # LIBCFS_HAVE_NR_UNSTABLE_NFS
+#
+# LIBCFS_HAVE_MMAP_LOCK
+#
+# kernel v5.8-rc1~83^2~24
+# mmap locking API: rename mmap_sem to mmap_lock
+#
+AC_DEFUN([LIBCFS_HAVE_MMAP_LOCK], [
+LB_CHECK_COMPILE([if mmap_lock API is available],
+mmap_write_lock, [
+ #include <linux/mm.h>
+],[
+ mmap_write_lock(NULL);
+],[
+ AC_DEFINE(HAVE_MMAP_LOCK, 1,
+ [mmap_lock API is available.])
+])
+]) # LIBCFS_HAVE_MMAP_LOCK
+
AC_DEFUN([LIBCFS_PROG_LINUX_SRC], [] )
AC_DEFUN([LIBCFS_PROG_LINUX_RESULTS], [])
LIBCFS_FORCE_SIG_WITH_TASK
LIBCFS_CACHE_DETAIL_WRITERS
LIBCFS_HAVE_NR_UNSTABLE_NFS
+# 5.8
+LIBCFS_HAVE_MMAP_LOCK
]) # LIBCFS_PROG_LINUX
#
kfree(shrinker);
}
+#ifndef HAVE_MMAP_LOCK
+static inline void mmap_write_lock(struct mm_struct *mm)
+{
+ down_write(&mm->mmap_sem);
+}
+
+static inline bool mmap_write_trylock(struct mm_struct *mm)
+{
+ return down_write_trylock(&mm->mmap_sem) != 0;
+}
+
+static inline void mmap_write_unlock(struct mm_struct *mm)
+{
+ up_write(&mm->mmap_sem);
+}
+
+static inline void mmap_read_lock(struct mm_struct *mm)
+{
+ down_read(&mm->mmap_sem);
+}
+
+static inline bool mmap_read_trylock(struct mm_struct *mm)
+{
+ return down_read_trylock(&mm->mmap_sem) != 0;
+}
+
+static inline void mmap_read_unlock(struct mm_struct *mm)
+{
+ up_read(&mm->mmap_sem);
+}
+#endif
+
#endif /* __LINUX_CFS_MEM_H__ */
struct page *page;
void *old_buf = buf;
- /* Avoid deadlocks on mmap_sem if called from sys_mmap_pgoff(),
- * which is already holding mmap_sem for writes. If some other
+ /* Avoid deadlocks on mmap_lock if called from sys_mmap_pgoff(),
+ * which is already holding mmap_lock for writes. If some other
* thread gets the write lock in the meantime, this thread will
* block, but at least it won't deadlock on itself. LU-1735 */
- if (down_read_trylock(&mm->mmap_sem) == 0)
+ if (!mmap_read_trylock(mm))
return -EDEADLK;
/* ignore errors, just check how much was successfully transferred */
buf += bytes;
addr += bytes;
}
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
return buf - old_buf;
}
*
* We must take lli_trunc_sem in read mode on entry in to various i/o paths
* in Lustre, in order to exclude truncates. Some of these paths then need to
- * take the mmap_sem, while still holding the trunc_sem. The problem is that
- * page faults hold the mmap_sem when calling in to Lustre, and then must also
+ * take the mmap_lock, while still holding the trunc_sem. The problem is that
+ * page faults hold the mmap_lock when calling in to Lustre, and then must also
* take the trunc_sem to exclude truncate.
*
- * This means the locking order for trunc_sem and mmap_sem is sometimes AB,
+ * This means the locking order for trunc_sem and mmap_lock is sometimes AB,
* sometimes BA. This is almost OK because in both cases, we take the trunc
* sem for read, so it doesn't block.
*
*
* So we have, on our truncate sem, in order (where 'reader' and 'writer' refer
* to the mode in which they take the semaphore):
- * reader (holding mmap_sem, needs truncate_sem)
+ * reader (holding mmap_lock, needs truncate_sem)
* writer
- * reader (holding truncate sem, waiting for mmap_sem)
+ * reader (holding truncate sem, waiting for mmap_lock)
*
* And so the readers deadlock.
*
* of the order they arrived in.
*
* down_read_nowait is only used in the page fault case, where we already hold
- * the mmap_sem. This is because otherwise repeated read and write operations
+ * the mmap_lock. This is because otherwise repeated read and write operations
* (which take the truncate sem) could prevent a truncate from ever starting.
* This could still happen with page faults, but without an even more complex
* mechanism, this is unavoidable.
struct vm_area_struct *our_vma(struct mm_struct *mm, unsigned long addr,
size_t count)
{
- struct vm_area_struct *vma, *ret = NULL;
- ENTRY;
+ struct vm_area_struct *vma, *ret = NULL;
+ ENTRY;
- /* mmap_sem must have been held by caller. */
- LASSERT(!down_write_trylock(&mm->mmap_sem));
+ /* mmap_lock must have been held by caller. */
+ LASSERT(!mmap_write_trylock(mm));
- for(vma = find_vma(mm, addr);
- vma != NULL && vma->vm_start < (addr + count); vma = vma->vm_next) {
- if (vma->vm_ops && vma->vm_ops == &ll_file_vm_ops &&
- vma->vm_flags & VM_SHARED) {
- ret = vma;
- break;
- }
- }
- RETURN(ret);
+ for (vma = find_vma(mm, addr);
+ vma != NULL && vma->vm_start < (addr + count);
+ vma = vma->vm_next) {
+ if (vma->vm_ops && vma->vm_ops == &ll_file_vm_ops &&
+ vma->vm_flags & VM_SHARED) {
+ ret = vma;
+ break;
+ }
+ }
+ RETURN(ret);
}
/**
"%s: PCC backend fs not support ->page_mkwrite()\n",
ll_i2sbi(inode)->ll_fsname);
pcc_ioctl_detach(inode, PCC_DETACH_OPT_UNCACHE);
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
*cached = true;
RETURN(VM_FAULT_RETRY | VM_FAULT_NOPAGE);
}
*/
if (page->mapping == pcc_file->f_mapping) {
*cached = true;
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
RETURN(VM_FAULT_RETRY | VM_FAULT_NOPAGE);
}
if (OBD_FAIL_CHECK(OBD_FAIL_LLITE_PCC_DETACH_MKWRITE)) {
pcc_io_fini(inode);
pcc_ioctl_detach(inode, PCC_DETACH_OPT_UNCACHE);
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
RETURN(VM_FAULT_RETRY | VM_FAULT_NOPAGE);
}
if (*pages == NULL)
return -ENOMEM;
- down_read(¤t->mm->mmap_sem);
+ mmap_read_lock(current->mm);
result = get_user_pages(current, current->mm, addr, page_count,
rw == READ, 0, *pages, NULL);
- up_read(¤t->mm->mmap_sem);
+ mmap_read_unlock(current->mm);
if (unlikely(result != page_count)) {
ll_free_user_pages(*pages, page_count);
addr = (unsigned long)iov.iov_base;
count = iov.iov_len;
- if (count == 0)
- continue;
+ if (count == 0)
+ continue;
count += addr & ~PAGE_MASK;
addr &= PAGE_MASK;
- down_read(&mm->mmap_sem);
- while((vma = our_vma(mm, addr, count)) != NULL) {
+ mmap_read_lock(mm);
+ while ((vma = our_vma(mm, addr, count)) != NULL) {
struct dentry *de = file_dentry(vma->vm_file);
struct inode *inode = de->d_inode;
- int flags = CEF_MUST;
+ int flags = CEF_MUST;
if (ll_file_nolock(vma->vm_file)) {
/*
break;
}
- /*
- * XXX: Required lock mode can be weakened: CIT_WRITE
- * io only ever reads user level buffer, and CIT_READ
- * only writes on it.
- */
- policy_from_vma(&policy, vma, addr, count);
- descr->cld_mode = vvp_mode_from_vma(vma);
- descr->cld_obj = ll_i2info(inode)->lli_clob;
- descr->cld_start = cl_index(descr->cld_obj,
- policy.l_extent.start);
- descr->cld_end = cl_index(descr->cld_obj,
- policy.l_extent.end);
- descr->cld_enq_flags = flags;
- result = cl_io_lock_alloc_add(env, io, descr);
-
- CDEBUG(D_VFSTRACE, "lock: %d: [%lu, %lu]\n",
- descr->cld_mode, descr->cld_start,
- descr->cld_end);
+ /*
+ * XXX: Required lock mode can be weakened: CIT_WRITE
+ * io only ever reads user level buffer, and CIT_READ
+ * only writes on it.
+ */
+ policy_from_vma(&policy, vma, addr, count);
+ descr->cld_mode = vvp_mode_from_vma(vma);
+ descr->cld_obj = ll_i2info(inode)->lli_clob;
+ descr->cld_start = cl_index(descr->cld_obj,
+ policy.l_extent.start);
+ descr->cld_end = cl_index(descr->cld_obj,
+ policy.l_extent.end);
+ descr->cld_enq_flags = flags;
+ result = cl_io_lock_alloc_add(env, io, descr);
+
+ CDEBUG(D_VFSTRACE, "lock: %d: [%lu, %lu]\n",
+ descr->cld_mode, descr->cld_start,
+ descr->cld_end);
if (result < 0)
break;
count -= vma->vm_end - addr;
addr = vma->vm_end;
}
- up_read(&mm->mmap_sem);
+ mmap_read_unlock(mm);
if (result < 0)
break;
}