Skip to content

Commit

Permalink
sched/umcg: add UMCG server/worker API (early RFC)
Browse files Browse the repository at this point in the history
Implement UMCG server/worker API.

This is an early RFC patch - the code seems working, but
more testing is needed. Gaps I plan to address before this
is ready for a detailed review:

- preemption/interrupt handling;
- better documentation/comments;
- tracing;
- additional testing;
- corner cases like abnormal process/task termination;
- in some cases where I kill the task (umcg_segv), returning
an error may be more appropriate.

All in all, please focus more on the high-level approach
and less on things like variable names, (doc) comments, or indentation.

Signed-off-by: Peter Oskolkov <posk@google.com>
  • Loading branch information
Peter Oskolkov authored and intel-lab-lkp committed May 22, 2021
1 parent 12ea5df commit 634e0c0
Show file tree
Hide file tree
Showing 7 changed files with 845 additions and 9 deletions.
5 changes: 5 additions & 0 deletions include/linux/mm_types.h
Expand Up @@ -562,6 +562,11 @@ struct mm_struct {
#ifdef CONFIG_IOMMU_SUPPORT
u32 pasid;
#endif

#ifdef CONFIG_UMCG
spinlock_t umcg_lock;
struct list_head umcg_groups;
#endif
} __randomize_layout;

/*
Expand Down
5 changes: 5 additions & 0 deletions include/linux/syscalls.h
Expand Up @@ -1059,6 +1059,11 @@ asmlinkage long umcg_wait(u32 flags, const struct __kernel_timespec __user *time
asmlinkage long umcg_wake(u32 flags, u32 next_tid);
asmlinkage long umcg_swap(u32 wake_flags, u32 next_tid, u32 wait_flags,
const struct __kernel_timespec __user *timeout);
asmlinkage long umcg_create_group(u32 api_version, u64, flags);
asmlinkage long umcg_destroy_group(u32 group_id);
asmlinkage long umcg_poll_worker(u32 flags, struct umcg_task __user **ut);
asmlinkage long umcg_run_worker(u32 flags, u32 worker_tid,
struct umcg_task __user **ut);

/*
* Architecture-specific system calls
Expand Down
11 changes: 11 additions & 0 deletions kernel/fork.c
Expand Up @@ -1026,6 +1026,10 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
seqcount_init(&mm->write_protect_seq);
mmap_init_lock(mm);
INIT_LIST_HEAD(&mm->mmlist);
#ifdef CONFIG_UMCG
spin_lock_init(&mm->umcg_lock);
INIT_LIST_HEAD(&mm->umcg_groups);
#endif
mm->core_state = NULL;
mm_pgtables_bytes_init(mm);
mm->map_count = 0;
Expand Down Expand Up @@ -1102,6 +1106,13 @@ static inline void __mmput(struct mm_struct *mm)
list_del(&mm->mmlist);
spin_unlock(&mmlist_lock);
}
#ifdef CONFIG_UMCG
if (!list_empty(&mm->umcg_groups)) {
spin_lock(&mm->umcg_lock);
list_del(&mm->umcg_groups);
spin_unlock(&mm->umcg_lock);
}
#endif
if (mm->binfmt)
module_put(mm->binfmt->module);
mmdrop(mm);
Expand Down
11 changes: 11 additions & 0 deletions kernel/sched/core.c
Expand Up @@ -26,6 +26,7 @@

#include "pelt.h"
#include "smp.h"
#include "umcg.h"

/*
* Export tracepoints that act as a bare tracehook (ie: have no trace event
Expand Down Expand Up @@ -6012,10 +6013,20 @@ static inline void sched_submit_work(struct task_struct *tsk)
*/
if (blk_needs_flush_plug(tsk))
blk_schedule_flush_plug(tsk);

#ifdef CONFIG_UMCG
if (rcu_access_pointer(tsk->umcg_task_data))
umcg_on_block();
#endif
}

static void sched_update_worker(struct task_struct *tsk)
{
#ifdef CONFIG_UMCG
if (rcu_access_pointer(tsk->umcg_task_data))
umcg_on_wake();
#endif

if (tsk->flags & (PF_WQ_WORKER | PF_IO_WORKER)) {
if (tsk->flags & PF_WQ_WORKER)
wq_worker_running(tsk);
Expand Down

0 comments on commit 634e0c0

Please sign in to comment.