Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to proc/file ops to handle kernel 5.6 series #33

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion dkms.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ BUILT_MODULE_LOCATION[0]="kernel"
# where we put it under the kernel modules directory
DEST_MODULE_LOCATION[0]="/kernel/../updates/"
# how to build it
MAKE[0]="./configure --prefix=/opt/xpmem; make clean; make install"
MAKE[0]="./configure --with-kernelvers=${kernelver} --prefix=/opt/xpmem; make clean; make install"

# clean up command
CLEAN="make distclean"
Expand Down
56 changes: 31 additions & 25 deletions kernel/xpmem_attach.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
#include <linux/sched/signal.h>
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
# define LOCK_FIELD(_mm) _mm->mmap_lock
#else
# define LOCK_FIELD(_mm) _mm->mmap_sem
#endif

static void
xpmem_open_handler(struct vm_area_struct *vma)
{
Expand Down Expand Up @@ -239,9 +245,9 @@ xpmem_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf)
ret = xpmem_seg_down_read(seg_tg, seg, 1, 0);
if (ret == -EAGAIN) {
/* to avoid possible deadlock drop current->mm->mmap_sem */
up_read(&current->mm->mmap_sem);
up_read(LOCK_FIELD(&current->mm));
ret = xpmem_seg_down_read(seg_tg, seg, 1, 1);
down_read(&current->mm->mmap_sem);
down_read(LOCK_FIELD(&current->mm));
vma_verification_needed = 1;
}
if (ret != 0)
Expand All @@ -254,11 +260,11 @@ xpmem_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf)
* getting the smaller address first.
*/
if (current->mm < seg_tg->mm) {
down_read(&seg_tg->mm->mmap_sem);
} else if (!down_read_trylock(&seg_tg->mm->mmap_sem)) {
up_read(&current->mm->mmap_sem);
down_read(&seg_tg->mm->mmap_sem);
down_read(&current->mm->mmap_sem);
down_read(LOCK_FIELD(&seg_tg->mm));
} else if (!down_read_trylock(LOCK_FIELD(&seg_tg->mm))) {
up_read(LOCK_FIELD(&current->mm));
down_read(LOCK_FIELD(&seg_tg->mm));
down_read(LOCK_FIELD(&current->mm));
vma_verification_needed = 1;
}
seg_tg_mmap_sem_locked = 1;
Expand Down Expand Up @@ -342,7 +348,7 @@ xpmem_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf)
}
out:
if (seg_tg_mmap_sem_locked)
up_read(&seg_tg->mm->mmap_sem);
up_read(LOCK_FIELD(&seg_tg->mm));

if (att_locked)
mutex_unlock(&att->mutex);
Expand Down Expand Up @@ -495,10 +501,10 @@ xpmem_attach(struct file *file, xpmem_apid_t apid, off_t offset, size_t size,
if (flags & MAP_FIXED) {
struct vm_area_struct *existing_vma;

down_write(&current->mm->mmap_sem);
down_write(LOCK_FIELD(&current->mm));
existing_vma = find_vma_intersection(current->mm, vaddr,
vaddr + size);
up_write(&current->mm->mmap_sem);
up_write(LOCK_FIELD(&current->mm));
for ( ; existing_vma && existing_vma->vm_start < vaddr + size
; existing_vma = existing_vma->vm_next) {
if (xpmem_is_vm_ops_set(existing_vma)) {
Expand All @@ -515,9 +521,9 @@ xpmem_attach(struct file *file, xpmem_apid_t apid, off_t offset, size_t size,
}
att->at_vaddr = at_vaddr;

down_write(&current->mm->mmap_sem);
down_write(LOCK_FIELD(&current->mm));
vma = find_vma(current->mm, at_vaddr);
up_write(&current->mm->mmap_sem);
up_write(LOCK_FIELD(&current->mm));

vma->vm_private_data = att;
vma->vm_flags |=
Expand Down Expand Up @@ -568,25 +574,25 @@ xpmem_detach(u64 at_vaddr)
struct xpmem_attachment *att;
struct vm_area_struct *vma;

down_write(&current->mm->mmap_sem);
down_write(LOCK_FIELD(&current->mm));

/* find the corresponding vma */
vma = find_vma(current->mm, at_vaddr);
if (!vma || vma->vm_start > at_vaddr) {
up_write(&current->mm->mmap_sem);
up_write(LOCK_FIELD(&current->mm));
return 0;
}

att = (struct xpmem_attachment *)vma->vm_private_data;
if (!xpmem_is_vm_ops_set(vma) || att == NULL) {
up_write(&current->mm->mmap_sem);
up_write(LOCK_FIELD(&current->mm));
return -EINVAL;
}
xpmem_att_ref(att);

if (mutex_lock_killable(&att->mutex)) {
xpmem_att_deref(att);
up_write(&current->mm->mmap_sem);
up_write(LOCK_FIELD(&current->mm));
return -EINTR;
}

Expand All @@ -597,7 +603,7 @@ xpmem_detach(u64 at_vaddr)
mutex_unlock(&att->invalidate_mutex);
mutex_unlock(&att->mutex);
xpmem_att_deref(att);
up_write(&current->mm->mmap_sem);
up_write(LOCK_FIELD(&current->mm));
return 0;
}
att->flags |= XPMEM_FLAG_DESTROYING;
Expand All @@ -612,7 +618,7 @@ xpmem_detach(u64 at_vaddr)
xpmem_ap_deref(ap);
mutex_unlock(&att->mutex);
xpmem_att_deref(att);
up_write(&current->mm->mmap_sem);
up_write(LOCK_FIELD(&current->mm));
return -EACCES;
}

Expand All @@ -631,7 +637,7 @@ xpmem_detach(u64 at_vaddr)

/* NTH: drop the current mm semaphore before calling vm_munmap (which will
* call down_write on the same semaphore) */
up_write(&current->mm->mmap_sem);
up_write(LOCK_FIELD(&current->mm));
ret = vm_munmap(vma->vm_start, att->at_size);
DBUG_ON(ret != 0);

Expand Down Expand Up @@ -667,7 +673,7 @@ xpmem_detach_att(struct xpmem_access_permit *ap, struct xpmem_attachment *att)
mm = current->mm ? current->mm : att->mm;

/* must lock mmap_sem before att's sema to prevent deadlock */
down_write(&mm->mmap_sem);
down_write(LOCK_FIELD(&mm));
mutex_lock(&att->mutex);

/* ensure we aren't racing with MMU notifier PTE cleanup */
Expand All @@ -676,7 +682,7 @@ xpmem_detach_att(struct xpmem_access_permit *ap, struct xpmem_attachment *att)
if (att->flags & XPMEM_FLAG_DESTROYING) {
mutex_unlock(&att->invalidate_mutex);
mutex_unlock(&att->mutex);
up_write(&mm->mmap_sem);
up_write(LOCK_FIELD(&mm));
return;
}
att->flags |= XPMEM_FLAG_DESTROYING;
Expand All @@ -688,7 +694,7 @@ xpmem_detach_att(struct xpmem_access_permit *ap, struct xpmem_attachment *att)
if (!vma || vma->vm_start > att->at_vaddr) {
DBUG_ON(1);
mutex_unlock(&att->mutex);
up_write(&mm->mmap_sem);
up_write(LOCK_FIELD(&mm));
return;
}
DBUG_ON(!xpmem_is_vm_ops_set(vma));
Expand All @@ -707,7 +713,7 @@ xpmem_detach_att(struct xpmem_access_permit *ap, struct xpmem_attachment *att)

/* NTH: drop the semaphore and attachment lock before calling vm_munmap */
mutex_unlock(&att->mutex);
up_write(&mm->mmap_sem);
up_write(LOCK_FIELD(&mm));

/* NTH: if the current task does not have a memory descriptor
* then there is nothing more to do. the memory mapping should
Expand Down Expand Up @@ -751,7 +757,7 @@ xpmem_clear_PTEs_of_att(struct xpmem_attachment *att, u64 start, u64 end,
}
} else {
/* Must lock mmap_sem before att's sema to prevent deadlock. */
down_read(&att->mm->mmap_sem);
down_read(LOCK_FIELD(&att->mm));
mutex_lock(&att->mutex);
}

Expand Down Expand Up @@ -832,7 +838,7 @@ xpmem_clear_PTEs_of_att(struct xpmem_attachment *att, u64 start, u64 end,
mutex_unlock(&att->invalidate_mutex);
} else {
mutex_unlock(&att->mutex);
up_read(&att->mm->mmap_sem);
up_read(LOCK_FIELD(&att->mm));
}
}

Expand Down
14 changes: 12 additions & 2 deletions kernel/xpmem_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,11 @@ xpmem_debug_printk_procfs_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
char buf;

if(copy_from_user(&buf, buffer, 1))
return -EFAULT;

if (buf == '0')
if (buf == '0')
xpmem_debug_on = 0;
else if (buf == '1')
xpmem_debug_on = 1;
Expand All @@ -315,6 +315,15 @@ xpmem_debug_printk_procfs_open(struct inode *inode, struct file *file)
return single_open(file, xpmem_debug_printk_procfs_show, NULL);
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
struct proc_ops xpmem_debug_printk_procfs_ops = {
.proc_lseek = seq_lseek,
.proc_read = seq_read,
.proc_write = xpmem_debug_printk_procfs_write,
.proc_open = xpmem_debug_printk_procfs_open,
.proc_release = single_release,
};
#else
struct file_operations xpmem_debug_printk_procfs_ops = {
.owner = THIS_MODULE,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

owner set twice?

.llseek = seq_lseek,
Expand All @@ -323,3 +332,4 @@ struct file_operations xpmem_debug_printk_procfs_ops = {
.open = xpmem_debug_printk_procfs_open,
.release = single_release,
};
#endif /* kernel 5.6 */
11 changes: 11 additions & 0 deletions kernel/xpmem_mmu_notifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@
#include <linux/mm.h>
#include <linux/cdev.h>
#include <linux/percpu.h>
#include <linux/version.h>

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
/*
* This is not being picked up
*
*/
extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
unsigned long end, unsigned int stride_shift,
bool freed_tables);
#endif

#include <asm/tlb.h>
#include <asm/tlbflush.h>
Expand Down
14 changes: 12 additions & 2 deletions kernel/xpmem_pfn.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,11 +621,21 @@ xpmem_unpin_procfs_open(struct inode *inode, struct file *file)
return single_open(file, xpmem_unpin_procfs_show, PDE_DATA(inode));
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
struct proc_ops xpmem_unpin_procfs_ops = {
.proc_lseek = seq_lseek,
.proc_read = seq_read,
.proc_write = xpmem_unpin_procfs_write,
.proc_open = xpmem_unpin_procfs_open,
.proc_release = single_release,
};
#else
struct file_operations xpmem_unpin_procfs_ops = {
.owner = THIS_MODULE,
.llseek = seq_lseek,
.read = seq_read,
.write = xpmem_unpin_procfs_write,
.read = seq_read,
.write = xpmem_unpin_procfs_write,
.open = xpmem_unpin_procfs_open,
.release = single_release,
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a merge issue. I don't think this will compile with 5.5.x and older.

#endif /* kernel 5.6 */
8 changes: 8 additions & 0 deletions kernel/xpmem_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,11 @@ extern int xpmem_fork_end(void);
#define XPMEM_TGID_STRING_LEN 11
extern spinlock_t xpmem_unpin_procfs_lock;
extern struct proc_dir_entry *xpmem_unpin_procfs_dir;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
extern struct proc_ops xpmem_unpin_procfs_ops;
#else
extern struct file_operations xpmem_unpin_procfs_ops;
#endif /* kernel 5.6 */

/* found in xpmem_main.c */
extern struct xpmem_partition *xpmem_my_part;
Expand Down Expand Up @@ -339,7 +343,11 @@ extern int xpmem_seg_down_read(struct xpmem_thread_group *,
struct xpmem_segment *, int, int);
extern int xpmem_validate_access(struct xpmem_access_permit *, off_t, size_t,
int, u64 *);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
extern struct proc_ops xpmem_debug_printk_procfs_ops;
#else
extern struct file_operations xpmem_debug_printk_procfs_ops;
#endif /* kernel 5.6 */
/* found in xpmem_mmu_notifier.c */
extern int xpmem_mmu_notifier_init(struct xpmem_thread_group *);
extern void xpmem_mmu_notifier_unlink(struct xpmem_thread_group *);
Expand Down