Skip to content
This repository has been archived by the owner on Sep 18, 2022. It is now read-only.

Commit

Permalink
kernel: Add hooks for user-accessible timers in the kernel.
Browse files Browse the repository at this point in the history
Hooks for user-accessible timers allow implementation of a
more efficient gettimeofday in user-space.

Change-Id: If2f63d010c1cf142eb84f3745617e756913e46f7
Signed-off-by: Brent DeGraaf <[email protected]>
  • Loading branch information
Greg Reid authored and Brent DeGraaf committed Nov 15, 2012
1 parent 5d9616e commit 79faa17
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 2 deletions.
26 changes: 26 additions & 0 deletions include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1561,6 +1561,32 @@ int in_gate_area_no_mm(unsigned long addr);
#define in_gate_area(mm, addr) ({(void)mm; in_gate_area_no_mm(addr);})
#endif /* __HAVE_ARCH_GATE_AREA */

#ifdef CONFIG_USE_USER_ACCESSIBLE_TIMERS
static inline int use_user_accessible_timers(void) { return 1; }
extern int in_user_timers_area(struct mm_struct *mm, unsigned long addr);
extern struct vm_area_struct *get_user_timers_vma(struct mm_struct *mm);
extern int get_user_timer_page(struct vm_area_struct *vma,
struct mm_struct *mm, unsigned long start, unsigned int gup_flags,
struct page **pages, int idx, int *goto_next_page);
#else
static inline int use_user_accessible_timers(void) { return 0; }
static inline int in_user_timers_area(struct mm_struct *mm, unsigned long addr)
{
return 0;
}
static inline struct vm_area_struct *get_user_timers_vma(struct mm_struct *mm)
{
return NULL;
}
static inline int get_user_timer_page(struct vm_area_struct *vma,
struct mm_struct *mm, unsigned long start, unsigned int gup_flags,
struct page **pages, int idx, int *goto_next_page)
{
*goto_next_page = 0;
return 0;
}
#endif

int drop_caches_sysctl_handler(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
unsigned long shrink_slab(struct shrink_control *shrink,
Expand Down
11 changes: 11 additions & 0 deletions mm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -390,3 +390,14 @@ config MEMORY_HOLE_CARVEOUT
the memory corresponding to the hole to be removed using memblock-
remove.

config USE_USER_ACCESSIBLE_TIMERS
bool "Enables timers accessible from userspace"
depends on MMU
help
User-accessible timers allow the kernel to map kernel timer
registers to a userspace accessible page, to allow faster
access to time information. This flag will enable the
interface code in the main kernel. However, there are
architecture-specific code that will need to be enabled
separately.

13 changes: 13 additions & 0 deletions mm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -1726,6 +1726,19 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
goto next_page;
}

if (use_user_accessible_timers()) {
if (!vma && in_user_timers_area(mm, start)) {
int goto_next_page = 0;
int user_timer_ret = get_user_timer_page(vma,
mm, start, gup_flags, pages, i,
&goto_next_page);
if (goto_next_page)
goto next_page;
else
return user_timer_ret;
}
}

if (!vma ||
(vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
!(vm_flags & vma->vm_flags))
Expand Down
8 changes: 6 additions & 2 deletions mm/mlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,9 @@ long mlock_vma_pages_range(struct vm_area_struct *vma,

if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) ||
is_vm_hugetlb_page(vma) ||
vma == get_gate_vma(current->mm))) {
vma == get_gate_vma(current->mm) ||
((use_user_accessible_timers() &&
(vma == get_user_timers_vma(current->mm)))))) {

__mlock_vma_pages_range(vma, start, end, NULL);

Expand Down Expand Up @@ -324,7 +326,9 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
int lock = !!(newflags & VM_LOCKED);

if (newflags == vma->vm_flags || (vma->vm_flags & VM_SPECIAL) ||
is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm))
is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm) ||
((use_user_accessible_timers()) &&
(vma == get_user_timers_vma(current->mm))))
goto out; /* don't set VM_LOCKED, don't count */

pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
Expand Down

0 comments on commit 79faa17

Please sign in to comment.