refactoring process structures
This commit is contained in:
@@ -28,7 +28,7 @@ void kputs(char *buf)
|
||||
int len = strlen(buf);
|
||||
unsigned long flags;
|
||||
|
||||
flags = ihk_mc_spinlock_lock(&kmsg_lock);
|
||||
flags = __ihk_mc_spinlock_lock(&kmsg_lock);
|
||||
|
||||
if (len + kmsg_buf.tail > kmsg_buf.len) {
|
||||
kmsg_buf.tail = 0;
|
||||
@@ -40,19 +40,19 @@ void kputs(char *buf)
|
||||
memcpy(kmsg_buf.str + kmsg_buf.tail, buf, len);
|
||||
kmsg_buf.tail += len;
|
||||
|
||||
ihk_mc_spinlock_unlock(&kmsg_lock, flags);
|
||||
__ihk_mc_spinlock_unlock(&kmsg_lock, flags);
|
||||
}
|
||||
|
||||
#define KPRINTF_LOCAL_BUF_LEN 1024
|
||||
|
||||
unsigned long kprintf_lock(void)
|
||||
{
|
||||
return ihk_mc_spinlock_lock(&kmsg_lock);
|
||||
return __ihk_mc_spinlock_lock(&kmsg_lock);
|
||||
}
|
||||
|
||||
void kprintf_unlock(unsigned long irqflags)
|
||||
{
|
||||
ihk_mc_spinlock_unlock(&kmsg_lock, irqflags);
|
||||
__ihk_mc_spinlock_unlock(&kmsg_lock, irqflags);
|
||||
}
|
||||
|
||||
/* Caller must hold kmsg_lock! */
|
||||
@@ -85,7 +85,7 @@ int kprintf(const char *format, ...)
|
||||
unsigned long flags;
|
||||
char buf[KPRINTF_LOCAL_BUF_LEN];
|
||||
|
||||
flags = ihk_mc_spinlock_lock(&kmsg_lock);
|
||||
flags = __ihk_mc_spinlock_lock(&kmsg_lock);
|
||||
|
||||
/* Copy into the local buf */
|
||||
len = sprintf(buf, "[%3d]: ", ihk_mc_get_processor_id());
|
||||
@@ -101,7 +101,7 @@ int kprintf(const char *format, ...)
|
||||
memcpy(kmsg_buf.str + kmsg_buf.tail, buf, len);
|
||||
kmsg_buf.tail += len;
|
||||
|
||||
ihk_mc_spinlock_unlock(&kmsg_lock, flags);
|
||||
__ihk_mc_spinlock_unlock(&kmsg_lock, flags);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ out:
|
||||
|
||||
static int fileobj_get_page(struct memobj *memobj, off_t off, int p2align, uintptr_t *physp, unsigned long *pflag)
|
||||
{
|
||||
struct process *proc = cpu_local_var(current);
|
||||
struct thread *proc = cpu_local_var(current);
|
||||
struct fileobj *obj = to_fileobj(memobj);
|
||||
int error;
|
||||
void *virt = NULL;
|
||||
|
||||
@@ -103,7 +103,7 @@ int futex_cmpxchg_enabled;
|
||||
struct futex_q {
|
||||
struct plist_node list;
|
||||
|
||||
struct process *task;
|
||||
struct thread *task;
|
||||
ihk_spinlock_t *lock_ptr;
|
||||
union futex_key key;
|
||||
union futex_key *requeue_pi_key;
|
||||
@@ -243,7 +243,7 @@ static int get_futex_value_locked(uint32_t *dest, uint32_t *from)
|
||||
*/
|
||||
static void wake_futex(struct futex_q *q)
|
||||
{
|
||||
struct process *p = q->task;
|
||||
struct thread *p = q->task;
|
||||
|
||||
/*
|
||||
* We set q->lock_ptr = NULL _before_ we wake up the task. If
|
||||
@@ -263,7 +263,7 @@ static void wake_futex(struct futex_q *q)
|
||||
barrier();
|
||||
q->lock_ptr = NULL;
|
||||
|
||||
sched_wakeup_process(p, PS_NORMAL);
|
||||
sched_wakeup_thread(p, PS_NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -658,7 +658,7 @@ static uint64_t futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q
|
||||
* queue_me() calls spin_unlock() upon completion, both serializing
|
||||
* access to the hash list and forcing another memory barrier.
|
||||
*/
|
||||
xchg4(&(cpu_local_var(current)->ftn->status), PS_INTERRUPTIBLE);
|
||||
xchg4(&(cpu_local_var(current)->tstatus), PS_INTERRUPTIBLE);
|
||||
queue_me(q, hb);
|
||||
|
||||
if (!plist_node_empty(&q->list)) {
|
||||
@@ -674,7 +674,7 @@ static uint64_t futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q
|
||||
}
|
||||
|
||||
/* This does not need to be serialized */
|
||||
cpu_local_var(current)->ftn->status = PS_RUNNING;
|
||||
cpu_local_var(current)->tstatus = PS_RUNNING;
|
||||
|
||||
return time_remain;
|
||||
}
|
||||
|
||||
121
kernel/host.c
121
kernel/host.c
@@ -39,11 +39,11 @@
|
||||
#define dkprintf(...) do { if (0) kprintf(__VA_ARGS__); } while (0)
|
||||
#endif
|
||||
|
||||
void check_mapping_for_proc(struct process *proc, unsigned long addr)
|
||||
void check_mapping_for_proc(struct thread *thread, unsigned long addr)
|
||||
{
|
||||
unsigned long __phys;
|
||||
|
||||
if (ihk_mc_pt_virt_to_phys(proc->vm->page_table, (void*)addr, &__phys)) {
|
||||
if (ihk_mc_pt_virt_to_phys(thread->vm->address_space->page_table, (void*)addr, &__phys)) {
|
||||
kprintf("check_map: no mapping for 0x%lX\n", addr);
|
||||
}
|
||||
else {
|
||||
@@ -60,7 +60,7 @@ void check_mapping_for_proc(struct process *proc, unsigned long addr)
|
||||
* NOTE: if args, args_len, envs, envs_len are zero,
|
||||
* the function constructs them based on the descriptor
|
||||
*/
|
||||
int prepare_process_ranges_args_envs(struct process *proc,
|
||||
int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
struct program_load_desc *pn,
|
||||
struct program_load_desc *p,
|
||||
enum ihk_mc_pt_attribute attr,
|
||||
@@ -81,6 +81,9 @@ int prepare_process_ranges_args_envs(struct process *proc,
|
||||
uintptr_t interp_obase = -1;
|
||||
uintptr_t interp_nbase = -1;
|
||||
size_t map_size;
|
||||
struct process *proc = thread->proc;
|
||||
struct process_vm *vm = proc->vm;
|
||||
struct address_space *as = vm->address_space;
|
||||
|
||||
n = p->num_sections;
|
||||
|
||||
@@ -89,7 +92,7 @@ int prepare_process_ranges_args_envs(struct process *proc,
|
||||
if (pn->sections[i].interp && (interp_nbase == (uintptr_t)-1)) {
|
||||
interp_obase = pn->sections[i].vaddr;
|
||||
interp_obase -= (interp_obase % pn->interp_align);
|
||||
interp_nbase = proc->vm->region.map_start;
|
||||
interp_nbase = vm->region.map_start;
|
||||
interp_nbase = (interp_nbase + pn->interp_align - 1)
|
||||
& ~(pn->interp_align - 1);
|
||||
}
|
||||
@@ -114,7 +117,7 @@ int prepare_process_ranges_args_envs(struct process *proc,
|
||||
}
|
||||
|
||||
up = virt_to_phys(up_v);
|
||||
if (add_process_memory_range(proc, s, e, up, flags, NULL, 0) != 0) {
|
||||
if (add_process_memory_range(vm, s, e, up, flags, NULL, 0) != 0) {
|
||||
ihk_mc_free_pages(up_v, range_npages);
|
||||
kprintf("ERROR: adding memory range for ELF section %i\n", i);
|
||||
goto err;
|
||||
@@ -123,14 +126,14 @@ int prepare_process_ranges_args_envs(struct process *proc,
|
||||
{
|
||||
void *_virt = (void *)s;
|
||||
unsigned long _phys;
|
||||
if (ihk_mc_pt_virt_to_phys(proc->vm->page_table,
|
||||
if (ihk_mc_pt_virt_to_phys(as->page_table,
|
||||
_virt, &_phys)) {
|
||||
kprintf("ERROR: no mapping for 0x%lX\n", _virt);
|
||||
}
|
||||
for (_virt = (void *)s + PAGE_SIZE;
|
||||
(unsigned long)_virt < e; _virt += PAGE_SIZE) {
|
||||
unsigned long __phys;
|
||||
if (ihk_mc_pt_virt_to_phys(proc->vm->page_table,
|
||||
if (ihk_mc_pt_virt_to_phys(as->page_table,
|
||||
_virt, &__phys)) {
|
||||
kprintf("ERROR: no mapping for 0x%lX\n", _virt);
|
||||
panic("mapping");
|
||||
@@ -149,23 +152,23 @@ int prepare_process_ranges_args_envs(struct process *proc,
|
||||
|
||||
/* TODO: Maybe we need flag */
|
||||
if (pn->sections[i].interp) {
|
||||
proc->vm->region.map_end = e;
|
||||
vm->region.map_end = e;
|
||||
}
|
||||
else if (i == 0) {
|
||||
proc->vm->region.text_start = s;
|
||||
proc->vm->region.text_end = e;
|
||||
vm->region.text_start = s;
|
||||
vm->region.text_end = e;
|
||||
}
|
||||
else if (i == 1) {
|
||||
proc->vm->region.data_start = s;
|
||||
proc->vm->region.data_end = e;
|
||||
vm->region.data_start = s;
|
||||
vm->region.data_end = e;
|
||||
}
|
||||
else {
|
||||
proc->vm->region.data_start =
|
||||
(s < proc->vm->region.data_start ?
|
||||
s : proc->vm->region.data_start);
|
||||
proc->vm->region.data_end =
|
||||
(e > proc->vm->region.data_end ?
|
||||
e : proc->vm->region.data_end);
|
||||
vm->region.data_start =
|
||||
(s < vm->region.data_start ?
|
||||
s : vm->region.data_start);
|
||||
vm->region.data_end =
|
||||
(e > vm->region.data_end ?
|
||||
e : vm->region.data_end);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,17 +176,17 @@ int prepare_process_ranges_args_envs(struct process *proc,
|
||||
pn->entry -= interp_obase;
|
||||
pn->entry += interp_nbase;
|
||||
p->entry = pn->entry;
|
||||
ihk_mc_modify_user_context(proc->uctx, IHK_UCR_PROGRAM_COUNTER,
|
||||
pn->entry);
|
||||
ihk_mc_modify_user_context(thread->uctx,
|
||||
IHK_UCR_PROGRAM_COUNTER,
|
||||
pn->entry);
|
||||
}
|
||||
|
||||
proc->vm->region.brk_start = proc->vm->region.brk_end =
|
||||
proc->vm->region.data_end;
|
||||
vm->region.brk_start = vm->region.brk_end = vm->region.data_end;
|
||||
|
||||
/* Map, copy and update args and envs */
|
||||
flags = VR_PROT_READ | VR_PROT_WRITE;
|
||||
flags |= VRFLAG_PROT_TO_MAXPROT(flags);
|
||||
addr = proc->vm->region.map_start - PAGE_SIZE * SCD_RESERVED_COUNT;
|
||||
addr = vm->region.map_start - PAGE_SIZE * SCD_RESERVED_COUNT;
|
||||
e = addr + PAGE_SIZE * ARGENV_PAGE_COUNT;
|
||||
|
||||
if((args_envs = ihk_mc_alloc_pages(ARGENV_PAGE_COUNT, IHK_MC_AP_NOWAIT)) == NULL){
|
||||
@@ -192,7 +195,7 @@ int prepare_process_ranges_args_envs(struct process *proc,
|
||||
}
|
||||
args_envs_p = virt_to_phys(args_envs);
|
||||
|
||||
if(add_process_memory_range(proc, addr, e, args_envs_p,
|
||||
if(add_process_memory_range(vm, addr, e, args_envs_p,
|
||||
flags, NULL, 0) != 0){
|
||||
ihk_mc_free_pages(args_envs, ARGENV_PAGE_COUNT);
|
||||
kprintf("ERROR: adding memory range for args/envs\n");
|
||||
@@ -305,10 +308,10 @@ int prepare_process_ranges_args_envs(struct process *proc,
|
||||
|
||||
dkprintf("env OK\n");
|
||||
|
||||
p->rprocess = (unsigned long)proc;
|
||||
p->rpgtable = virt_to_phys(proc->vm->page_table);
|
||||
p->rprocess = (unsigned long)thread;
|
||||
p->rpgtable = virt_to_phys(as->page_table);
|
||||
|
||||
if (init_process_stack(proc, pn, argc, argv, envc, env) != 0) {
|
||||
if (init_process_stack(thread, pn, argc, argv, envc, env) != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -327,7 +330,9 @@ static int process_msg_prepare_process(unsigned long rphys)
|
||||
unsigned long phys, sz;
|
||||
struct program_load_desc *p, *pn;
|
||||
int npages, n;
|
||||
struct thread *thread;
|
||||
struct process *proc;
|
||||
struct process_vm *vm;
|
||||
enum ihk_mc_pt_attribute attr;
|
||||
|
||||
attr = PTATTR_NO_EXECUTE | PTATTR_WRITABLE | PTATTR_FOR_USER;
|
||||
@@ -354,41 +359,43 @@ static int process_msg_prepare_process(unsigned long rphys)
|
||||
memcpy_long(pn, p, sizeof(struct program_load_desc)
|
||||
+ sizeof(struct program_image_section) * n);
|
||||
|
||||
if((proc = create_process(p->entry)) == NULL){
|
||||
if((thread = create_thread(p->entry)) == NULL){
|
||||
ihk_mc_free(pn);
|
||||
ihk_mc_unmap_virtual(p, npages, 1);
|
||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||
return -ENOMEM;
|
||||
}
|
||||
proc->ftn->pid = pn->pid;
|
||||
proc->ftn->pgid = pn->pgid;
|
||||
proc = thread->proc;
|
||||
vm = thread->vm;
|
||||
|
||||
proc->ftn->ruid = pn->cred[0];
|
||||
proc->ftn->euid = pn->cred[1];
|
||||
proc->ftn->suid = pn->cred[2];
|
||||
proc->ftn->fsuid = pn->cred[3];
|
||||
proc->ftn->rgid = pn->cred[4];
|
||||
proc->ftn->egid = pn->cred[5];
|
||||
proc->ftn->sgid = pn->cred[6];
|
||||
proc->ftn->fsgid = pn->cred[7];
|
||||
proc->pid = pn->pid;
|
||||
proc->pgid = pn->pgid;
|
||||
proc->ruid = pn->cred[0];
|
||||
proc->euid = pn->cred[1];
|
||||
proc->suid = pn->cred[2];
|
||||
proc->fsuid = pn->cred[3];
|
||||
proc->rgid = pn->cred[4];
|
||||
proc->egid = pn->cred[5];
|
||||
proc->sgid = pn->cred[6];
|
||||
proc->fsgid = pn->cred[7];
|
||||
|
||||
proc->vm->region.user_start = pn->user_start;
|
||||
proc->vm->region.user_end = pn->user_end;
|
||||
proc->vm->region.map_start = (USER_END / 3) & LARGE_PAGE_MASK;
|
||||
proc->vm->region.map_end = proc->vm->region.map_start;
|
||||
vm->region.user_start = pn->user_start;
|
||||
vm->region.user_end = pn->user_end;
|
||||
vm->region.map_start = (USER_END / 3) & LARGE_PAGE_MASK;
|
||||
vm->region.map_end = proc->vm->region.map_start;
|
||||
memcpy(proc->rlimit, pn->rlimit, sizeof(struct rlimit) * MCK_RLIM_MAX);
|
||||
|
||||
/* TODO: Clear it at the proper timing */
|
||||
cpu_local_var(scp).post_idx = 0;
|
||||
|
||||
if (prepare_process_ranges_args_envs(proc, pn, p, attr,
|
||||
if (prepare_process_ranges_args_envs(thread, pn, p, attr,
|
||||
NULL, 0, NULL, 0) != 0) {
|
||||
kprintf("error: preparing process ranges, args, envs, stack\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
dkprintf("new process : %p [%d] / table : %p\n", proc, proc->ftn->pid,
|
||||
proc->vm->page_table);
|
||||
dkprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
|
||||
vm->address_space->page_table);
|
||||
|
||||
ihk_mc_free(pn);
|
||||
|
||||
@@ -401,8 +408,7 @@ err:
|
||||
ihk_mc_free(pn);
|
||||
ihk_mc_unmap_virtual(p, npages, 1);
|
||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||
free_process_memory(proc);
|
||||
destroy_process(proc);
|
||||
destroy_thread(thread);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -476,8 +482,8 @@ static void syscall_channel_send(struct ihk_ikc_channel_desc *c,
|
||||
ihk_ikc_send(c, packet, 0);
|
||||
}
|
||||
|
||||
extern unsigned long do_kill(int, int, int, struct siginfo *, int ptracecont);
|
||||
extern void settid(struct process *proc, int mode, int newcpuid, int oldcpuid);
|
||||
extern unsigned long do_kill(struct thread *, int, int, int, struct siginfo *, int ptracecont);
|
||||
extern void settid(struct thread *proc, int mode, int newcpuid, int oldcpuid);
|
||||
|
||||
extern void process_procfs_request(unsigned long rarg);
|
||||
extern int memcheckall();
|
||||
@@ -492,6 +498,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
struct ikc_scd_packet *packet = __packet;
|
||||
struct ikc_scd_packet pckt;
|
||||
int rc;
|
||||
struct thread *thread;
|
||||
struct process *proc;
|
||||
struct mcctrl_signal {
|
||||
int cond;
|
||||
@@ -539,13 +546,17 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
return -1;
|
||||
}
|
||||
dkprintf("SCD_MSG_SCHEDULE_PROCESS: %lx\n", packet->arg);
|
||||
proc = (struct process *)packet->arg;
|
||||
thread = (struct thread *)packet->arg;
|
||||
proc = thread->proc;
|
||||
|
||||
settid(proc, 0, cpuid, -1);
|
||||
proc->ftn->status = PS_RUNNING;
|
||||
runq_add_proc(proc, cpuid);
|
||||
settid(thread, 0, cpuid, -1);
|
||||
proc->pstatus = PS_RUNNING;
|
||||
thread->tstatus = PS_RUNNING;
|
||||
chain_thread(thread);
|
||||
chain_process(proc);
|
||||
runq_add_thread(thread, cpuid);
|
||||
|
||||
//cpu_local_var(next) = (struct process *)packet->arg;
|
||||
//cpu_local_var(next) = (struct thread *)packet->arg;
|
||||
return 0;
|
||||
case SCD_MSG_SEND_SIGNAL:
|
||||
pp = ihk_mc_map_memory(NULL, packet->arg, sizeof(struct mcctrl_signal));
|
||||
@@ -559,7 +570,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
pckt.arg = packet->arg;
|
||||
syscall_channel_send(c, &pckt);
|
||||
|
||||
rc = do_kill(info.pid, info.tid, info.sig, &info.info, 0);
|
||||
rc = do_kill(NULL, info.pid, info.tid, info.sig, &info.info, 0);
|
||||
kprintf("SCD_MSG_SEND_SIGNAL: do_kill(pid=%d, tid=%d, sig=%d)=%d\n", info.pid, info.tid, info.sig, rc);
|
||||
return 0;
|
||||
case SCD_MSG_PROCFS_REQUEST:
|
||||
|
||||
@@ -41,13 +41,14 @@ struct cpu_local_var {
|
||||
struct malloc_header free_list;
|
||||
ihk_spinlock_t free_list_lock;
|
||||
|
||||
struct process idle;
|
||||
struct fork_tree_node idle_ftn;
|
||||
struct thread idle;
|
||||
struct process idle_proc;
|
||||
struct process_vm idle_vm;
|
||||
struct address_space idle_asp;
|
||||
|
||||
ihk_spinlock_t runq_lock;
|
||||
unsigned long runq_irqstate;
|
||||
struct process *current;
|
||||
struct thread *current;
|
||||
struct list_head runq;
|
||||
size_t runq_len;
|
||||
|
||||
@@ -58,6 +59,7 @@ struct cpu_local_var {
|
||||
struct ihk_ikc_channel_desc *syscall_channel2;
|
||||
struct syscall_params scp2;
|
||||
struct ikc_scd_init_param iip2;
|
||||
struct resource_set *resource_set;
|
||||
|
||||
int status;
|
||||
int fs;
|
||||
|
||||
@@ -14,8 +14,18 @@
|
||||
#define __HEADER_KMALLOC_H
|
||||
|
||||
#include <ihk/mm.h>
|
||||
#include <cls.h>
|
||||
|
||||
#define kmalloc(size, flag) _kmalloc(size, flag, __FILE__, __LINE__)
|
||||
void panic(const char *);
|
||||
int kprintf(const char *format, ...);
|
||||
|
||||
#define kmalloc(size, flag) ({\
|
||||
void *r = _kmalloc(size, flag, __FILE__, __LINE__);\
|
||||
if(r == NULL){\
|
||||
kprintf("kmalloc: out of memory %s:%d no_preempt=%d\n", __FILE__, __LINE__, cpu_local_var(no_preempt)); \
|
||||
}\
|
||||
r;\
|
||||
})
|
||||
#define kfree(ptr) _kfree(ptr, __FILE__, __LINE__)
|
||||
#define memcheck(ptr, msg) _memcheck(ptr, msg, __FILE__, __LINE__, 0)
|
||||
void *_kmalloc(int size, enum ihk_mc_ap_flag flag, char *file, int line);
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#define VRFLAG_PROT_TO_MAXPROT(vrflag) (((vrflag) & VR_PROT_MASK) << 4)
|
||||
#define VRFLAG_MAXPROT_TO_PROT(vrflag) (((vrflag) & VR_MAXPROT_MASK) >> 4)
|
||||
|
||||
// struct process.status, struct thread.status
|
||||
#define PS_RUNNING 0x1
|
||||
#define PS_INTERRUPTIBLE 0x2
|
||||
#define PS_UNINTERRUPTIBLE 0x4
|
||||
@@ -58,15 +59,19 @@
|
||||
#define PS_EXITED 0x10
|
||||
#define PS_STOPPED 0x20
|
||||
#define PS_TRACED 0x40 /* Set to "not running" by a ptrace related event */
|
||||
#define PS_STOPPING 0x80
|
||||
#define PS_TRACING 0x100
|
||||
|
||||
#define PS_NORMAL (PS_INTERRUPTIBLE | PS_UNINTERRUPTIBLE)
|
||||
|
||||
// struct process.ptrace
|
||||
#define PT_TRACED 0x80 /* The process is ptraced */
|
||||
#define PT_TRACE_EXEC 0x100 /* Trace execve(2) */
|
||||
#define PT_TRACE_SYSCALL_ENTER 0x200 /* Trace syscall enter */
|
||||
#define PT_TRACE_SYSCALL_EXIT 0x400 /* Trace syscall exit */
|
||||
#define PT_TRACE_SYSCALL_MASK (PT_TRACE_SYSCALL_ENTER | PT_TRACE_SYSCALL_EXIT)
|
||||
|
||||
// ptrace(2) request
|
||||
#define PTRACE_TRACEME 0
|
||||
#define PTRACE_PEEKTEXT 1
|
||||
#define PTRACE_PEEKDATA 2
|
||||
@@ -95,6 +100,7 @@
|
||||
#define PTRACE_GETREGSET 0x4204
|
||||
#define PTRACE_SETREGSET 0x4205
|
||||
|
||||
// ptrace(2) options
|
||||
#define PTRACE_O_TRACESYSGOOD 1
|
||||
#define PTRACE_O_TRACEFORK 2
|
||||
#define PTRACE_O_TRACEVFORK 4
|
||||
@@ -104,6 +110,7 @@
|
||||
#define PTRACE_O_TRACEEXIT 0x40
|
||||
#define PTRACE_O_MASK 0x7f
|
||||
|
||||
// ptrace(2) events
|
||||
#define PTRACE_EVENT_FORK 1
|
||||
#define PTRACE_EVENT_VFORK 2
|
||||
#define PTRACE_EVENT_CLONE 3
|
||||
@@ -158,6 +165,66 @@
|
||||
#include <waitq.h>
|
||||
#include <futex.h>
|
||||
|
||||
struct resource_set;
|
||||
struct process_hash;
|
||||
struct thread_hash;
|
||||
struct address_space;
|
||||
struct process;
|
||||
struct thread;
|
||||
struct process_vm;
|
||||
struct vm_regions;
|
||||
struct vm_range;
|
||||
|
||||
#define HASH_SIZE 73
|
||||
|
||||
struct resource_set {
|
||||
struct list_head list;
|
||||
char *path;
|
||||
struct process_hash *process_hash;
|
||||
struct thread_hash *thread_hash;
|
||||
struct list_head phys_mem_list;
|
||||
mcs_rwlock_lock_t phys_mem_lock;
|
||||
cpu_set_t cpu_set;
|
||||
mcs_rwlock_lock_t cpu_set_lock;
|
||||
struct process *pid1;
|
||||
};
|
||||
|
||||
extern struct list_head resource_set_list;
|
||||
extern mcs_rwlock_lock_t resource_set_lock;
|
||||
|
||||
struct process_hash {
|
||||
struct list_head list[HASH_SIZE];
|
||||
mcs_rwlock_lock_t lock[HASH_SIZE];
|
||||
};
|
||||
|
||||
static inline int
|
||||
process_hash(int pid)
|
||||
{
|
||||
return pid % HASH_SIZE;
|
||||
}
|
||||
|
||||
static inline int
|
||||
thread_hash(int tid)
|
||||
{
|
||||
return tid % HASH_SIZE;
|
||||
}
|
||||
|
||||
struct thread_hash {
|
||||
struct list_head list[HASH_SIZE];
|
||||
mcs_rwlock_lock_t lock[HASH_SIZE];
|
||||
};
|
||||
|
||||
struct address_space {
|
||||
struct page_table *page_table;
|
||||
struct list_head siblings_list;
|
||||
struct resource_set *res;
|
||||
int type;
|
||||
#define ADDRESS_SPACE_NORMAL 1
|
||||
#define ADDRESS_SPACE_PVAS 2
|
||||
int nslots;
|
||||
int pids[];
|
||||
};
|
||||
|
||||
struct user_fpregs_struct
|
||||
{
|
||||
unsigned short cwd;
|
||||
@@ -234,6 +301,7 @@ struct vm_range {
|
||||
};
|
||||
|
||||
struct vm_regions {
|
||||
unsigned long vm_start, vm_end;
|
||||
unsigned long text_start, text_end;
|
||||
unsigned long data_start, data_end;
|
||||
unsigned long brk_start, brk_end;
|
||||
@@ -252,11 +320,12 @@ struct sigfd {
|
||||
#define SFD_CLOEXEC 02000000
|
||||
#define SFD_NONBLOCK 04000
|
||||
|
||||
struct sig_handler {
|
||||
struct sig_common {
|
||||
ihk_spinlock_t lock;
|
||||
ihk_atomic_t use;
|
||||
ihk_atomic_t use;
|
||||
struct sigfd *sigfd;
|
||||
struct k_sigaction action[_NSIG];
|
||||
struct list_head sigpending;
|
||||
};
|
||||
|
||||
struct sig_pending {
|
||||
@@ -266,27 +335,60 @@ struct sig_pending {
|
||||
int ptracecont;
|
||||
};
|
||||
|
||||
struct sig_shared {
|
||||
ihk_spinlock_t lock;
|
||||
ihk_atomic_t use;
|
||||
struct list_head sigpending;
|
||||
};
|
||||
|
||||
typedef void pgio_func_t(void *arg);
|
||||
|
||||
/* Represents a node in the process fork tree, it may exist even after the
|
||||
* corresponding process exited due to references from the parent and/or
|
||||
* children and is used for implementing wait/waitpid without having a
|
||||
* special "init" process */
|
||||
struct fork_tree_node {
|
||||
ihk_spinlock_t lock;
|
||||
ihk_atomic_t refcount;
|
||||
int exit_status;
|
||||
int status;
|
||||
struct process {
|
||||
struct list_head hash_list;
|
||||
mcs_rwlock_lock_t update_lock; // lock for parent, status, ...?
|
||||
|
||||
struct process *owner;
|
||||
// process vm
|
||||
struct process_vm *vm;
|
||||
|
||||
// threads and children
|
||||
struct list_head threads_list;
|
||||
mcs_rwlock_lock_t threads_lock; // lock for threads_list
|
||||
|
||||
/* The ptracing process behave as the parent of the ptraced process
|
||||
after using PTRACE_ATTACH except getppid. So we save it here. */
|
||||
struct process *parent;
|
||||
struct process *ppid_parent;
|
||||
struct list_head children_list;
|
||||
struct list_head ptraced_children_list;
|
||||
mcs_rwlock_lock_t children_lock; // lock for children_list and ptraced_children_list
|
||||
struct list_head siblings_list; // lock parent
|
||||
struct list_head ptraced_siblings_list; // lock ppid_parent
|
||||
|
||||
ihk_atomic_t refcount;
|
||||
|
||||
// process status and exit status
|
||||
int pstatus; // PS_RUNNING -> PS_EXITED -> PS_ZOMBIE
|
||||
// | ^ ^
|
||||
// | |---+ |
|
||||
// V | |
|
||||
// PS_STOPPING | |
|
||||
// (PS_TRACING)| |
|
||||
// | | |
|
||||
// V +---- |
|
||||
// PS_STOPPED -----+
|
||||
// (PS_TRACED)
|
||||
int exit_status;
|
||||
|
||||
/* Store exit_status for a group of threads when stopped by SIGSTOP.
|
||||
exit_status can't be used because values of exit_status of threads
|
||||
might divert while the threads are exiting by group_exit(). */
|
||||
int group_exit_status;
|
||||
|
||||
/* Manage ptraced processes in the separate list to make it easy to
|
||||
restore the orginal parent child relationship when
|
||||
performing PTRACE_DETACH */
|
||||
struct waitq waitpid_q;
|
||||
|
||||
// process info and credentials etc.
|
||||
int pid;
|
||||
int tid;
|
||||
int pgid;
|
||||
int ruid;
|
||||
int euid;
|
||||
@@ -296,50 +398,36 @@ struct fork_tree_node {
|
||||
int egid;
|
||||
int sgid;
|
||||
int fsgid;
|
||||
|
||||
struct fork_tree_node *parent;
|
||||
struct list_head children;
|
||||
struct list_head siblings_list;
|
||||
|
||||
/* The ptracing process behave as the parent of the ptraced process
|
||||
after using PTRACE_ATTACH except getppid. So we save it here. */
|
||||
struct fork_tree_node *ppid_parent;
|
||||
int execed;
|
||||
int nohost;
|
||||
struct rlimit rlimit[MCK_RLIM_MAX];
|
||||
unsigned long saved_auxv[AUXV_LEN];
|
||||
char *saved_cmdline;
|
||||
long saved_cmdline_len;
|
||||
|
||||
/* Manage ptraced processes in the separate list to make it easy to
|
||||
restore the orginal parent child relationship when
|
||||
performing PTRACE_DETACH */
|
||||
struct list_head ptrace_children;
|
||||
struct list_head ptrace_siblings_list;
|
||||
/* Store ptrace flags.
|
||||
* The lower 8 bits are PTRACE_O_xxx of the PTRACE_SETOPTIONS request.
|
||||
* Other bits are for inner use of the McKernel.
|
||||
*/
|
||||
int ptrace;
|
||||
|
||||
struct waitq waitpid_q;
|
||||
/* Store ptrace event message.
|
||||
* PTRACE_O_xxx will store event message here.
|
||||
* PTRACE_GETEVENTMSG will get from here.
|
||||
*/
|
||||
unsigned long ptrace_eventmsg;
|
||||
|
||||
/* Store exit_status for a group of threads when stopped by SIGSTOP.
|
||||
exit_status can't be used because values of exit_status of threads
|
||||
might divert while the threads are exiting by group_exit(). */
|
||||
int group_exit_status;
|
||||
/* Store event related to signal. For example,
|
||||
it represents that the proceess has been resumed by SIGCONT. */
|
||||
int signal_flags;
|
||||
|
||||
/* Store ptrace flags.
|
||||
* The lower 8 bits are PTRACE_O_xxx of the PTRACE_SETOPTIONS request.
|
||||
* Other bits are for inner use of the McKernel.
|
||||
*/
|
||||
int ptrace;
|
||||
/* Store signal sent to parent when the process terminates. */
|
||||
int termsig;
|
||||
|
||||
/* Store ptrace event message.
|
||||
PTRACE_O_xxx will store event message here.
|
||||
PTRACE_GETEVENTMSG will get from here.
|
||||
*/
|
||||
unsigned long ptrace_eventmsg;
|
||||
|
||||
/* Store event related to signal. For example,
|
||||
it represents that the proceess has been resumed by SIGCONT. */
|
||||
int signal_flags;
|
||||
|
||||
/* Store signal sent to parent when the process terminates. */
|
||||
int termsig;
|
||||
};
|
||||
|
||||
void hold_fork_tree_node(struct fork_tree_node *ftn);
|
||||
void release_fork_tree_node(struct fork_tree_node *ftn);
|
||||
void hold_thread(struct thread *ftn);
|
||||
void release_thread(struct thread *ftn);
|
||||
|
||||
/*
|
||||
* Scheduling policies
|
||||
@@ -364,101 +452,109 @@ struct sched_param {
|
||||
int sched_priority;
|
||||
};
|
||||
|
||||
struct process {
|
||||
struct thread {
|
||||
struct list_head hash_list;
|
||||
// thread info
|
||||
int cpu_id;
|
||||
int tid;
|
||||
int tstatus;
|
||||
|
||||
ihk_atomic_t refcount;
|
||||
// process vm
|
||||
struct process_vm *vm;
|
||||
|
||||
// context
|
||||
ihk_mc_kernel_context_t ctx;
|
||||
ihk_mc_user_context_t *uctx;
|
||||
|
||||
// sibling
|
||||
struct process *proc;
|
||||
struct list_head siblings_list; // lock process
|
||||
|
||||
// Runqueue list entry
|
||||
struct list_head sched_list;
|
||||
struct list_head sched_list; // lock cls
|
||||
int sched_policy;
|
||||
struct sched_param sched_param;
|
||||
|
||||
ihk_spinlock_t spin_sleep_lock;
|
||||
int spin_sleep;
|
||||
|
||||
struct thread {
|
||||
ihk_atomic_t refcount;
|
||||
|
||||
struct {
|
||||
int *clear_child_tid;
|
||||
unsigned long tlsblock_base, tlsblock_limit;
|
||||
} thread;
|
||||
|
||||
volatile int sigevent;
|
||||
int nohost;
|
||||
int execed;
|
||||
// thread info
|
||||
cpu_set_t cpu_set;
|
||||
fp_regs_struct *fp_regs;
|
||||
int in_syscall_offload;
|
||||
|
||||
// signal
|
||||
struct sig_common *sigcommon;
|
||||
sigset_t sigmask;
|
||||
stack_t sigstack;
|
||||
ihk_spinlock_t sigpendinglock;
|
||||
struct list_head sigpending;
|
||||
struct sig_shared *sigshared;
|
||||
struct sig_handler *sighandler;
|
||||
ihk_spinlock_t sigpendinglock;
|
||||
volatile int sigevent;
|
||||
|
||||
struct rlimit rlimit[MCK_RLIM_MAX];
|
||||
// gpio
|
||||
pgio_func_t *pgio_fp;
|
||||
void *pgio_arg;
|
||||
|
||||
struct fork_tree_node *ftn;
|
||||
|
||||
cpu_set_t cpu_set;
|
||||
unsigned long saved_auxv[AUXV_LEN];
|
||||
|
||||
// for ptrace
|
||||
unsigned long *ptrace_debugreg; /* debug registers for ptrace */
|
||||
struct sig_pending *ptrace_recvsig;
|
||||
struct sig_pending *ptrace_sendsig;
|
||||
fp_regs_struct *fp_regs;
|
||||
char *saved_cmdline;
|
||||
long saved_cmdline_len;
|
||||
int in_syscall_offload;
|
||||
};
|
||||
|
||||
struct process_vm {
|
||||
ihk_atomic_t refcount;
|
||||
|
||||
struct page_table *page_table;
|
||||
struct address_space *address_space;
|
||||
struct list_head vm_range_list;
|
||||
struct vm_regions region;
|
||||
struct process *owner_process; /* process that reside on the same page */
|
||||
struct process *proc; /* process that reside on the same page */
|
||||
|
||||
ihk_spinlock_t page_table_lock;
|
||||
ihk_spinlock_t memory_range_lock;
|
||||
ihk_spinlock_t page_table_lock;
|
||||
ihk_spinlock_t memory_range_lock;
|
||||
// to protect the followings:
|
||||
// 1. addition of process "memory range" (extend_process_region, add_process_memory_range)
|
||||
// 2. addition of process page table (allocate_pages, update_process_page_table)
|
||||
// note that physical memory allocator (ihk_mc_alloc_pages, ihk_pagealloc_alloc)
|
||||
// is protected by its own lock (see ihk/manycore/generic/page_alloc.c)
|
||||
|
||||
ihk_atomic_t refcount;
|
||||
cpu_set_t cpu_set;
|
||||
ihk_spinlock_t cpu_set_lock;
|
||||
int exiting;
|
||||
};
|
||||
|
||||
|
||||
struct process *create_process(unsigned long user_pc);
|
||||
struct process *clone_process(struct process *org, unsigned long pc,
|
||||
struct thread *create_thread(unsigned long user_pc);
|
||||
struct thread *clone_thread(struct thread *org, unsigned long pc,
|
||||
unsigned long sp, int clone_flags);
|
||||
void destroy_process(struct process *proc);
|
||||
void hold_process(struct process *proc);
|
||||
void release_process(struct process *proc);
|
||||
void flush_process_memory(struct process *proc);
|
||||
void free_process_memory(struct process *proc);
|
||||
void free_process_memory_ranges(struct process *proc);
|
||||
int populate_process_memory(struct process *proc, void *start, size_t len);
|
||||
void destroy_thread(struct thread *thread);
|
||||
void hold_thread(struct thread *thread);
|
||||
void release_thread(struct thread *thread);
|
||||
void flush_process_memory(struct process_vm *vm);
|
||||
void hold_process_vm(struct process_vm *vm);
|
||||
void release_process_vm(struct process_vm *vm);
|
||||
void hold_process(struct process *);
|
||||
void release_process(struct process *);
|
||||
void free_process_memory_ranges(struct process_vm *vm);
|
||||
int populate_process_memory(struct process_vm *vm, void *start, size_t len);
|
||||
|
||||
int add_process_memory_range(struct process *process,
|
||||
int add_process_memory_range(struct process_vm *vm,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long phys, unsigned long flag,
|
||||
struct memobj *memobj, off_t objoff);
|
||||
int remove_process_memory_range(struct process *process, unsigned long start,
|
||||
int remove_process_memory_range(struct process_vm *vm, unsigned long start,
|
||||
unsigned long end, int *ro_freedp);
|
||||
int split_process_memory_range(struct process *process,
|
||||
int split_process_memory_range(struct process_vm *vm,
|
||||
struct vm_range *range, uintptr_t addr, struct vm_range **splitp);
|
||||
int join_process_memory_range(struct process *process, struct vm_range *surviving,
|
||||
int join_process_memory_range(struct process_vm *vm, struct vm_range *surviving,
|
||||
struct vm_range *merging);
|
||||
int change_prot_process_memory_range(
|
||||
struct process *process, struct vm_range *range,
|
||||
struct process_vm *vm, struct vm_range *range,
|
||||
unsigned long newflag);
|
||||
int remap_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
uintptr_t start, uintptr_t end, off_t off);
|
||||
@@ -477,24 +573,24 @@ int extend_up_process_memory_range(struct process_vm *vm,
|
||||
|
||||
int page_fault_process_vm(struct process_vm *fault_vm, void *fault_addr,
|
||||
uint64_t reason);
|
||||
int remove_process_region(struct process *proc,
|
||||
int remove_process_region(struct process_vm *vm,
|
||||
unsigned long start, unsigned long end);
|
||||
struct program_load_desc;
|
||||
int init_process_stack(struct process *process, struct program_load_desc *pn,
|
||||
int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
int argc, char **argv,
|
||||
int envc, char **env);
|
||||
unsigned long extend_process_region(struct process *proc,
|
||||
unsigned long extend_process_region(struct process_vm *vm,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long address, unsigned long flag);
|
||||
extern enum ihk_mc_pt_attribute arch_vrflag_to_ptattr(unsigned long flag, uint64_t fault, pte_t *ptep);
|
||||
enum ihk_mc_pt_attribute common_vrflag_to_ptattr(unsigned long flag, uint64_t fault, pte_t *ptep);
|
||||
|
||||
void schedule(void);
|
||||
void runq_add_proc(struct process *proc, int cpu_id);
|
||||
void runq_del_proc(struct process *proc, int cpu_id);
|
||||
int sched_wakeup_process(struct process *proc, int valid_states);
|
||||
void runq_add_thread(struct thread *thread, int cpu_id);
|
||||
void runq_del_thread(struct thread *thread, int cpu_id);
|
||||
int sched_wakeup_thread(struct thread *thread, int valid_states);
|
||||
|
||||
void sched_request_migrate(int cpu_id, struct process *proc);
|
||||
void sched_request_migrate(int cpu_id, struct thread *thread);
|
||||
void check_need_resched(void);
|
||||
|
||||
void cpu_set(int cpu, cpu_set_t *cpu_set, ihk_spinlock_t *lock);
|
||||
@@ -502,8 +598,14 @@ void cpu_clear(int cpu, cpu_set_t *cpu_set, ihk_spinlock_t *lock);
|
||||
void cpu_clear_and_set(int c_cpu, int s_cpu,
|
||||
cpu_set_t *cpu_set, ihk_spinlock_t *lock);
|
||||
|
||||
struct process *findthread_and_lock(int pid, int tid, ihk_spinlock_t **savelock, unsigned long *irqstate);
|
||||
void process_unlock(void *savelock, unsigned long irqstate);
|
||||
void release_cpuid(int cpuid);
|
||||
|
||||
struct thread *find_thread(int pid, int tid, struct mcs_rwlock_node_irqsave *lock);
|
||||
void thread_unlock(struct thread *thread, struct mcs_rwlock_node_irqsave *lock);
|
||||
struct process *find_process(int pid, struct mcs_rwlock_node_irqsave *lock);
|
||||
void process_unlock(struct process *proc, struct mcs_rwlock_node_irqsave *lock);
|
||||
void chain_process(struct process *);
|
||||
void chain_thread(struct thread *);
|
||||
void proc_init();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -285,4 +285,5 @@ struct procfs_file {
|
||||
char fname[PROCFS_NAME_MAX]; /* procfs filename (request) */
|
||||
};
|
||||
|
||||
extern void terminate(int, int);
|
||||
#endif
|
||||
|
||||
@@ -36,7 +36,7 @@ struct timer {
|
||||
uint64_t timeout;
|
||||
struct waitq processes;
|
||||
struct list_head list;
|
||||
struct process *proc;
|
||||
struct thread *thread;
|
||||
};
|
||||
|
||||
uint64_t schedule_timeout(uint64_t timeout);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <ihk/lock.h>
|
||||
#include <list.h>
|
||||
|
||||
struct process;
|
||||
struct thread;
|
||||
struct waitq_entry;
|
||||
|
||||
typedef int (*waitq_func_t)(struct waitq_entry *wait, unsigned mode,
|
||||
@@ -58,7 +58,7 @@ typedef struct waitq_entry {
|
||||
}
|
||||
|
||||
extern void waitq_init(waitq_t *waitq);
|
||||
extern void waitq_init_entry(waitq_entry_t *entry, struct process *proc);
|
||||
extern void waitq_init_entry(waitq_entry_t *entry, struct thread *proc);
|
||||
extern int waitq_active(waitq_t *waitq);
|
||||
extern void waitq_add_entry(waitq_t *waitq, waitq_entry_t *entry);
|
||||
extern void waitq_add_entry_locked(waitq_t *waitq, waitq_entry_t *entry);
|
||||
|
||||
@@ -225,6 +225,8 @@ static void rest_init(void)
|
||||
|
||||
ikc_master_init();
|
||||
|
||||
proc_init();
|
||||
|
||||
sched_init();
|
||||
}
|
||||
|
||||
|
||||
38
kernel/mem.c
38
kernel/mem.c
@@ -174,7 +174,7 @@ static struct ihk_mc_interrupt_handler query_free_mem_handler = {
|
||||
|
||||
void set_signal(int sig, void *regs, struct siginfo *info);
|
||||
void check_signal(unsigned long, void *, int);
|
||||
int gencore(struct process *, void *, struct coretable **, int *);
|
||||
int gencore(struct thread *, void *, struct coretable **, int *);
|
||||
void freecore(struct coretable **);
|
||||
|
||||
/**
|
||||
@@ -184,14 +184,14 @@ void freecore(struct coretable **);
|
||||
* \param regs A pointer to a x86_regs structure.
|
||||
*/
|
||||
|
||||
void coredump(struct process *proc, void *regs)
|
||||
void coredump(struct thread *thread, void *regs)
|
||||
{
|
||||
struct syscall_request request IHK_DMA_ALIGN;
|
||||
int ret;
|
||||
struct coretable *coretable;
|
||||
int chunks;
|
||||
|
||||
ret = gencore(proc, regs, &coretable, &chunks);
|
||||
ret = gencore(thread, regs, &coretable, &chunks);
|
||||
if (ret != 0) {
|
||||
dkprintf("could not generate a core file image\n");
|
||||
return;
|
||||
@@ -200,7 +200,7 @@ void coredump(struct process *proc, void *regs)
|
||||
request.args[0] = chunks;
|
||||
request.args[1] = virt_to_phys(coretable);
|
||||
/* no data for now */
|
||||
ret = do_syscall(&request, proc->cpu_id, proc->ftn->pid);
|
||||
ret = do_syscall(&request, thread->cpu_id, thread->proc->pid);
|
||||
if (ret == 0) {
|
||||
kprintf("dumped core.\n");
|
||||
} else {
|
||||
@@ -209,10 +209,10 @@ void coredump(struct process *proc, void *regs)
|
||||
freecore(&coretable);
|
||||
}
|
||||
|
||||
static void unhandled_page_fault(struct process *proc, void *fault_addr, void *regs)
|
||||
static void unhandled_page_fault(struct thread *thread, void *fault_addr, void *regs)
|
||||
{
|
||||
const uintptr_t address = (uintptr_t)fault_addr;
|
||||
struct process_vm *vm = proc->vm;
|
||||
struct process_vm *vm = thread->vm;
|
||||
struct vm_range *range;
|
||||
char found;
|
||||
unsigned long irqflags;
|
||||
@@ -235,7 +235,7 @@ static void unhandled_page_fault(struct process *proc, void *fault_addr, void *r
|
||||
found = 1;
|
||||
dkprintf("address is in range, flag: 0x%X! \n",
|
||||
range->flag);
|
||||
ihk_mc_pt_print_pte(vm->page_table, (void*)address);
|
||||
ihk_mc_pt_print_pte(vm->address_space->page_table, (void*)address);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -366,7 +366,7 @@ void tlb_flush_handler(int vector)
|
||||
|
||||
static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
|
||||
{
|
||||
struct process *proc = cpu_local_var(current);
|
||||
struct thread *thread = cpu_local_var(current);
|
||||
int error;
|
||||
|
||||
dkprintf("[%d]page_fault_handler(%p,%lx,%p)\n",
|
||||
@@ -376,29 +376,24 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
|
||||
|
||||
cpu_enable_interrupt();
|
||||
|
||||
error = page_fault_process_vm(proc->vm, fault_addr, reason);
|
||||
error = page_fault_process_vm(thread->vm, fault_addr, reason);
|
||||
if (error) {
|
||||
struct siginfo info;
|
||||
|
||||
if (error == -ECANCELED) {
|
||||
dkprintf("process is exiting, terminate.\n");
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&proc->ftn->lock);
|
||||
proc->ftn->status = PS_ZOMBIE;
|
||||
ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock);
|
||||
release_fork_tree_node(proc->ftn->parent);
|
||||
release_fork_tree_node(proc->ftn);
|
||||
release_process(proc);
|
||||
|
||||
preempt_enable();
|
||||
schedule();
|
||||
terminate(0, SIGSEGV);
|
||||
// no return
|
||||
}
|
||||
|
||||
kprintf("[%d]page_fault_handler(%p,%lx,%p):"
|
||||
"fault vm failed. %d, TID: %d\n",
|
||||
ihk_mc_get_processor_id(), fault_addr,
|
||||
reason, regs, error, proc->ftn->tid);
|
||||
unhandled_page_fault(proc, fault_addr, regs);
|
||||
reason, regs, error, thread->tid);
|
||||
unhandled_page_fault(thread, fault_addr, regs);
|
||||
preempt_enable();
|
||||
memset(&info, '\0', sizeof info);
|
||||
if (error == -ERANGE) {
|
||||
info.si_signo = SIGBUS;
|
||||
@@ -407,7 +402,7 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
|
||||
set_signal(SIGBUS, regs, &info);
|
||||
}
|
||||
else {
|
||||
struct process_vm *vm = proc->vm;
|
||||
struct process_vm *vm = thread->vm;
|
||||
struct vm_range *range;
|
||||
|
||||
info.si_signo = SIGSEGV;
|
||||
@@ -421,7 +416,6 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
|
||||
info._sifields._sigfault.si_addr = fault_addr;
|
||||
set_signal(SIGSEGV, regs, &info);
|
||||
}
|
||||
preempt_enable();
|
||||
check_signal(0, regs, 0);
|
||||
goto out;
|
||||
}
|
||||
@@ -880,12 +874,10 @@ int memcheckall()
|
||||
struct alloc *ap;
|
||||
int r = 0;
|
||||
|
||||
kprintf("memcheckall\n");
|
||||
for(i = 0; i < HASHNUM; i++)
|
||||
for(ap = allochash[i]; ap; ap = ap->next)
|
||||
if(ap->p)
|
||||
r |= _memcheck(ap->p + 1, "memcheck", NULL, 0, 2);
|
||||
kprintf("done\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
1495
kernel/process.c
1495
kernel/process.c
File diff suppressed because it is too large
Load Diff
@@ -257,14 +257,14 @@ static void operate_proc_procfs_file(int pid, char *fname, int msg, int mode, in
|
||||
void process_procfs_request(unsigned long rarg)
|
||||
{
|
||||
unsigned long parg, pbuf;
|
||||
struct process *proc = cpu_local_var(current);
|
||||
struct thread *thread = cpu_local_var(current);
|
||||
struct process *proc = thread->proc;
|
||||
struct procfs_read *r;
|
||||
struct ikc_scd_packet packet;
|
||||
int rosnum, ret, pid, tid, ans = -EIO, eof = 0;
|
||||
char *buf, *p;
|
||||
struct ihk_ikc_channel_desc *syscall_channel;
|
||||
ihk_spinlock_t *savelock;
|
||||
unsigned long irqstate;
|
||||
struct mcs_rwlock_node_irqsave lock;
|
||||
unsigned long offset;
|
||||
int count;
|
||||
int npages;
|
||||
@@ -336,30 +336,31 @@ void process_procfs_request(unsigned long rarg)
|
||||
*/
|
||||
ret = sscanf(p, "%d/", &pid);
|
||||
if (ret == 1) {
|
||||
if (pid != cpu_local_var(current)->ftn->pid) {
|
||||
if (pid != cpu_local_var(current)->proc->pid) {
|
||||
/* We are not located in the proper cpu for some reason. */
|
||||
|
||||
dprintf("mismatched pid. We are %d, but requested pid is %d.\n",
|
||||
pid, cpu_local_var(current)->pid);
|
||||
tid = pid; /* main thread */
|
||||
proc = findthread_and_lock(pid, tid, &savelock, &irqstate);
|
||||
if (!proc) {
|
||||
thread = find_thread(pid, tid, &lock);
|
||||
if (!thread) {
|
||||
dprintf("We cannot find the proper cpu for requested pid.\n");
|
||||
goto end;
|
||||
}
|
||||
else if (proc->cpu_id != ihk_mc_get_processor_id()) {
|
||||
else if (thread->cpu_id != ihk_mc_get_processor_id()) {
|
||||
/* The target process has gone by migration. */
|
||||
r->newcpu = proc->cpu_id;
|
||||
dprintf("expected cpu id is %d.\n", proc->cpu_id);
|
||||
process_unlock(savelock, irqstate);
|
||||
r->newcpu = thread->cpu_id;
|
||||
dprintf("expected cpu id is %d.\n", thread->cpu_id);
|
||||
thread_unlock(thread, &lock);
|
||||
ans = 0;
|
||||
goto end;
|
||||
}
|
||||
else {
|
||||
process_unlock(savelock, irqstate);
|
||||
thread_unlock(thread, &lock);
|
||||
/* 'proc' is not 'current' */
|
||||
is_current = 0;
|
||||
}
|
||||
proc = thread->proc;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(p, "stat")) { /* "/proc/stat" */
|
||||
@@ -431,7 +432,7 @@ void process_procfs_request(unsigned long rarg)
|
||||
ans = -EIO;
|
||||
goto end;
|
||||
}
|
||||
ret = ihk_mc_pt_virt_to_phys(vm->page_table,
|
||||
ret = ihk_mc_pt_virt_to_phys(vm->address_space->page_table,
|
||||
(void *)offset, &pa);
|
||||
if(ret){
|
||||
if(ans == 0)
|
||||
@@ -562,8 +563,8 @@ void process_procfs_request(unsigned long rarg)
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
while (start < end) {
|
||||
*_buf = ihk_mc_pt_virt_to_pagemap(proc->vm->page_table, start);
|
||||
dprintf("PID: %d, /proc/pagemap: 0x%lx -> %lx\n", proc->ftn->pid,
|
||||
*_buf = ihk_mc_pt_virt_to_pagemap(proc->vm->address_space->page_table, start);
|
||||
dprintf("PID: %d, /proc/pagemap: 0x%lx -> %lx\n", proc->proc->pid,
|
||||
start, *_buf);
|
||||
start += PAGE_SIZE;
|
||||
++_buf;
|
||||
@@ -586,7 +587,6 @@ void process_procfs_request(unsigned long rarg)
|
||||
unsigned long lockedsize = 0;
|
||||
char tmp[1024];
|
||||
int len;
|
||||
struct fork_tree_node *ftn = proc->ftn;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&proc->vm->memory_range_lock);
|
||||
list_for_each_entry(range, &proc->vm->vm_range_list, list) {
|
||||
@@ -599,8 +599,8 @@ void process_procfs_request(unsigned long rarg)
|
||||
"Uid:\t%d\t%d\t%d\t%d\n"
|
||||
"Gid:\t%d\t%d\t%d\t%d\n"
|
||||
"VmLck:\t%9lu kB\n",
|
||||
ftn->ruid, ftn->euid, ftn->suid, ftn->fsuid,
|
||||
ftn->rgid, ftn->egid, ftn->sgid, ftn->fsgid,
|
||||
proc->ruid, proc->euid, proc->suid, proc->fsuid,
|
||||
proc->rgid, proc->egid, proc->sgid, proc->fsgid,
|
||||
(lockedsize + 1023) >> 10);
|
||||
len = strlen(tmp);
|
||||
if (r->offset < len) {
|
||||
@@ -712,7 +712,7 @@ void process_procfs_request(unsigned long rarg)
|
||||
char tmp[1024];
|
||||
int len;
|
||||
|
||||
if ((proc = findthread_and_lock(pid, tid, &savelock, &irqstate))){
|
||||
if ((thread = find_thread(pid, tid, &lock))){
|
||||
dprintf("thread found! pid=%d tid=%d\n", pid, tid);
|
||||
/*
|
||||
* pid (comm) state ppid
|
||||
@@ -748,10 +748,10 @@ void process_procfs_request(unsigned long rarg)
|
||||
0L, 0L, 0L, 0L, // rsslim...
|
||||
0L, 0L, 0L, 0L, // kstkesp...
|
||||
0L, 0L, 0L, 0L, // sigignore...
|
||||
0L, 0, proc->cpu_id, 0, // cnswap...
|
||||
0L, 0, thread->cpu_id, 0, // cnswap...
|
||||
0, 0LL, 0L, 0L // policy...
|
||||
);
|
||||
process_unlock(savelock, irqstate);
|
||||
thread_unlock(thread, &lock);
|
||||
dprintf("tmp=%s\n", tmp);
|
||||
|
||||
len = strlen(tmp);
|
||||
|
||||
1914
kernel/syscall.c
1914
kernel/syscall.c
File diff suppressed because it is too large
Load Diff
@@ -57,14 +57,14 @@ uint64_t schedule_timeout(uint64_t timeout)
|
||||
{
|
||||
struct waitq_entry my_wait;
|
||||
struct timer my_timer;
|
||||
struct process *proc = cpu_local_var(current);
|
||||
struct thread *thread = cpu_local_var(current);
|
||||
int irqstate;
|
||||
int spin_sleep;
|
||||
|
||||
irqstate = ihk_mc_spinlock_lock(&proc->spin_sleep_lock);
|
||||
irqstate = ihk_mc_spinlock_lock(&thread->spin_sleep_lock);
|
||||
dkprintf("schedule_timeout() spin sleep timeout: %lu\n", timeout);
|
||||
spin_sleep = ++proc->spin_sleep;
|
||||
ihk_mc_spinlock_unlock(&proc->spin_sleep_lock, irqstate);
|
||||
spin_sleep = ++thread->spin_sleep;
|
||||
ihk_mc_spinlock_unlock(&thread->spin_sleep_lock, irqstate);
|
||||
|
||||
/* Spin sleep.. */
|
||||
for (;;) {
|
||||
@@ -72,10 +72,10 @@ uint64_t schedule_timeout(uint64_t timeout)
|
||||
uint64_t t_e;
|
||||
int spin_over = 0;
|
||||
|
||||
irqstate = ihk_mc_spinlock_lock(&proc->spin_sleep_lock);
|
||||
irqstate = ihk_mc_spinlock_lock(&thread->spin_sleep_lock);
|
||||
|
||||
/* Woken up by someone? */
|
||||
if (proc->spin_sleep < 1) {
|
||||
if (thread->spin_sleep < 1) {
|
||||
t_e = rdtsc();
|
||||
|
||||
spin_over = 1;
|
||||
@@ -87,7 +87,7 @@ uint64_t schedule_timeout(uint64_t timeout)
|
||||
}
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock(&proc->spin_sleep_lock, irqstate);
|
||||
ihk_mc_spinlock_unlock(&thread->spin_sleep_lock, irqstate);
|
||||
|
||||
if (!spin_over) {
|
||||
t_s = rdtsc();
|
||||
@@ -97,12 +97,12 @@ uint64_t schedule_timeout(uint64_t timeout)
|
||||
need_schedule = v->runq_len > 1 ? 1 : 0;
|
||||
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
|
||||
|
||||
/* Give a chance to another process (if any) in case the core is
|
||||
/* Give a chance to another thread (if any) in case the core is
|
||||
* oversubscribed, but make sure we will be re-scheduled */
|
||||
if (need_schedule) {
|
||||
xchg4(&(cpu_local_var(current)->ftn->status), PS_RUNNING);
|
||||
xchg4(&(cpu_local_var(current)->tstatus), PS_RUNNING);
|
||||
schedule();
|
||||
xchg4(&(cpu_local_var(current)->ftn->status),
|
||||
xchg4(&(cpu_local_var(current)->tstatus),
|
||||
PS_INTERRUPTIBLE);
|
||||
}
|
||||
else {
|
||||
@@ -125,7 +125,7 @@ uint64_t schedule_timeout(uint64_t timeout)
|
||||
dkprintf("schedule_timeout() spin woken up, timeout: %lu\n",
|
||||
timeout);
|
||||
|
||||
/* Give a chance to another process (if any) in case we timed out,
|
||||
/* Give a chance to another thread (if any) in case we timed out,
|
||||
* but make sure we will be re-scheduled */
|
||||
if (timeout == 0) {
|
||||
int need_schedule;
|
||||
@@ -137,18 +137,18 @@ uint64_t schedule_timeout(uint64_t timeout)
|
||||
ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate);
|
||||
|
||||
if (need_schedule) {
|
||||
xchg4(&(cpu_local_var(current)->ftn->status), PS_RUNNING);
|
||||
xchg4(&(cpu_local_var(current)->tstatus), PS_RUNNING);
|
||||
schedule();
|
||||
xchg4(&(cpu_local_var(current)->ftn->status),
|
||||
xchg4(&(cpu_local_var(current)->tstatus),
|
||||
PS_INTERRUPTIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
irqstate = ihk_mc_spinlock_lock(&proc->spin_sleep_lock);
|
||||
if (spin_sleep == proc->spin_sleep) {
|
||||
--proc->spin_sleep;
|
||||
irqstate = ihk_mc_spinlock_lock(&thread->spin_sleep_lock);
|
||||
if (spin_sleep == thread->spin_sleep) {
|
||||
--thread->spin_sleep;
|
||||
}
|
||||
ihk_mc_spinlock_unlock(&proc->spin_sleep_lock, irqstate);
|
||||
ihk_mc_spinlock_unlock(&thread->spin_sleep_lock, irqstate);
|
||||
|
||||
return timeout;
|
||||
}
|
||||
@@ -156,7 +156,7 @@ uint64_t schedule_timeout(uint64_t timeout)
|
||||
|
||||
/* Init waitq and wait entry for this timer */
|
||||
my_timer.timeout = (timeout < LOOP_TIMEOUT) ? LOOP_TIMEOUT : timeout;
|
||||
my_timer.proc = cpu_local_var(current);
|
||||
my_timer.thread = cpu_local_var(current);
|
||||
waitq_init(&my_timer.processes);
|
||||
waitq_init_entry(&my_wait, cpu_local_var(current));
|
||||
|
||||
@@ -213,7 +213,7 @@ void wake_timers_loop(void)
|
||||
list_del(&timer->list);
|
||||
|
||||
dkprintf("timers timeout occurred, waking up pid: %d\n",
|
||||
timer->proc->ftn->pid);
|
||||
timer->thread->proc->pid);
|
||||
|
||||
waitq_wakeup(&timer->processes);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ int
|
||||
default_wake_function(waitq_entry_t *entry, unsigned mode,
|
||||
int flags, void *key)
|
||||
{
|
||||
return sched_wakeup_process(entry->private, PS_NORMAL);
|
||||
return sched_wakeup_thread(entry->private, PS_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -30,7 +30,7 @@ waitq_init(waitq_t *waitq)
|
||||
}
|
||||
|
||||
void
|
||||
waitq_init_entry(waitq_entry_t *entry, struct process *proc)
|
||||
waitq_init_entry(waitq_entry_t *entry, struct thread *proc)
|
||||
{
|
||||
entry->private = proc;
|
||||
entry->func = default_wake_function;
|
||||
@@ -89,14 +89,14 @@ waitq_prepare_to_wait(waitq_t *waitq, waitq_entry_t *entry, int state)
|
||||
ihk_mc_spinlock_lock_noirq(&waitq->lock);
|
||||
if (list_empty(&entry->link))
|
||||
list_add(&entry->link, &waitq->waitq);
|
||||
cpu_local_var(current)->ftn->status = state;
|
||||
cpu_local_var(current)->tstatus = state;
|
||||
ihk_mc_spinlock_unlock_noirq(&waitq->lock);
|
||||
}
|
||||
|
||||
void
|
||||
waitq_finish_wait(waitq_t *waitq, waitq_entry_t *entry)
|
||||
{
|
||||
cpu_local_var(current)->ftn->status = PS_RUNNING;
|
||||
cpu_local_var(current)->tstatus = PS_RUNNING;
|
||||
waitq_remove_entry(waitq, entry);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user