diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/i386/Kconfig linux-2.6.7/arch/i386/Kconfig --- linux-2.6.7.org/arch/i386/Kconfig 2004-09-02 14:42:23.059468448 +0200 +++ linux-2.6.7/arch/i386/Kconfig 2004-09-02 14:46:53.790311104 +0200 @@ -1317,6 +1317,8 @@ source "crypto/Kconfig" +source "hpc/Kconfig" + source "lib/Kconfig" source "cluster/Kconfig" diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/i386/kernel/asm-offsets.c linux-2.6.7/arch/i386/kernel/asm-offsets.c --- linux-2.6.7.org/arch/i386/kernel/asm-offsets.c 2004-06-16 07:19:13.000000000 +0200 +++ linux-2.6.7/arch/i386/kernel/asm-offsets.c 2004-09-02 14:46:53.825305784 +0200 @@ -12,6 +12,7 @@ #include #include #include +#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -56,10 +57,19 @@ OFFSET(EXEC_DOMAIN_handler, exec_domain, handler); OFFSET(RT_SIGFRAME_sigcontext, rt_sigframe, uc.uc_mcontext); - + /* Offset from the sysenter stack to tss.esp0 */ DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) - sizeof(struct tss_struct)); DEFINE(PAGE_SIZE_asm, PAGE_SIZE); + +#ifdef CONFIG_OPENMOSIX + OFFSET(TASK_om, task_struct, om); + OFFSET(OM_dflags, openmosix_task, dflags); + BLANK(); + + DEFINE(DDEPUTY, DDEPUTY); + DEFINE(DREMOTE, DREMOTE); +#endif /* CONFIG_OPENMOSIX */ } diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/i386/kernel/entry.S linux-2.6.7/arch/i386/kernel/entry.S --- linux-2.6.7.org/arch/i386/kernel/entry.S 2004-06-16 07:19:02.000000000 +0200 +++ linux-2.6.7/arch/i386/kernel/entry.S 2004-09-02 14:46:53.830305024 +0200 @@ -49,6 +49,11 @@ #include #include "irq_vectors.h" +#ifdef CONFIG_OPENMOSIX +#include +#include "omasm.h" +#endif /* CONFIG_OPENMOSIX */ + #define nr_syscalls ((syscall_table_size)/4) EBX = 0x00 @@ -181,6 +186,12 @@ popl %eax jmp syscall_exit +#ifdef CONFIG_OPENMOSIX +ENTRY(ret_from_kickstart) + GET_THREAD_INFO(%ebp) + jmp syscall_exit +#endif /* CONFIG OPENMOSIX */ + /* * Return to user mode is not as complex as all this looks, * but we want the default path for a system call return to @@ -199,6 +210,14 @@ testl $(VM_MASK | 3), %eax jz resume_kernel # returning to kernel or vm86-space ENTRY(resume_userspace) +#ifdef CONFIG_OPENMOSIX + movl TI_task(%ebp), %ebp + testl $(DDEPUTY|DREMOTE), TASK_om+OM_dflags(%ebp) # is this MIGRATED ? + jz 1f + call openmosix_pre_usermode +1: + GET_THREAD_INFO(%ebp) +#endif /* CONFIG_OPENMOSIX */ cli # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret @@ -283,6 +302,18 @@ # system call tracing in operation testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) jnz syscall_trace_entry +#ifdef CONFIG_OPENMOSIX +remote_or_local_syscall: + pushl %ebp + movl TI_task(%ebp), %ebp + testl $DREMOTE, TASK_om+OM_dflags(%ebp) # is this a DREMOTE task ? + popl %ebp + jz syscall_call +remote_syscall_call: + call *remote_sys_call_table(,%eax,4) + movl %eax,EAX(%esp) # store the return value + jmp syscall_exit +#endif /* CONFIG_OPENMOSIX */ syscall_call: call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) # store the return value diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/i386/kernel/i387.c linux-2.6.7/arch/i386/kernel/i387.c --- linux-2.6.7.org/arch/i386/kernel/i387.c 2004-06-16 07:20:26.000000000 +0200 +++ linux-2.6.7/arch/i386/kernel/i387.c 2004-09-02 14:46:53.839303656 +0200 @@ -94,7 +94,7 @@ * FPU tag word conversions. */ -static inline unsigned short twd_i387_to_fxsr( unsigned short twd ) +OM_NSTATIC inline unsigned short twd_i387_to_fxsr( unsigned short twd ) { unsigned int tmp; /* to avoid 16 bit prefixes in the code */ @@ -108,7 +108,7 @@ return tmp; } -static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave ) +OM_NSTATIC inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave ) { struct _fpxreg *st = NULL; unsigned long twd = (unsigned long) fxsave->twd; @@ -549,6 +549,13 @@ return fpvalid; } +#ifdef CONFIG_OPENMOSIX +int cpu_feature_has_fxsr(void) +{ + return cpu_has_fxsr; +} +#endif /* CONFIG_OPENMOSIX */ + int dump_task_extended_fpu(struct task_struct *tsk, struct user_fxsr_struct *fpu) { int fpvalid = tsk->used_math && cpu_has_fxsr; diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/i386/kernel/omasm.h linux-2.6.7/arch/i386/kernel/omasm.h --- linux-2.6.7.org/arch/i386/kernel/omasm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/arch/i386/kernel/omasm.h 2004-09-02 14:46:53.869299096 +0200 @@ -0,0 +1,291 @@ +.data + +ENTRY(remote_sys_call_table) + .long remote_sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ + .long remote_sys_exit + .long remote_sys_fork + .long remote_sys_read + .long remote_sys_write + .long remote_sys_open /* 5 */ + .long remote_sys_close + .long remote_sys_waitpid + .long remote_sys_creat + .long remote_sys_link + .long remote_sys_unlink /* 10 */ + .long remote_sys_execve + .long remote_sys_chdir + .long remote_sys_time + .long remote_sys_mknod + .long remote_sys_chmod /* 15 */ + .long remote_sys_lchown16 + .long sys_ni_syscall /* old break syscall holder */ + .long remote_sys_stat + .long remote_sys_lseek + .long remote_sys_getpid /* 20 */ + .long remote_sys_mount + .long remote_sys_oldumount + .long remote_sys_setuid16 + .long remote_sys_getuid16 + .long remote_sys_stime /* 25 */ + .long remote_sys_ptrace + .long remote_sys_alarm + .long remote_sys_fstat + .long remote_sys_pause + .long remote_sys_utime /* 30 */ + .long sys_ni_syscall /* old stty syscall holder */ + .long sys_ni_syscall /* old gtty syscall holder */ + .long remote_sys_access + .long remote_sys_nice + .long sys_ni_syscall /* 35 - old ftime syscall holder */ + .long remote_sys_sync + .long remote_sys_kill + .long remote_sys_rename + .long remote_sys_mkdir + .long remote_sys_rmdir /* 40 */ + .long remote_sys_dup + .long remote_sys_pipe + .long remote_sys_times + .long sys_ni_syscall /* old prof syscall holder */ + .long remote_sys_brk /* 45 */ + .long remote_sys_setgid16 + .long remote_sys_getgid16 + .long remote_sys_signal + .long remote_sys_geteuid16 + .long remote_sys_getegid16 /* 50 */ + .long remote_sys_acct + .long remote_sys_umount /* recycled never used phys() */ + .long sys_ni_syscall /* old lock syscall holder */ + .long remote_sys_ioctl + .long remote_sys_fcntl /* 55 */ + .long sys_ni_syscall /* old mpx syscall holder */ + .long remote_sys_setpgid + .long sys_ni_syscall /* old ulimit syscall holder */ + .long remote_sys_olduname + .long remote_sys_umask /* 60 */ + .long remote_sys_chroot + .long remote_sys_ustat + .long remote_sys_dup2 + .long remote_sys_getppid + .long remote_sys_getpgrp /* 65 */ + .long remote_sys_setsid + .long remote_sys_sigaction + .long remote_sys_sgetmask + .long remote_sys_ssetmask + .long remote_sys_setreuid16 /* 70 */ + .long remote_sys_setregid16 + .long remote_sys_sigsuspend + .long remote_sys_sigpending + .long remote_sys_sethostname + .long remote_sys_setrlimit /* 75 */ + .long remote_sys_old_getrlimit + .long remote_sys_getrusage + .long remote_sys_gettimeofday + .long remote_sys_settimeofday + .long remote_sys_getgroups16 /* 80 */ + .long remote_sys_setgroups16 + .long remote_old_select + .long remote_sys_symlink + .long remote_sys_lstat + .long remote_sys_readlink /* 85 */ + .long remote_sys_uselib + .long remote_sys_swapon + .long remote_sys_reboot + .long remote_old_readdir + .long remote_old_mmap /* 90 */ + .long remote_sys_munmap + .long remote_sys_truncate + .long remote_sys_ftruncate + .long remote_sys_fchmod + .long remote_sys_fchown16 /* 95 */ + .long remote_sys_getpriority + .long remote_sys_setpriority + .long sys_ni_syscall /* old profil syscall holder */ + .long remote_sys_statfs + .long remote_sys_fstatfs /* 100 */ + .long remote_sys_ioperm + .long remote_sys_socketcall + .long remote_sys_syslog + .long remote_sys_setitimer + .long remote_sys_getitimer /* 105 */ + .long remote_sys_newstat + .long remote_sys_newlstat + .long remote_sys_newfstat + .long remote_sys_uname + .long remote_sys_iopl /* 110 */ + .long remote_sys_vhangup + .long sys_ni_syscall /* old "idle" system call */ + .long remote_sys_vm86old + .long remote_sys_wait4 + .long remote_sys_swapoff /* 115 */ + .long remote_sys_sysinfo + .long remote_sys_ipc + .long remote_sys_fsync + .long remote_sys_sigreturn + .long remote_sys_clone /* 120 */ + .long remote_sys_setdomainname + .long remote_sys_newuname + .long remote_sys_modify_ldt + .long remote_sys_adjtimex + .long remote_sys_mprotect /* 125 */ + .long remote_sys_sigprocmask + .long sys_ni_syscall /* old "create_module" */ + .long remote_sys_init_module + .long remote_sys_delete_module + .long sys_ni_syscall /* 130: old "get_kernel_syms" */ + .long remote_sys_quotactl + .long remote_sys_getpgid + .long remote_sys_fchdir + .long remote_sys_bdflush + .long remote_sys_sysfs /* 135 */ + .long remote_sys_personality + .long sys_ni_syscall /* reserved for afs_syscall */ + .long remote_sys_setfsuid16 + .long remote_sys_setfsgid16 + .long remote_sys_llseek /* 140 */ + .long remote_sys_getdents + .long remote_sys_select + .long remote_sys_flock + .long remote_sys_msync + .long remote_sys_readv /* 145 */ + .long remote_sys_writev + .long remote_sys_getsid + .long remote_sys_fdatasync + .long remote_sys_sysctl + .long remote_sys_mlock /* 150 */ + .long remote_sys_munlock + .long remote_sys_mlockall + .long remote_sys_munlockall + .long remote_sys_sched_setparam + .long remote_sys_sched_getparam /* 155 */ + .long remote_sys_sched_setscheduler + .long remote_sys_sched_getscheduler + .long remote_sys_sched_yield + .long remote_sys_sched_get_priority_max + .long remote_sys_sched_get_priority_min /* 160 */ + .long remote_sys_sched_rr_get_interval + .long remote_sys_nanosleep + .long remote_sys_mremap + .long remote_sys_setresuid16 + .long remote_sys_getresuid16 /* 165 */ + .long remote_sys_vm86 + .long sys_ni_syscall /* Old sys_query_module */ + .long remote_sys_poll + .long remote_sys_nfsservctl + .long remote_sys_setresgid16 /* 170 */ + .long remote_sys_getresgid16 + .long remote_sys_prctl + .long remote_sys_rt_sigreturn + .long remote_sys_rt_sigaction + .long remote_sys_rt_sigprocmask /* 175 */ + .long remote_sys_rt_sigpending + .long remote_sys_rt_sigtimedwait + .long remote_sys_rt_sigqueueinfo + .long remote_sys_rt_sigsuspend + .long remote_sys_pread64 /* 180 */ + .long remote_sys_pwrite64 + .long remote_sys_chown16 + .long remote_sys_getcwd + .long remote_sys_capget + .long remote_sys_capset /* 185 */ + .long remote_sys_sigaltstack + .long remote_sys_sendfile + .long sys_ni_syscall /* reserved for streams1 */ + .long sys_ni_syscall /* reserved for streams2 */ + .long remote_sys_vfork /* 190 */ + .long remote_sys_getrlimit + .long remote_sys_mmap2 + .long remote_sys_truncate64 + .long remote_sys_ftruncate64 + .long remote_sys_stat64 /* 195 */ + .long remote_sys_lstat64 + .long remote_sys_fstat64 + .long remote_sys_lchown + .long remote_sys_getuid + .long remote_sys_getgid /* 200 */ + .long remote_sys_geteuid + .long remote_sys_getegid + .long remote_sys_setreuid + .long remote_sys_setregid + .long remote_sys_getgroups /* 205 */ + .long remote_sys_setgroups + .long remote_sys_fchown + .long remote_sys_setresuid + .long remote_sys_getresuid + .long remote_sys_setresgid /* 210 */ + .long remote_sys_getresgid + .long remote_sys_chown + .long remote_sys_setuid + .long remote_sys_setgid + .long remote_sys_setfsuid /* 215 */ + .long remote_sys_setfsgid + .long remote_sys_pivot_root + .long remote_sys_mincore + .long remote_sys_madvise + .long remote_sys_getdents64 /* 220 */ + .long remote_sys_fcntl64 + .long sys_ni_syscall /* reserved for TUX */ + .long sys_ni_syscall + .long remote_sys_gettid + .long remote_sys_readahead /* 225 */ + .long remote_sys_setxattr + .long remote_sys_lsetxattr + .long remote_sys_fsetxattr + .long remote_sys_getxattr + .long remote_sys_lgetxattr /* 230 */ + .long remote_sys_fgetxattr + .long remote_sys_listxattr + .long remote_sys_llistxattr + .long remote_sys_flistxattr + .long remote_sys_removexattr /* 235 */ + .long remote_sys_lremovexattr + .long remote_sys_fremovexattr + .long remote_sys_tkill + .long remote_sys_sendfile64 + .long remote_sys_futex /* 240 */ + .long remote_sys_sched_setaffinity + .long remote_sys_sched_getaffinity + .long remote_sys_set_thread_area + .long remote_sys_get_thread_area + .long remote_sys_io_setup /* 245 */ + .long remote_sys_io_destroy + .long remote_sys_io_getevents + .long remote_sys_io_submit + .long remote_sys_io_cancel + .long remote_sys_fadvise64 /* 250 */ + .long sys_ni_syscall + .long remote_sys_exit_group + .long remote_sys_lookup_dcookie + .long remote_sys_epoll_create + .long remote_sys_epoll_ctl /* 255 */ + .long remote_sys_epoll_wait + .long remote_sys_remap_file_pages + .long remote_sys_set_tid_address + .long remote_sys_timer_create + .long remote_sys_timer_settime /* 260 */ + .long remote_sys_timer_gettime + .long remote_sys_timer_getoverrun + .long remote_sys_timer_delete + .long remote_sys_clock_settime + .long remote_sys_clock_gettime /* 265 */ + .long remote_sys_clock_getres + .long remote_sys_clock_nanosleep + .long remote_sys_statfs64 + .long remote_sys_fstatfs64 + .long remote_sys_tgkill /* 270 */ + .long remote_sys_utimes + .long remote_sys_fadvise64_64 + .long sys_ni_syscall /* sys_vserver */ + .long remote_sys_mbind + .long remote_sys_get_mempolicy + .long remote_sys_set_mempolicy + .long remote_sys_mq_open + .long remote_sys_mq_unlink + .long remote_sys_mq_timedsend + .long remote_sys_mq_timedreceive /* 280 */ + .long remote_sys_mq_notify + .long remote_sys_mq_getsetattr + .long sys_ni_syscall /* reserved for kexec */ + +remote_syscall_table_size=(.-remote_sys_call_table) +.text + diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/i386/kernel/process.c linux-2.6.7/arch/i386/kernel/process.c --- linux-2.6.7.org/arch/i386/kernel/process.c 2004-06-16 07:18:37.000000000 +0200 +++ linux-2.6.7/arch/i386/kernel/process.c 2004-09-02 14:46:53.901294232 +0200 @@ -53,6 +53,10 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include +#endif /* CONFIG_OPENMOSIX */ + asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); int hlt_counter; @@ -288,6 +292,31 @@ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } +#ifdef CONFIG_OPENMOSIX +/* + * Create an user thread + * difference from kernel_thread are: no CLONE_VM, SIGCHLD, and leave space + * on the stack for user registers pt_regs. + */ +int user_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + struct pt_regs regs; + + memset(®s, 0, sizeof(regs)); + regs.ebx = (unsigned long) fn; + regs.edx = (unsigned long) arg; + regs.xds = __USER_DS; + regs.xes = __USER_DS; + regs.orig_eax = -1; + regs.eip = (unsigned long) kernel_thread_helper; + regs.xcs = __KERNEL_CS; + regs.eflags = 0x286; + + /* Ok, create the new process.. */ + return do_fork(flags | SIGCHLD | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); +} +#endif /* CONFIG_OPENMOSIX */ + /* * Free current thread data structures etc.. */ @@ -586,6 +615,7 @@ unsigned long clone_flags; unsigned long newsp; int __user *parent_tidptr, *child_tidptr; + int retval; clone_flags = regs.ebx; newsp = regs.ecx; @@ -593,7 +623,16 @@ child_tidptr = (int __user *)regs.edi; if (!newsp) newsp = regs.esp; - return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0, parent_tidptr, child_tidptr); +#ifdef CONFIG_OPENMOSIX + if (clone_flags & CLONE_VM) + openmosix_pre_clone(); +#endif /* CONFIG_OPENMOSIX */ + retval = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0, parent_tidptr, child_tidptr); +#ifdef CONFIG_OPENMOSIX + if (clone_flags & CLONE_VM) + openmosix_post_clone(); +#endif /* CONFIG_OPENMOSIX */ + return retval; } /* @@ -608,7 +647,16 @@ */ asmlinkage int sys_vfork(struct pt_regs regs) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0, NULL, NULL); + int retval; + +#ifdef CONFIG_OPENMOSIX + openmosix_pre_clone(); +#endif /* CONFIG_OPENMOSIX */ + retval = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0, NULL, NULL); +#ifdef CONFIG_OPENMOSIX + openmosix_post_clone(); +#endif /* CONFIG_OPENMOSIX */ + return retval; } /* @@ -775,4 +823,3 @@ return -EFAULT; return 0; } - diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/i386/kernel/vm86.c linux-2.6.7/arch/i386/kernel/vm86.c --- linux-2.6.7.org/arch/i386/kernel/vm86.c 2004-09-02 14:41:31.337331408 +0200 +++ linux-2.6.7/arch/i386/kernel/vm86.c 2004-09-02 14:51:12.898920608 +0200 @@ -48,6 +48,11 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include +#include +#endif /* CONFIG_OPENMOSIX */ + /* * Known problems: * @@ -131,6 +136,11 @@ loadsegment(fs, current->thread.saved_fs); loadsegment(gs, current->thread.saved_gs); ret = KVM86->regs32; +#ifdef CONFIG_OPENMOSIX + task_lock(current); + task_clear_stay(current, DSTAY_FOR_86); + task_unlock(current); +#endif /* CONFIG_OPENMOSIX */ return ret; } @@ -188,6 +198,13 @@ struct task_struct *tsk; int tmp, ret = -EPERM; +#ifdef CONFIG_OPENMOSIX + ret = -ENOMEM; + if (!task_go_home_for_reason(current, DSTAY_FOR_86)) + goto out; + ret = -EPERM; +#endif /* CONFIG_OPENMOSIX */ + tsk = current; if (tsk->thread.saved_esp0) goto out; @@ -247,6 +264,11 @@ ret = -EFAULT; if (tmp) goto out; +#ifdef CONFIG_OPENMOSIX + ret = -ENOMEM; + if (!task_go_home_for_reason(current, DSTAY_FOR_86)) + goto out; +#endif /* CONFIG_OPENMOSIX */ info.regs32 = ®s; info.vm86plus.is_vm86pus = 1; tsk->thread.vm86_info = (struct vm86_struct __user *)v86; @@ -329,6 +351,11 @@ regs32 = save_v86_state(regs16); regs32->eax = retval; +#ifdef CONFIG_OPENMOSIX + task_lock(current); + task_clear_stay(current, DSTAY_FOR_86); + task_unlock(current); +#endif /* CONFIG_OPENMOSIX */ __asm__ __volatile__("movl %0,%%esp\n\t" "movl %1,%%ebp\n\t" "jmp resume_userspace" diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/i386/mm/fault.c linux-2.6.7/arch/i386/mm/fault.c --- linux-2.6.7.org/arch/i386/mm/fault.c 2004-09-02 14:41:31.731271520 +0200 +++ linux-2.6.7/arch/i386/mm/fault.c 2004-09-02 14:46:53.911292712 +0200 @@ -391,6 +391,13 @@ /* info.si_code has been set above */ info.si_addr = (void *)address; force_sig_info(SIGSEGV, &info, tsk); +/* good help at catching random segfaults, we're given + * an equivalent kernel oops but for u-space */ +#ifdef CONFIG_OPENMOSIX_DEBUG + printk("%d received SIGSEV at addr 0x%p\n", current->pid, + info._sifields._sigfault._addr); + show_user_registers(regs); +#endif /* CONFIG_OPENMOSIX_DEBUG */ return; } diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/ppc/Kconfig linux-2.6.7/arch/ppc/Kconfig --- linux-2.6.7.org/arch/ppc/Kconfig 2004-09-02 14:42:23.117459632 +0200 +++ linux-2.6.7/arch/ppc/Kconfig 2004-09-02 14:52:04.616058408 +0200 @@ -1376,4 +1376,6 @@ source "crypto/Kconfig" +source "hpc/Kconfig" + source "cluster/Kconfig" diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/ppc/kernel/asm-offsets.c linux-2.6.7/arch/ppc/kernel/asm-offsets.c --- linux-2.6.7.org/arch/ppc/kernel/asm-offsets.c 2004-09-02 14:41:36.530541920 +0200 +++ linux-2.6.7/arch/ppc/kernel/asm-offsets.c 2004-09-02 14:46:53.973283288 +0200 @@ -24,6 +24,7 @@ #include #include #include +#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -130,5 +131,12 @@ DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); +#ifdef CONFIG_OPENMOSIX + DEFINE(TASK_om, offsetof(struct task_struct, om)); + DEFINE(OM_dflags, offsetof(struct openmosix_task, dflags)); + BLANK(); + DEFINE(DDEPUTY, DDEPUTY); + DEFINE(DREMOTE, DREMOTE); +#endif /* CONFIG_OPENMOSIX */ return 0; } diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/ppc/kernel/entry.S linux-2.6.7/arch/ppc/kernel/entry.S --- linux-2.6.7.org/arch/ppc/kernel/entry.S 2004-09-02 14:41:36.546539488 +0200 +++ linux-2.6.7/arch/ppc/kernel/entry.S 2004-09-02 14:46:53.976282832 +0200 @@ -206,11 +206,25 @@ andi. r11,r11,_TIF_SYSCALL_TRACE bne- syscall_dotrace syscall_dotrace_cont: +#ifdef CONFIG_OPENMOSIX + lwz r11, TASK_om+OM_dflags(r2) + andi. r11, r11, DREMOTE + beq local_syscall_load +remote_syscall_load: + cmpli 0,r0,NR_syscalls + lis r10,remote_sys_call_table@h + ori r10,r10,remote_sys_call_table@l + slwi r0,r0,2 + bge- 66f + b fetch_syscall +local_syscall_load: +#endif /* CONFIG_OPENMOSIX */ cmpli 0,r0,NR_syscalls lis r10,sys_call_table@h ori r10,r10,sys_call_table@l slwi r0,r0,2 bge- 66f +fetch_syscall: lwzx r10,r10,r0 /* Fetch system call handler [ptr] */ mtlr r10 addi r9,r1,STACK_FRAME_OVERHEAD @@ -272,6 +286,12 @@ li r3,0 b ret_from_syscall +#ifdef CONFIG_OPENMOSIX + .globl ret_from_kickstart +ret_from_kickstart: + b ret_from_syscall +#endif /* CONFIG_OPENMOSIX */ + /* Traced system call support */ syscall_dotrace: SAVE_NVGPRS(r1) @@ -591,6 +611,13 @@ beq resume_kernel user_exc_return: /* r10 contains MSR_KERNEL here */ +#ifdef CONFIG_OPENMOSIX + lwz r9, TASK_om+OM_dflags(r2) + andi. r9, r9, (DREMOTE|DDEPUTY) + beq- 42f + bl openmosix_pre_usermode +42: +#endif /* CONFIG_OPENMOSIX */ /* Check current_thread_info()->flags */ rlwinm r9,r1,0,0,18 lwz r9,TI_FLAGS(r9) diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/ppc/kernel/misc.S linux-2.6.7/arch/ppc/kernel/misc.S --- linux-2.6.7.org/arch/ppc/kernel/misc.S 2004-09-02 14:41:36.588533104 +0200 +++ linux-2.6.7/arch/ppc/kernel/misc.S 2004-09-02 14:46:53.982281920 +0200 @@ -25,6 +25,11 @@ #include #include +#ifdef CONFIG_OPENMOSIX +/* FIXME */ +#define SIGCHLD 17 +#endif /* CONFIG_OPENMOSIX */ + .text .align 5 @@ -1160,6 +1165,36 @@ blr /* + * Create an user thread + * user_thread(fn, arg, flags) + */ +_GLOBAL(user_thread) + stwu r1,-16(r1) + stw r30,8(r1) + stw r31,12(r1) + mr r30,r3 /* function */ + mr r31,r4 /* argument */ + ori r3,r5,SIGCHLD /* flags */ + oris r3,r3,CLONE_UNTRACED>>16 + li r4,0 /* new sp (unused) */ + li r0,__NR_clone + sc + cmpi 0,r3,0 /* parent or child? */ + bne 1f /* return if parent */ + li r0,0 /* make top-level stack frame */ + stwu r0,-16(r1) + mtlr r30 /* fn addr in lr */ + mr r3,r31 /* load arg and call fn */ + blrl + li r0,__NR_exit /* exit if function returns */ + li r3,0 + sc +1: lwz r30,8(r1) + lwz r31,12(r1) + addi r1,r1,16 + blr + +/* * This routine is just here to keep GCC happy - sigh... */ _GLOBAL(__main) @@ -1450,3 +1485,277 @@ .long sys_mq_notify .long sys_mq_getsetattr .long sys_ni_syscall /* 268 reserved for sys_kexec_load */ + +#ifdef CONFIG_OPENMOSIX +_GLOBAL(remote_sys_call_table) + .long remote_sys_restart_syscall /* 0 */ + .long remote_sys_exit + .long remote_ppc_fork + .long remote_sys_read + .long remote_sys_write + .long remote_sys_open /* 5 */ + .long remote_sys_close + .long remote_sys_waitpid + .long remote_sys_creat + .long remote_sys_link + .long remote_sys_unlink /* 10 */ + .long remote_sys_execve + .long remote_sys_chdir + .long remote_sys_time + .long remote_sys_mknod + .long remote_sys_chmod /* 15 */ + .long remote_sys_lchown + .long sys_ni_syscall /* old break syscall holder */ + .long remote_sys_stat + .long remote_sys_lseek + .long remote_sys_getpid /* 20 */ + .long remote_sys_mount + .long remote_sys_oldumount + .long remote_sys_setuid + .long remote_sys_getuid + .long remote_sys_stime /* 25 */ + .long remote_sys_ptrace + .long remote_sys_alarm + .long remote_sys_fstat + .long remote_sys_pause + .long remote_sys_utime /* 30 */ + .long sys_ni_syscall /* old stty syscall holder */ + .long sys_ni_syscall /* old gtty syscall holder */ + .long remote_sys_access + .long remote_sys_nice + .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */ + .long remote_sys_sync + .long remote_sys_kill + .long remote_sys_rename + .long remote_sys_mkdir + .long remote_sys_rmdir /* 40 */ + .long remote_sys_dup + .long remote_sys_pipe + .long remote_sys_times + .long sys_ni_syscall /* old prof syscall holder */ + .long remote_sys_brk /* 45 */ + .long remote_sys_setgid + .long remote_sys_getgid + .long remote_sys_signal + .long remote_sys_geteuid + .long remote_sys_getegid /* 50 */ + .long remote_sys_acct + .long remote_sys_umount /* recycled never used phys() */ + .long sys_ni_syscall /* old lock syscall holder */ + .long remote_sys_ioctl + .long remote_sys_fcntl /* 55 */ + .long sys_ni_syscall /* old mpx syscall holder */ + .long remote_sys_setpgid + .long sys_ni_syscall /* old ulimit syscall holder */ + .long remote_sys_olduname + .long remote_sys_umask /* 60 */ + .long remote_sys_chroot + .long remote_sys_ustat + .long remote_sys_dup2 + .long remote_sys_getppid + .long remote_sys_getpgrp /* 65 */ + .long remote_sys_setsid + .long remote_sys_sigaction + .long remote_sys_sgetmask + .long remote_sys_ssetmask + .long remote_sys_setreuid /* 70 */ + .long remote_sys_setregid + .long remote_ppc_sigsuspend + .long remote_sys_sigpending + .long remote_sys_sethostname + .long remote_sys_setrlimit /* 75 */ + .long remote_sys_old_getrlimit + .long remote_sys_getrusage + .long remote_sys_gettimeofday + .long remote_sys_settimeofday + .long remote_sys_getgroups /* 80 */ + .long remote_sys_setgroups + .long remote_ppc_select + .long remote_sys_symlink + .long remote_sys_lstat + .long remote_sys_readlink /* 85 */ + .long remote_sys_uselib + .long remote_sys_swapon + .long remote_sys_reboot + .long remote_old_readdir + .long remote_sys_mmap /* 90 */ + .long remote_sys_munmap + .long remote_sys_truncate + .long remote_sys_ftruncate + .long remote_sys_fchmod + .long remote_sys_fchown /* 95 */ + .long remote_sys_getpriority + .long remote_sys_setpriority + .long sys_ni_syscall /* old profil syscall holder */ + .long remote_sys_statfs + .long remote_sys_fstatfs /* 100 */ + .long sys_ni_syscall + .long remote_sys_socketcall + .long remote_sys_syslog + .long remote_sys_setitimer + .long remote_sys_getitimer /* 105 */ + .long remote_sys_newstat + .long remote_sys_newlstat + .long remote_sys_newfstat + .long remote_sys_uname + .long sys_ni_syscall /* 110 */ + .long remote_sys_vhangup + .long sys_ni_syscall /* old 'idle' syscall */ + .long sys_ni_syscall + .long remote_sys_wait4 + .long remote_sys_swapoff /* 115 */ + .long remote_sys_sysinfo + .long remote_sys_ipc + .long remote_sys_fsync + .long remote_sys_sigreturn + .long remote_ppc_clone /* 120 */ + .long remote_sys_setdomainname + .long remote_sys_newuname + .long sys_ni_syscall + .long remote_sys_adjtimex + .long remote_sys_mprotect /* 125 */ + .long remote_sys_sigprocmask + .long sys_ni_syscall /* old sys_create_module */ + .long remote_sys_init_module + .long remote_sys_delete_module + .long sys_ni_syscall /* old sys_get_kernel_syms */ /* 130 */ + .long remote_sys_quotactl + .long remote_sys_getpgid + .long remote_sys_fchdir + .long remote_sys_bdflush + .long remote_sys_sysfs /* 135 */ + .long remote_sys_personality + .long sys_ni_syscall /* for afs_syscall */ + .long remote_sys_setfsuid + .long remote_sys_setfsgid + .long remote_sys_llseek /* 140 */ + .long remote_sys_getdents + .long remote_ppc_select + .long remote_sys_flock + .long remote_sys_msync + .long remote_sys_readv /* 145 */ + .long remote_sys_writev + .long remote_sys_getsid + .long remote_sys_fdatasync + .long remote_sys_sysctl + .long remote_sys_mlock /* 150 */ + .long remote_sys_munlock + .long remote_sys_mlockall + .long remote_sys_munlockall + .long remote_sys_sched_setparam + .long remote_sys_sched_getparam /* 155 */ + .long remote_sys_sched_setscheduler + .long remote_sys_sched_getscheduler + .long remote_sys_sched_yield + .long remote_sys_sched_get_priority_max + .long remote_sys_sched_get_priority_min /* 160 */ + .long remote_sys_sched_rr_get_interval + .long remote_sys_nanosleep + .long remote_sys_mremap + .long remote_sys_setresuid + .long remote_sys_getresuid /* 165 */ + .long sys_ni_syscall /* old sys_query_module */ + .long remote_sys_poll + .long remote_sys_nfsservctl + .long remote_sys_setresgid + .long remote_sys_getresgid /* 170 */ + .long remote_sys_prctl + .long remote_sys_rt_sigreturn + .long remote_sys_rt_sigaction + .long remote_sys_rt_sigprocmask + .long remote_sys_rt_sigpending /* 175 */ + .long remote_sys_rt_sigtimedwait + .long remote_sys_rt_sigqueueinfo + .long remote_ppc_rt_sigsuspend + .long remote_sys_pread64 + .long remote_sys_pwrite64 /* 180 */ + .long remote_sys_chown + .long remote_sys_getcwd + .long remote_sys_capget + .long remote_sys_capset + .long remote_sys_sigaltstack /* 185 */ + .long remote_sys_sendfile + .long sys_ni_syscall /* streams1 */ + .long sys_ni_syscall /* streams2 */ + .long remote_ppc_vfork + .long remote_sys_getrlimit /* 190 */ + .long remote_sys_readahead + .long remote_sys_mmap2 + .long remote_sys_truncate64 + .long remote_sys_ftruncate64 + .long remote_sys_stat64 /* 195 */ + .long remote_sys_lstat64 + .long remote_sys_fstat64 + .long remote_sys_pciconfig_read + .long remote_sys_pciconfig_write + .long remote_sys_pciconfig_iobase /* 200 */ + .long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */ + .long remote_sys_getdents64 + .long remote_sys_pivot_root + .long remote_sys_fcntl64 + .long remote_sys_madvise /* 205 */ + .long remote_sys_mincore + .long remote_sys_gettid + .long remote_sys_tkill + .long remote_sys_setxattr + .long remote_sys_lsetxattr /* 210 */ + .long remote_sys_fsetxattr + .long remote_sys_getxattr + .long remote_sys_lgetxattr + .long remote_sys_fgetxattr + .long remote_sys_listxattr /* 215 */ + .long remote_sys_llistxattr + .long remote_sys_flistxattr + .long remote_sys_removexattr + .long remote_sys_lremovexattr + .long remote_sys_fremovexattr /* 220 */ + .long remote_sys_futex + .long remote_sys_sched_setaffinity + .long remote_sys_sched_getaffinity + .long sys_ni_syscall + .long sys_ni_syscall /* 225 - reserved for Tux */ + .long remote_sys_sendfile64 + .long remote_sys_io_setup + .long remote_sys_io_destroy + .long remote_sys_io_getevents + .long remote_sys_io_submit /* 230 */ + .long remote_sys_io_cancel + .long remote_sys_set_tid_address + .long remote_sys_fadvise64 + .long remote_sys_exit_group + .long remote_sys_lookup_dcookie /* 235 */ + .long remote_sys_epoll_create + .long remote_sys_epoll_ctl + .long remote_sys_epoll_wait + .long remote_sys_remap_file_pages + .long remote_sys_timer_create /* 240 */ + .long remote_sys_timer_settime + .long remote_sys_timer_gettime + .long remote_sys_timer_getoverrun + .long remote_sys_timer_delete + .long remote_sys_clock_settime /* 245 */ + .long remote_sys_clock_gettime + .long remote_sys_clock_getres + .long remote_sys_clock_nanosleep + .long remote_ppc_swapcontext + .long remote_sys_tgkill /* 250 */ + .long remote_sys_utimes + .long remote_sys_statfs64 + .long remote_sys_fstatfs64 + .long remote_ppc_fadvise64_64 + .long sys_ni_syscall /* 255 - rtas (used on ppc64) */ + .long sys_ni_syscall /* 256 reserved for sys_debug_setcontext */ + .long sys_ni_syscall /* 257 reserved for vserver */ + .long sys_ni_syscall /* 258 reserved for new sys_remap_file_pages */ + .long sys_ni_syscall /* 259 reserved for new sys_mbind */ + .long sys_ni_syscall /* 260 reserved for new sys_get_mempolicy */ + .long sys_ni_syscall /* 261 reserved for new sys_set_mempolicy */ + .long remote_sys_mq_open + .long remote_sys_mq_unlink + .long remote_sys_mq_timedsend + .long remote_sys_mq_timedreceive/* 265 */ + .long remote_sys_mq_notify + .long remote_sys_mq_getsetattr + .long sys_ni_syscall /* 268 reserved for sys_kexec_load */ + +#endif /* CONFIG_OPENMOSIX */ diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/ppc/kernel/process.c linux-2.6.7/arch/ppc/kernel/process.c --- linux-2.6.7.org/arch/ppc/kernel/process.c 2004-09-02 14:41:36.597531736 +0200 +++ linux-2.6.7/arch/ppc/kernel/process.c 2004-09-02 14:46:54.012277360 +0200 @@ -46,6 +46,10 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include +#endif /* CONFIG_OPENMOSIX */ + extern unsigned long _get_SP(void); struct task_struct *last_task_used_math = NULL; @@ -552,11 +556,22 @@ int __user *child_tidp, int p6, struct pt_regs *regs) { + int retval; + CHECK_FULL_REGS(regs); if (usp == 0) usp = regs->gpr[1]; /* stack pointer for child */ - return do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0, +#ifdef CONFIG_OPENMOSIX + if (clone_flags & CLONE_VM) + openmosix_pre_clone(); +#endif /* CONFIG_OPENMOSIX */ + retval = do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0, parent_tidp, child_tidp); +#ifdef CONFIG_OPENMOSIX + if (clone_flags & CLONE_VM) + openmosix_post_clone(); +#endif /* CONFIG_OPENMOSIX */ + return retval; } int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, @@ -569,9 +584,18 @@ int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs) { + int retval; + CHECK_FULL_REGS(regs); - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], +#ifdef CONFIG_OPENMOSIX + openmosix_pre_clone(); +#endif /* CONFIG_OPENMOSIX */ + retval = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL); +#ifdef CONFIG_OPENMOSIX + openmosix_post_clone(); +#endif /* CONFIG_OPENMOSIX */ + return retval; } int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/x86_64/Kconfig linux-2.6.7/arch/x86_64/Kconfig --- linux-2.6.7.org/arch/x86_64/Kconfig 2004-09-02 14:42:23.219444128 +0200 +++ linux-2.6.7/arch/x86_64/Kconfig 2004-09-02 14:46:54.014277056 +0200 @@ -503,6 +503,8 @@ source "crypto/Kconfig" +source "hpc/Kconfig" + source "lib/Kconfig" source "cluster/Kconfig" diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/x86_64/kernel/asm-offsets.c linux-2.6.7/arch/x86_64/kernel/asm-offsets.c --- linux-2.6.7.org/arch/x86_64/kernel/asm-offsets.c 2004-06-16 07:19:35.000000000 +0200 +++ linux-2.6.7/arch/x86_64/kernel/asm-offsets.c 2004-09-02 14:46:54.051271432 +0200 @@ -13,6 +13,7 @@ #include #include #include +#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -26,9 +27,13 @@ ENTRY(flags); ENTRY(thread); ENTRY(pid); +#ifdef CONFIG_OPENMOSIX + DEFINE(TASK_om, offsetof(struct task_struct, om)); +#endif /* CONFIG_OPENMOSIX */ BLANK(); #undef ENTRY #define ENTRY(entry) DEFINE(threadinfo_ ## entry, offsetof(struct thread_info, entry)) + ENTRY(task); ENTRY(flags); ENTRY(addr_limit); ENTRY(preempt_count); @@ -62,5 +67,11 @@ BLANK(); #endif +#ifdef CONFIG_OPENMOSIX + DEFINE(OM_dflags, offsetof(struct openmosix_task, dflags)); + BLANK(); + DEFINE(DDEPUTY, DDEPUTY); + DEFINE(DREMOTE, DREMOTE); +#endif /* CONFIG_OPENMOSIX */ return 0; } diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/x86_64/kernel/entry.S linux-2.6.7/arch/x86_64/kernel/entry.S --- linux-2.6.7.org/arch/x86_64/kernel/entry.S 2004-06-16 07:19:13.000000000 +0200 +++ linux-2.6.7/arch/x86_64/kernel/entry.S 2004-09-02 14:46:54.059270216 +0200 @@ -43,6 +43,10 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include "omasm.h" +#endif /* CONFIG_OPENMOSIX */ + .code64 #ifdef CONFIG_PREEMPT @@ -148,6 +152,12 @@ jmp rff_action CFI_ENDPROC +#ifdef CONFIG_OPENMOSIX +ENTRY(ret_from_kickstart) + GET_THREAD_INFO(%rcx) + jmp ret_from_sys_call +#endif /* CONFIG OPENMOSIX */ + /* * System call entry. Upto 6 arguments in registers are supported. * @@ -189,6 +199,18 @@ jnz tracesys cmpq $__NR_syscall_max,%rax ja badsys +#ifdef CONFIG_OPENMOSIX +remote_or_local_syscall: + movq threadinfo_task(%rcx), %rcx + testq $DREMOTE, TASK_om+OM_dflags(%rcx) # is this a DREMOTE task ? + jz syscall_call +remote_syscall_call: + movq %r10,%rcx + call *remote_sys_call_table(,%rax,8) + movq %rax,RAX-ARGOFFSET(%rsp) + jmp ret_from_sys_call +syscall_call: +#endif /* CONFIG_OPENMOSIX */ movq %r10,%rcx call *sys_call_table(,%rax,8) # XXX: rip relative movq %rax,RAX-ARGOFFSET(%rsp) diff -Nur --exclude '*.orig' linux-2.6.7.org/arch/x86_64/kernel/omasm.h linux-2.6.7/arch/x86_64/kernel/omasm.h --- linux-2.6.7.org/arch/x86_64/kernel/omasm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/arch/x86_64/kernel/omasm.h 2004-09-02 14:46:54.062269760 +0200 @@ -0,0 +1,281 @@ +.data + +ENTRY(remote_sys_call_table) + .long remote_sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ + .long remote_sys_exit + .long remote_sys_fork + .long remote_sys_read + .long remote_sys_write + .long remote_sys_open /* 5 */ + .long remote_sys_close + .long remote_sys_waitpid + .long remote_sys_creat + .long remote_sys_link + .long remote_sys_unlink /* 10 */ + .long remote_sys_execve + .long remote_sys_chdir + .long remote_sys_time + .long remote_sys_mknod + .long remote_sys_chmod /* 15 */ + .long remote_sys_lchown16 + .long sys_ni_syscall /* old break syscall holder */ + .long remote_sys_stat + .long remote_sys_lseek + .long remote_sys_getpid /* 20 */ + .long remote_sys_mount + .long remote_sys_oldumount + .long remote_sys_setuid16 + .long remote_sys_getuid16 + .long remote_sys_stime /* 25 */ + .long remote_sys_ptrace + .long remote_sys_alarm + .long remote_sys_fstat + .long remote_sys_pause + .long remote_sys_utime /* 30 */ + .long sys_ni_syscall /* old stty syscall holder */ + .long sys_ni_syscall /* old gtty syscall holder */ + .long remote_sys_access + .long remote_sys_nice + .long sys_ni_syscall /* 35 - old ftime syscall holder */ + .long remote_sys_sync + .long remote_sys_kill + .long remote_sys_rename + .long remote_sys_mkdir + .long remote_sys_rmdir /* 40 */ + .long remote_sys_dup + .long remote_sys_pipe + .long remote_sys_times + .long sys_ni_syscall /* old prof syscall holder */ + .long remote_sys_brk /* 45 */ + .long remote_sys_setgid16 + .long remote_sys_getgid16 + .long remote_sys_signal + .long remote_sys_geteuid16 + .long remote_sys_getegid16 /* 50 */ + .long remote_sys_acct + .long remote_sys_umount /* recycled never used phys() */ + .long sys_ni_syscall /* old lock syscall holder */ + .long remote_sys_ioctl + .long remote_sys_fcntl /* 55 */ + .long sys_ni_syscall /* old mpx syscall holder */ + .long remote_sys_setpgid + .long sys_ni_syscall /* old ulimit syscall holder */ + .long remote_sys_olduname + .long remote_sys_umask /* 60 */ + .long remote_sys_chroot + .long remote_sys_ustat + .long remote_sys_dup2 + .long remote_sys_getppid + .long remote_sys_getpgrp /* 65 */ + .long remote_sys_setsid + .long remote_sys_sigaction + .long remote_sys_sgetmask + .long remote_sys_ssetmask + .long remote_sys_setreuid16 /* 70 */ + .long remote_sys_setregid16 + .long remote_sys_sigsuspend + .long remote_sys_sigpending + .long remote_sys_sethostname + .long remote_sys_setrlimit /* 75 */ + .long remote_sys_old_getrlimit + .long remote_sys_getrusage + .long remote_sys_gettimeofday + .long remote_sys_settimeofday + .long remote_sys_getgroups16 /* 80 */ + .long remote_sys_setgroups16 + .long remote_old_select + .long remote_sys_symlink + .long remote_sys_lstat + .long remote_sys_readlink /* 85 */ + .long remote_sys_uselib + .long remote_sys_swapon + .long remote_sys_reboot + .long remote_old_readdir + .long remote_old_mmap /* 90 */ + .long remote_sys_munmap + .long remote_sys_truncate + .long remote_sys_ftruncate + .long remote_sys_fchmod + .long remote_sys_fchown16 /* 95 */ + .long remote_sys_getpriority + .long remote_sys_setpriority + .long sys_ni_syscall /* old profil syscall holder */ + .long remote_sys_statfs + .long remote_sys_fstatfs /* 100 */ + .long remote_sys_ioperm + .long remote_sys_socketcall + .long remote_sys_syslog + .long remote_sys_setitimer + .long remote_sys_getitimer /* 105 */ + .long remote_sys_newstat + .long remote_sys_newlstat + .long remote_sys_newfstat + .long remote_sys_uname + .long remote_sys_iopl /* 110 */ + .long remote_sys_vhangup + .long sys_ni_syscall /* old "idle" system call */ + .long remote_sys_vm86old + .long remote_sys_wait4 + .long remote_sys_swapoff /* 115 */ + .long remote_sys_sysinfo + .long remote_sys_ipc + .long remote_sys_fsync + .long remote_sys_sigreturn + .long remote_sys_clone /* 120 */ + .long remote_sys_setdomainname + .long remote_sys_newuname + .long remote_sys_modify_ldt + .long remote_sys_adjtimex + .long remote_sys_mprotect /* 125 */ + .long remote_sys_sigprocmask + .long sys_ni_syscall /* old "create_module" */ + .long remote_sys_init_module + .long remote_sys_delete_module + .long sys_ni_syscall /* 130: old "get_kernel_syms" */ + .long remote_sys_quotactl + .long remote_sys_getpgid + .long remote_sys_fchdir + .long remote_sys_bdflush + .long remote_sys_sysfs /* 135 */ + .long remote_sys_personality + .long sys_ni_syscall /* reserved for afs_syscall */ + .long remote_sys_setfsuid16 + .long remote_sys_setfsgid16 + .long remote_sys_llseek /* 140 */ + .long remote_sys_getdents + .long remote_sys_select + .long remote_sys_flock + .long remote_sys_msync + .long remote_sys_readv /* 145 */ + .long remote_sys_writev + .long remote_sys_getsid + .long remote_sys_fdatasync + .long remote_sys_sysctl + .long remote_sys_mlock /* 150 */ + .long remote_sys_munlock + .long remote_sys_mlockall + .long remote_sys_munlockall + .long remote_sys_sched_setparam + .long remote_sys_sched_getparam /* 155 */ + .long remote_sys_sched_setscheduler + .long remote_sys_sched_getscheduler + .long remote_sys_sched_yield + .long remote_sys_sched_get_priority_max + .long remote_sys_sched_get_priority_min /* 160 */ + .long remote_sys_sched_rr_get_interval + .long remote_sys_nanosleep + .long remote_sys_mremap + .long remote_sys_setresuid16 + .long remote_sys_getresuid16 /* 165 */ + .long remote_sys_vm86 + .long sys_ni_syscall /* Old sys_query_module */ + .long remote_sys_poll + .long remote_sys_nfsservctl + .long remote_sys_setresgid16 /* 170 */ + .long remote_sys_getresgid16 + .long remote_sys_prctl + .long remote_sys_rt_sigreturn + .long remote_sys_rt_sigaction + .long remote_sys_rt_sigprocmask /* 175 */ + .long remote_sys_rt_sigpending + .long remote_sys_rt_sigtimedwait + .long remote_sys_rt_sigqueueinfo + .long remote_sys_rt_sigsuspend + .long remote_sys_pread64 /* 180 */ + .long remote_sys_pwrite64 + .long remote_sys_chown16 + .long remote_sys_getcwd + .long remote_sys_capget + .long remote_sys_capset /* 185 */ + .long remote_sys_sigaltstack + .long remote_sys_sendfile + .long sys_ni_syscall /* reserved for streams1 */ + .long sys_ni_syscall /* reserved for streams2 */ + .long remote_sys_vfork /* 190 */ + .long remote_sys_getrlimit + .long remote_sys_mmap2 + .long remote_sys_truncate64 + .long remote_sys_ftruncate64 + .long remote_sys_stat64 /* 195 */ + .long remote_sys_lstat64 + .long remote_sys_fstat64 + .long remote_sys_lchown + .long remote_sys_getuid + .long remote_sys_getgid /* 200 */ + .long remote_sys_geteuid + .long remote_sys_getegid + .long remote_sys_setreuid + .long remote_sys_setregid + .long remote_sys_getgroups /* 205 */ + .long remote_sys_setgroups + .long remote_sys_fchown + .long remote_sys_setresuid + .long remote_sys_getresuid + .long remote_sys_setresgid /* 210 */ + .long remote_sys_getresgid + .long remote_sys_chown + .long remote_sys_setuid + .long remote_sys_setgid + .long remote_sys_setfsuid /* 215 */ + .long remote_sys_setfsgid + .long remote_sys_pivot_root + .long remote_sys_mincore + .long remote_sys_madvise + .long remote_sys_getdents64 /* 220 */ + .long remote_sys_fcntl64 + .long sys_ni_syscall /* reserved for TUX */ + .long sys_ni_syscall + .long remote_sys_gettid + .long remote_sys_readahead /* 225 */ + .long remote_sys_setxattr + .long remote_sys_lsetxattr + .long remote_sys_fsetxattr + .long remote_sys_getxattr + .long remote_sys_lgetxattr /* 230 */ + .long remote_sys_fgetxattr + .long remote_sys_listxattr + .long remote_sys_llistxattr + .long remote_sys_flistxattr + .long remote_sys_removexattr /* 235 */ + .long remote_sys_lremovexattr + .long remote_sys_fremovexattr + .long remote_sys_tkill + .long remote_sys_sendfile64 + .long remote_sys_futex /* 240 */ + .long remote_sys_sched_setaffinity + .long remote_sys_sched_getaffinity + .long remote_sys_set_thread_area + .long remote_sys_get_thread_area + .long remote_sys_io_setup /* 245 */ + .long remote_sys_io_destroy + .long remote_sys_io_getevents + .long remote_sys_io_submit + .long remote_sys_io_cancel + .long remote_sys_fadvise64 /* 250 */ + .long sys_ni_syscall + .long remote_sys_exit_group + .long remote_sys_lookup_dcookie + .long remote_sys_epoll_create + .long remote_sys_epoll_ctl /* 255 */ + .long remote_sys_epoll_wait + .long remote_sys_remap_file_pages + .long remote_sys_set_tid_address + .long remote_sys_timer_create + .long remote_sys_timer_settime /* 260 */ + .long remote_sys_timer_gettime + .long remote_sys_timer_getoverrun + .long remote_sys_timer_delete + .long remote_sys_clock_settime + .long remote_sys_clock_gettime /* 265 */ + .long remote_sys_clock_getres + .long remote_sys_clock_nanosleep + .long remote_sys_statfs64 + .long remote_sys_fstatfs64 + .long remote_sys_tgkill /* 270 */ + .long remote_sys_utimes + .long remote_sys_fadvise64_64 + .long sys_ni_syscall /* sys_vserver */ + +remote_syscall_table_size=(.-remote_sys_call_table) +.text + diff -Nur --exclude '*.orig' linux-2.6.7.org/fs/proc/base.c linux-2.6.7/fs/proc/base.c --- linux-2.6.7.org/fs/proc/base.c 2004-09-02 14:42:21.768664680 +0200 +++ linux-2.6.7/fs/proc/base.c 2004-09-02 14:46:54.101263832 +0200 @@ -34,6 +34,10 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include +#endif + /* * For hysterical raisins we keep the same inumbers as in the old procfs. * Feel free to change the macro below - just keep the range distinct from @@ -71,6 +75,12 @@ #ifdef CONFIG_GRKERNSEC_PROC_IPADDR PROC_TGID_IPADDR, #endif +#ifdef CONFIG_OPENMOSIX + PROC_TGID_OPENMOSIX, + PROC_TGID_OPENMOSIX_WHERE, + PROC_TGID_OPENMOSIX_STAY, + PROC_TGID_OPENMOSIX_DEBUG, +#endif PROC_TGID_FD_DIR, PROC_TID_INO, PROC_TID_STATUS, @@ -94,6 +104,12 @@ PROC_TID_ATTR_EXEC, PROC_TID_ATTR_FSCREATE, #endif +#ifdef CONFIG_OPENMOSIX + PROC_TID_OPENMOSIX, + PROC_TID_OPENMOSIX_WHERE, + PROC_TID_OPENMOSIX_STAY, + PROC_TID_OPENMOSIX_DEBUG, +#endif PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */ }; @@ -127,6 +143,9 @@ #ifdef CONFIG_SECURITY E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), #endif +#ifdef CONFIG_OPENMOSIX + E(PROC_TGID_OPENMOSIX, "om", S_IFDIR|S_IRUGO|S_IXUGO), +#endif #ifdef CONFIG_KALLSYMS E(PROC_TGID_WCHAN, "wchan", S_IFREG|S_IRUGO), #endif @@ -149,6 +168,9 @@ #ifdef CONFIG_SECURITY E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), #endif +#ifdef CONFIG_OPENMOSIX + E(PROC_TID_OPENMOSIX, "om", S_IFDIR|S_IRUGO|S_IXUGO), +#endif #ifdef CONFIG_KALLSYMS E(PROC_TID_WCHAN, "wchan", S_IFREG|S_IRUGO), #endif @@ -172,6 +194,21 @@ }; #endif +#ifdef CONFIG_OPENMOSIX +static struct pid_entry tgid_openmosix_stuff[] = { + E(PROC_TGID_OPENMOSIX_WHERE, "where", S_IFREG|S_IRUGO|S_IWUGO), + E(PROC_TGID_OPENMOSIX_STAY, "stay", S_IFREG|S_IRUGO|S_IWUGO), + E(PROC_TGID_OPENMOSIX_DEBUG, "debug", S_IFREG|S_IRUGO|S_IWUGO), + {0,0,NULL,0} +}; +static struct pid_entry tid_openmosix_stuff[] = { + E(PROC_TID_OPENMOSIX_WHERE, "where", S_IFREG|S_IRUGO|S_IWUGO), + E(PROC_TID_OPENMOSIX_STAY, "stay", S_IFREG|S_IRUGO|S_IWUGO), + E(PROC_TID_OPENMOSIX_DEBUG, "debug", S_IFREG|S_IRUGO|S_IWUGO), + {0,0,NULL,0} +}; +#endif + #undef E static inline struct task_struct *proc_task(struct inode *inode) @@ -1269,6 +1306,84 @@ static struct inode_operations proc_tgid_attr_inode_operations; #endif +#ifdef CONFIG_OPENMOSIX +static ssize_t proc_pid_openmosix_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + struct inode * inode = file->f_dentry->d_inode; + unsigned long page; + ssize_t length; + ssize_t end; + struct task_struct *task = proc_task(inode); + + if (count > PAGE_SIZE) + count = PAGE_SIZE; + if (!(page = __get_free_page(GFP_KERNEL))) + return -ENOMEM; + + length = openmosix_proc_pid_getattr(task, + (char*)file->f_dentry->d_name.name, + (void*)page, count); + if (length < 0) { + free_page(page); + return length; + } + /* Static 4kB (or whatever) block capacity */ + if (*ppos >= length) { + free_page(page); + return 0; + } + if (count + *ppos > length) + count = length - *ppos; + end = count + *ppos; + if (copy_to_user(buf, (char *) page + *ppos, count)) + count = -EFAULT; + else + *ppos = end; + free_page(page); + return count; +} + +static ssize_t proc_pid_openmosix_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + struct inode * inode = file->f_dentry->d_inode; + char *page; + ssize_t length; + struct task_struct *task = proc_task(inode); + + if (count > PAGE_SIZE) + count = PAGE_SIZE; + if (*ppos != 0) { + /* No partial writes. */ + return -EINVAL; + } + page = (char*)__get_free_page(GFP_USER); + if (!page) + return -ENOMEM; + length = -EFAULT; + if (copy_from_user(page, buf, count)) + goto out; + + length = openmosix_proc_pid_setattr(task, + (char*)file->f_dentry->d_name.name, + (void*)page, count); +out: + free_page((unsigned long) page); + return length; +} + +static struct file_operations proc_pid_openmosix_operations = { + .read = proc_pid_openmosix_read, + .write = proc_pid_openmosix_write, +}; + +static struct file_operations proc_tid_openmosix_operations; +static struct inode_operations proc_tid_openmosix_inode_operations; +static struct file_operations proc_tgid_openmosix_operations; +static struct inode_operations proc_tgid_openmosix_inode_operations; +#endif /* CONFIG_OPENMOSIX */ + /* SMP-safe */ static struct dentry *proc_pident_lookup(struct inode *dir, struct dentry *dentry, @@ -1404,6 +1519,26 @@ inode->i_fop = &proc_pid_attr_operations; break; #endif +#ifdef CONFIG_OPENMOSIX + case PROC_TID_OPENMOSIX: + inode->i_nlink = 2; + inode->i_op = &proc_tid_openmosix_inode_operations; + inode->i_fop = &proc_tid_openmosix_operations; + break; + case PROC_TGID_OPENMOSIX: + inode->i_nlink = 2; + inode->i_op = &proc_tgid_openmosix_inode_operations; + inode->i_fop = &proc_tgid_openmosix_operations; + break; + case PROC_TID_OPENMOSIX_WHERE: + case PROC_TGID_OPENMOSIX_WHERE: + case PROC_TID_OPENMOSIX_STAY: + case PROC_TGID_OPENMOSIX_STAY: + case PROC_TID_OPENMOSIX_DEBUG: + case PROC_TGID_OPENMOSIX_DEBUG: + inode->i_fop = &proc_pid_openmosix_operations; + break; +#endif #ifdef CONFIG_KALLSYMS case PROC_TID_WCHAN: case PROC_TGID_WCHAN: @@ -1496,6 +1631,54 @@ }; #endif +#ifdef CONFIG_OPENMOSIX +static int proc_tgid_openmosix_readdir(struct file * filp, + void * dirent, filldir_t filldir) +{ + return proc_pident_readdir(filp,dirent,filldir, + tgid_openmosix_stuff, + ARRAY_SIZE(tgid_openmosix_stuff)); +} + +static int proc_tid_openmosix_readdir(struct file * filp, + void * dirent, filldir_t filldir) +{ + return proc_pident_readdir(filp,dirent,filldir, + tid_openmosix_stuff, + ARRAY_SIZE(tid_openmosix_stuff)); +} + +static struct file_operations proc_tgid_openmosix_operations = { + .read = generic_read_dir, + .readdir = proc_tgid_openmosix_readdir, +}; + +static struct file_operations proc_tid_openmosix_operations = { + .read = generic_read_dir, + .readdir = proc_tid_openmosix_readdir, +}; + +static struct dentry *proc_tgid_openmosix_lookup(struct inode *dir, + struct dentry *dentry, struct nameidata *nd) +{ + return proc_pident_lookup(dir, dentry, tgid_openmosix_stuff); +} + +static struct dentry *proc_tid_openmosix_lookup(struct inode *dir, + struct dentry *dentry, struct nameidata *nd) +{ + return proc_pident_lookup(dir, dentry, tid_openmosix_stuff); +} + +static struct inode_operations proc_tgid_openmosix_inode_operations = { + .lookup = proc_tgid_openmosix_lookup, +}; + +static struct inode_operations proc_tid_openmosix_inode_operations = { + .lookup = proc_tid_openmosix_lookup, +}; +#endif /* CONFIG_OPENMOSIX */ + /* * /proc/self: */ diff -Nur --exclude '*.orig' linux-2.6.7.org/fs/proc/root.c linux-2.6.7/fs/proc/root.c --- linux-2.6.7.org/fs/proc/root.c 2004-09-02 14:42:21.774663768 +0200 +++ linux-2.6.7/fs/proc/root.c 2004-09-02 14:46:54.104263376 +0200 @@ -18,6 +18,10 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include +#endif + struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver; #ifdef CONFIG_SYSCTL @@ -72,6 +76,9 @@ proc_sys_root = proc_mkdir("sys", NULL); #endif #endif +#ifdef CONFIG_OPENMOSIX + openmosix_proc_init(); +#endif #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) proc_mkdir("sys/fs", NULL); proc_mkdir("sys/fs/binfmt_misc", NULL); diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/arch-i386.c linux-2.6.7/hpc/arch-i386.c --- linux-2.6.7.org/hpc/arch-i386.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/arch-i386.c 2004-09-02 14:46:54.134258816 +0200 @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave); + +void fxsave_to_fsave(union i387_union *from, union i387_union *to) +{ + u8 *fcp, *tcp; + int i; + + to->fsave.cwd = from->fxsave.cwd; + to->fsave.swd = from->fxsave.swd; + to->fsave.twd = twd_fxsr_to_i387(&from->fxsave); + to->fsave.fip = from->fxsave.fip; + to->fsave.fcs = from->fxsave.fcs; + to->fsave.foo = from->fxsave.foo; + to->fsave.fos = from->fxsave.fos; + to->fxsave.padding[0] = from->fxsave.fop; + to->fxsave.padding[1] = from->fxsave.mxcsr; + + fcp = (u8 *) from->fxsave.st_space; + tcp = (u8 *) to->fsave.st_space; + + /* 8 registers of 16 bytes to copy to 10 bytes */ + for (i = 0; i < 8; i++, tcp += 10, fcp += 16) + memcpy(tcp, fcp, 10); + + memcpy(to->fxsave.xmm_space, from->fxsave.xmm_space, + sizeof(to->fxsave.xmm_space)); +} + +unsigned short twd_i387_to_fxsr(unsigned short twd); +void fsave_to_fxsave(union i387_union *from, union i387_union *to) +{ + u8 *fcp, *tcp; + int i; + + to->fxsave.cwd = from->fsave.cwd; + to->fxsave.swd = from->fsave.swd; + to->fxsave.twd = twd_i387_to_fxsr(from->fsave.twd); + to->fxsave.fop = from->fxsave.padding[0]; + to->fxsave.fip = from->fsave.fip; + to->fxsave.fcs = from->fsave.fcs; + to->fxsave.foo = from->fsave.foo; + to->fxsave.mxcsr = from->fxsave.padding[1]; + to->fxsave.fos = from->fsave.fos; + + fcp = (u8 *) from->fsave.st_space; + tcp = (u8 *) to->fxsave.st_space; + + /* 8 registers of 10 bytes to copy to 16 bytes */ + for (i = 0; i < 8; i++, tcp += 16, fcp += 10) + memcpy(tcp, fcp, 10); + + memcpy(to->fxsave.xmm_space, from->fxsave.xmm_space, + sizeof(from->fxsave.xmm_space)); +} + + +/*****************************************************************************/ +/* receive part */ + +int arch_mig_receive_specific(task_t *p, struct mig_arch_h *m) +{ + switch (m->type) + { + case MIG_ARCH_I386_LDT: + printk(KERN_WARNING "oM: mig arch ldt not handle yet.\n"); + break; + default: + printk(KERN_ERR "oM: mig arch type not handle.\n"); + return 1; + } + return 0; +} + +#define TASK_GET_USER_REGS(p) \ + ((struct pt_regs *) (THREAD_SIZE + \ + (unsigned long) p->thread_info)) - 1; + +int arch_mig_receive_proc_context(task_t *p, struct mig_task_h *m) +{ + struct pt_regs *regs; + + /* copy pt_regs */ + regs = TASK_GET_USER_REGS(p); + memcpy(regs, &m->regs, sizeof(struct pt_regs)); + + /* debugs regs */ + memcpy((caddr_t) p->thread.debugreg, (caddr_t) m->arch.debugreg, + sizeof(m->arch.debugreg)); + return 0; +} + +void arch_mig_receive_fp(task_t *p, struct mig_fp_h *fp) +{ + unlazy_fpu(p); + + /* if same kind of cpu we just memcpy the structure */ + if ((cpu_feature_has_fxsr() && fp->has_fxsr) + || (!cpu_feature_has_fxsr() && !fp->has_fxsr)) + { + memcpy((caddr_t) &p->thread.i387, (caddr_t) &fp->data, + sizeof(union i387_union)); + return; + } + + if (fp->has_fxsr) + fxsave_to_fsave(&fp->data, &p->thread.i387); + else + fsave_to_fxsave(&fp->data, &p->thread.i387); + +} + +/*****************************************************************************/ +/* send part */ + +void arch_mig_send_pre(task_t *p) +{ + if (p->mm->context.ldt) + clear_LDT(); +} + +void arch_mig_send_post(task_t *p) +{ + if (p->mm->context.ldt) + load_LDT(&p->mm->context); +} + +int arch_mig_send_specific(task_t *p) +{ + return 0; +} + +int arch_mig_send_fp(task_t *p, struct mig_fp_h *fp) +{ + unlazy_fpu(p); + fp->has_fxsr = cpu_feature_has_fxsr(); + memcpy(&fp->data, &p->thread.i387, sizeof(p->thread.i387)); + return 0; +} + +int arch_mig_send_proc_context(task_t *p, struct mig_task_h *m) +{ + struct pt_regs *regs; + + /* copy pt_regs */ + regs = TASK_GET_USER_REGS(p); + memcpy(&m->regs, regs, sizeof(struct pt_regs)); + + /* copy debugregs */ + memcpy((caddr_t)m->arch.debugreg, (caddr_t)p->thread.debugreg, + sizeof(m->arch.debugreg)); + + if (task_test_dflags(p, DDEPUTY)) + memcpy(m->arch.features, boot_cpu_data.x86_capability, + sizeof(m->arch.features)); + + return 0; +} + + +asmlinkage void ret_from_kickstart(void) __asm__("ret_from_kickstart"); + +#define loaddebug(tsk,register) \ + __asm__("movl %0,%%db" #register \ + : /* no output */ \ + :"r" (tsk->thread.debugreg[register])) + +void arch_kickstart(struct task_struct *p) +{ + struct pt_regs *regs; + regs = TASK_GET_USER_REGS(p); + + if (p->thread.debugreg[7]) { + loaddebug(p, 0); + loaddebug(p, 1); + loaddebug(p, 2); + loaddebug(p, 3); + loaddebug(p, 6); + loaddebug(p, 7); + } + + regs->xcs = __USER_CS; + + set_task_state(p, TASK_RUNNING); + /* FIXME: not sure about this one */ + flush_signals(p); + + asm("movl %0,%%esp ; jmp ret_from_kickstart" : : "r"(regs)); + /* not reached */ +} + +/*****************************************************************************/ +#include + +asmlinkage long remote_old_mmap(int n, struct pt_regs regs) +{ + struct mmap_arg_struct; + extern asmlinkage int old_mmap(struct mmap_arg_struct __user *arg); + return old_mmap((struct mmap_arg_struct *) SYSARG(0)); +} + +DO_REMOTE_SYSCALL(long, sys_iopl) +DO_REMOTE_SYSCALL(long, sys_ioperm) +DO_REMOTE_SYSCALL(long, sys_vm86old) +DO_REMOTE_SYSCALL(long, sys_vm86) diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/arch-ppc.c linux-2.6.7/hpc/arch-ppc.c --- linux-2.6.7.org/hpc/arch-ppc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/arch-ppc.c 2004-09-02 14:46:54.135258664 +0200 @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*****************************************************************************/ +/* receive part */ + +int arch_mig_receive_specific(task_t *p, struct mig_arch_h *m) +{ + return 0; +} + +int arch_mig_receive_proc_context(task_t *p, struct mig_task_h *m) +{ + memcpy(p->thread.regs, &m->regs, sizeof(struct pt_regs)); + return 0; +} + +void arch_mig_receive_fp(task_t *p, struct mig_fp_h *fp) +{ + struct thread_struct *th = &p->thread; + + memcpy(th->fpr, fp->fpr, sizeof(th->fpr)); + + th->fpscr_pad = fp->fpscr_pad; /* FIXME: not sure this one is needed */ + th->fpscr = fp->fpscr; + +} + +/*****************************************************************************/ +/* send part */ + +void arch_mig_send_pre(task_t *p) +{ +} + +void arch_mig_send_post(task_t *p) +{ +} + +int arch_mig_send_specific(task_t *p) +{ + return 0; +} + +int arch_mig_send_fp(task_t *p, struct mig_fp_h *fp) +{ + struct thread_struct *th = &p->thread; + + memcpy(fp->fpr, th->fpr, sizeof(fp->fpr)); + + fp->fpscr_pad = th->fpscr_pad; /* FIXME: not sure this one is needed */ + fp->fpscr = th->fpscr; + return 0; +} + +int arch_mig_send_proc_context(task_t *p, struct mig_task_h *m) +{ + memcpy(&m->regs, p->thread.regs, sizeof(struct pt_regs)); + return 0; +} + + +void arch_kickstart(struct task_struct *p) +{ + asm ("b ret_from_kickstart"); +} + +/*****************************************************************************/ +#include + +DO_REMOTE_SYSCALL(long, ppc_fork) +DO_REMOTE_SYSCALL(long, ppc_vfork) +DO_REMOTE_SYSCALL(long, ppc_rt_sigsuspend) +DO_REMOTE_SYSCALL(long, ppc_swapcontext) +DO_REMOTE_SYSCALL(long, ppc_fadvise64_64) +DO_REMOTE_SYSCALL(long, ppc_clone) +DO_REMOTE_SYSCALL(long, ppc_select) +DO_REMOTE_SYSCALL(long, ppc_sigsuspend) +DO_REMOTE_SYSCALL(long, sys_pciconfig_read) +DO_REMOTE_SYSCALL(long, sys_pciconfig_write) +DO_REMOTE_SYSCALL(long, sys_pciconfig_iobase) +DO_REMOTE_SYSCALL(long, sys_mmap) diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/arch-x86_64.c linux-2.6.7/hpc/arch-x86_64.c --- linux-2.6.7.org/hpc/arch-x86_64.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/arch-x86_64.c 2004-09-02 14:46:54.174252736 +0200 @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*****************************************************************************/ +/* receive part */ + +int arch_mig_receive_specific(task_t *p, struct mig_arch_h *m) +{ + switch (m->type) + { + case MIG_ARCH_I386_LDT: + printk(KERN_WARNING "oM: mig arch ldt not handle yet.\n"); + break; + default: + printk(KERN_ERR "oM: mig arch type not handle.\n"); + return 1; + } + return 0; +} + +int arch_mig_receive_proc_context(task_t *p, struct mig_task_h *m) +{ + struct pt_regs *regs; + + /* copy pt_regs */ + regs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; + memcpy(regs, &m->regs, sizeof(struct pt_regs)); + + /* debugs regs */ + p->thread.debugreg0 = m->debugreg[0]; + p->thread.debugreg1 = m->debugreg[1]; + p->thread.debugreg2 = m->debugreg[2]; + p->thread.debugreg3 = m->debugreg[3]; + p->thread.debugreg6 = m->debugreg[6]; + p->thread.debugreg7 = m->debugreg[7]; + + return 0; +} + +void arch_mig_receive_fp(task_t *p, struct mig_fp_h *fp) +{ + unlazy_fpu(p); + + /* all opterons got same fp feature */ + memcpy((caddr_t) &p->thread.i387, (caddr_t) &fp->data, + sizeof(union i387_union)); +} + +/*****************************************************************************/ +/* send part */ + +void arch_mig_send_pre(task_t *p) +{ + if (p->mm->context.ldt) + clear_LDT(); +} + +void arch_mig_send_post(task_t *p) +{ + if (p->mm->context.ldt) + load_LDT(&p->mm->context); +} + +int arch_mig_send_specific(task_t *p) +{ + return 0; +} + +int arch_mig_send_fp(task_t *p, struct mig_fp_h *fp) +{ + unlazy_fpu(p); + memcpy(&fp->data, &p->thread.i387, sizeof(p->thread.i387)); + return 0; +} + +int arch_mig_send_proc_context(task_t *p, struct mig_task_h *m) +{ + struct pt_regs *regs; + + /* copy pt_regs */ + regs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; + memcpy(&m->regs, regs, sizeof(struct pt_regs)); + + /* copy debugregs */ + m->debugreg[0] = p->thread.debugreg0; + m->debugreg[1] = p->thread.debugreg1; + m->debugreg[2] = p->thread.debugreg2; + m->debugreg[3] = p->thread.debugreg3; + m->debugreg[6] = p->thread.debugreg6; + m->debugreg[7] = p->thread.debugreg7; + + if (task_test_dflags(p, DDEPUTY)) + memcpy(m->features, boot_cpu_data.x86_capability, + sizeof(m->features)); + + /* send task segment registers. */ + /* FIXME: i really don't think this is necessary */ + m->fs = p->thread.fs; + m->gs = p->thread.gs; + + return 0; +} + + +asmlinkage void ret_from_kickstart(void) __asm__("ret_from_kickstart"); + +void arch_kickstart(struct task_struct *p) +{ + struct pt_regs *regs; + regs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; + + if (p->thread.debugreg7) { + __asm__("movq %0,%%db0" : /* */ :"r" (p->thread.debugreg0)); + __asm__("movq %0,%%db1" : /* */ :"r" (p->thread.debugreg1)); + __asm__("movq %0,%%db2" : /* */ :"r" (p->thread.debugreg2)); + __asm__("movq %0,%%db3" : /* */ :"r" (p->thread.debugreg3)); + __asm__("movq %0,%%db6" : /* */ :"r" (p->thread.debugreg6)); + __asm__("movq %0,%%db7" : /* */ :"r" (p->thread.debugreg7)); + } + + regs->cs = __USER_CS; + + set_task_state(p, TASK_RUNNING); + /* FIXME: not sure about this one */ + flush_signals(p); + + asm("movq %0,%%rsp ; jmp ret_from_kickstart" : : "r"(regs)); + /* not reached */ +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/comm.c linux-2.6.7/hpc/comm.c --- linux-2.6.7.org/hpc/comm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/comm.c 2004-09-02 14:46:54.177252280 +0200 @@ -0,0 +1,615 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR) + +unsigned long comm_remote_timo = COMM_REMOTE_TIMO; /* for remote accept */ +unsigned long comm_connect_timo = COMM_CONNECT_TIMO; /* for connection */ +unsigned long comm_reconn_timo = COMM_RECONN_TIMO; /* for reconnection */ + + +static int comm_dorecv(struct socket *, struct msghdr *, int); + + +/** + * comm_shutdown - shutdown socket + * @mlink: openMosix link to shutdown + **/ +static void comm_shutdown(om_link_t *mlink) +{ + struct socket *sock; + + if (!mlink) + return; + sock = mlink->sock; + + mlink->dlen = 0; + if (sock->ops) + sock->ops->shutdown(sock, SEND_SHUTDOWN); +} + +/** + * comm_getname - get the name of socket + * @mlink: openMosix link to shutdown + * @address: the sockaddr to fill + **/ +int comm_getname(om_link_t *mlink, struct sockaddr *address) +{ + struct socket *sock; + int val, ret; + + val = sizeof(struct sockaddr); + sock = mlink->sock; + if (!sock->ops || !sock->ops->getname) + return -1; + ret = sock->ops->getname(sock, address, &val, 0); + if (ret) + return -1; + return val; +} + +/** + * comm_data_ready - Wake the socket when data are ready + * @sk: socket to wake up + * @len: unneeded + **/ +void comm_data_ready(struct sock *sk, int len) +{ + wake_up_interruptible(sk->sk_sleep); +} + +static int comm_setup_tcp(struct socket *sock) +{ + int val; + int error; + mm_segment_t oldfs; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + /* old TOADDR/ACCEPT */ + val = 1; + if ((error = sock_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, + (char *) &val, sizeof(val)))) + goto fail; + /* FIXME: check on these, old COMM_MIGD */ + val = OPENMOSIX_CONNECTION_KEEPALIVE_INTERVAL; + if ((error = sock->ops->setsockopt(sock, IPPROTO_TCP, + TCP_KEEPINTVL, (char *) &val, sizeof(val)))) + goto fail; + + val = OPENMOSIX_CONNECTION_KEEPALIVE_MAXTRIES; + if ((error = sock->ops->setsockopt(sock, IPPROTO_TCP, + TCP_KEEPCNT, (char *) &val, sizeof(val)))) + goto fail; + + val = OPENMOSIX_CONNECTION_KEEPALIVE_TOTAL; + if ((error = sock->ops->setsockopt(sock, IPPROTO_TCP, + TCP_KEEPIDLE, (char *) &val, sizeof(val)))) + goto fail; + + val = 1; + if ((error = sock->ops->setsockopt(sock, IPPROTO_TCP, + TCP_NODELAY, (char *) &val, sizeof(val)))) + goto fail; + +fail: + set_fs(oldfs); + return error; +} + + +om_link_t * comm_socket(int family, int type, int proto) +{ + int error; + struct socket *sock; + om_link_t *mlink = NULL; + + mlink = kmalloc(sizeof(om_link_t), GFP_KERNEL); + if (!mlink) + return NULL; + + error = sock_create(family, type, proto, &sock); + if (error < 0) + goto out; + + memset(mlink, 0, sizeof(om_link_t)); + mlink->flags = COMM_FULLINK; + mlink->sock = sock; + mlink->peer = 0; + + return mlink; + +out: + kfree(mlink); + return NULL; +} + + +int comm_bind(struct socket *sock, struct sockaddr *saddr) +{ + int error; + + error = sock->ops->bind(sock, saddr, sizeof(*saddr)); + if (error == -EADDRINUSE) + printk("comm_bind() Already in use\n"); + + return error; +} + +static int comm_listen(struct socket *sock) +{ + int error; + + error = sock->ops->listen(sock, SOMAXCONN); + + return error; +} + + +int comm_connect(om_link_t *mlink, struct sockaddr *saddr, unsigned long timo) +{ + struct socket *sock = mlink->sock; + int error; + DECLARE_WAITQUEUE(wait, current); + + if (!timo) + timo = MAX_SCHEDULE_TIMEOUT; + + error = sock->ops->connect(sock, saddr, sizeof(*saddr), O_NONBLOCK); + + add_wait_queue(sock->sk->sk_sleep, &wait); + while (sock->state != SS_CONNECTED) { + set_current_state(TASK_INTERRUPTIBLE); + error = sock->ops->connect(sock, saddr, sizeof(*saddr), + O_NONBLOCK); + if (error != -EALREADY || (error=sock_error(sock->sk))) + break; + + timo = schedule_timeout(timo); + if (timo <= 0) { + error = -EAGAIN; + break; + } + } + remove_wait_queue(sock->sk->sk_sleep, &wait); + set_current_state(TASK_RUNNING); + + if (error) { + printk("comm_open_connect(): failed to connect\n"); + return error; + } + + if (sock->sk->sk_err) { + error = sock_error(sock->sk); /* cleans error.. */ + printk("comm_open_connect(): sk_err\n"); + return error; + } + + return 0; +} + + +/** + * comm_close - close an openMosix communication socket + * @mlink: openMosix link + * + * Description: + * + **/ +void comm_close(om_link_t *mlink) +{ + BUG_ON(!mlink); + + comm_shutdown(mlink); + sock_release(mlink->sock); + + kfree(mlink); +} + +/** + * comm_peek - peek the socket looking for data pending + **/ +int comm_peek(struct socket *sock) +{ + int mask; + + mask = sock->ops->poll(NULL, sock, NULL); + return (mask & POLLIN_SET) ? 1 : 0; +} + + +/** + * comm_poll - wait for a communication event, interrupt or openMosix event + * @sock: socket to poll + * @mask: polling mask + * @interruptible: is the task interruptible + * @timo: timeout (0 = MAX_SCHEDULE_TIMEOUT) + * + * Description: + * returns 1 on communication events, and 0 otherwise + */ +static int comm_poll(struct socket *sock, int mask, int interruptible, unsigned long timo) +{ + int pollmask; + static struct file sighfile = {.f_count = ATOMIC_INIT(1)}; + DECLARE_WAITQUEUE(wait, current); + + /* + * sighfile: we are required to supply a file to "hold" while we poll. + * a bit ridiculous in this context, but nobody will notice because + * f_count will never drop to 0 + */ + if (!timo) + timo = MAX_SCHEDULE_TIMEOUT; + add_wait_queue(sock->sk->sk_sleep, &wait); + for (;;) + { + set_current_state(TASK_INTERRUPTIBLE); + pollmask = sock->ops->poll(&sighfile, sock, NULL); + if ((pollmask & mask) || (interruptible && signal_pending(current))) + break; + + timo = schedule_timeout(timo); + if (timo <= 0) + break; + } + remove_wait_queue(sock->sk->sk_sleep, &wait); + set_current_state(TASK_RUNNING); + + return (pollmask & mask) ? 1 : 0; +} + + +/** + * comm_wait - wait for a message, or some other openMosix event + * + * Description: + * return 1 if there is a message, 0 if another event occured first. + **/ +int comm_wait(struct socket *sock) +{ + return comm_poll(sock, POLLIN_SET, 1, 0UL); +} + + +/** + * comm_accept - accept a connection on openMosix socket + * @ml: the socket that receive a connection + * @mlp: the new link opened will be assigned here + * @saddr: source address of the connection + * @timeout: timeout (0 = MAX_SCHEDULE_TIMEOUT) + **/ +int comm_accept(om_link_t *ml, om_link_t **mlp, struct sockaddr *saddr, + unsigned long timeout) +{ + struct socket *sock; + om_link_t *newlink; + int error = -EMFILE; + + newlink = kmalloc(sizeof(om_link_t), GFP_KERNEL); + if (!newlink) + return -ENOMEM; + + sock = sock_alloc(); + if (!sock) + goto failed_sock; + + sock->type = ml->sock->type; + sock->ops = ml->sock->ops; + + if (timeout && !comm_poll(ml->sock, POLLIN | POLLRDNORM, 0, timeout)) { + error = -EAGAIN; + goto failed; + } + + error = ml->sock->ops->accept(ml->sock, sock, 0); + if (error) + goto failed; + + /* configure the link */ + memset(newlink, 0, sizeof(om_link_t)); + newlink->sock = sock; + newlink->flags = COMM_FULLINK; + + /* set up connection options */ + error = comm_setup_tcp(sock); + if (error) + goto failed; + + *mlp = newlink; + return error; + +failed: + sock_release(sock); +failed_sock: + kfree(newlink); + *mlp = NULL; + return error; +} + +/** + * comm_flushdata() - flush remaining data from previous message + * @mlink: + * + * Description: + * If the current->om.contact has any data pending left, + * just throw it away and possibly close the openmosix_link + */ +#define VOID_BUF_SPACE_SZ 256 +static char void_buf_space[VOID_BUF_SPACE_SZ]; + +void comm_flushdata(om_link_t *mlink) +{ + struct iovec iov; + struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0, 0 }; + mm_segment_t oldfs; + int n = 0; + int boguscnt = 100; + + /* if no data left return */ + if (!mlink->dlen) + return; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + /* just fetch remaining data and throw it away */ + while (mlink->dlen <= 0) + { + iov.iov_base = void_buf_space; + iov.iov_len = VOID_BUF_SPACE_SZ; + msg.msg_flags = MSG_WAITALL | MSG_NOSIGNAL; + + n = comm_dorecv(mlink->sock, &msg, iov.iov_len); + if (n <= 0) + break; + mlink->dlen -= n; + + if (!--boguscnt) { + printk("comm_flushdata() stuck in loop\n"); + dump_stack(); + } + } + + set_fs(oldfs); +} + + +/** + * comm_dorecv - Reliable read data from socket + * @sock: socket to read from + * @msg: fill with data + * @len: lenght of the data + * + * Description: + * reliably read data on success, or if + * error == -EFAULT: returns number of bytes received otherwise + * (any other error): returns negative error. + **/ +static int comm_dorecv(struct socket *sock, struct msghdr *msg, int len) +{ + int n = 0; + int left = len; + + do { + n = sock_recvmsg(sock, msg, left, msg->msg_flags); + if (n <= 0) { + /* if we already got -EFAULT, we must report */ + if (n == -EFAULT) + { + for ( ; msg->msg_iovlen; msg->msg_iov++) { + msg->msg_iovlen--; + len -= msg->msg_iov->iov_len; + } + return len; + } + + /* .. otherwise - it is fatal - return error */ + if (n < 0) + return n; + return -EPIPE; + } + + left -= n; + if (left) { + /* ...->recvmsg() updated iovec, we update msg */ + while (!msg->msg_iov->iov_len) + { + msg->msg_iov++; + msg->msg_iovlen--; + } + } + } while (left); + return len; +} + + +/** + * comm_recv - receive a message of size @len + * @mlink: openmosix_link we're using + * @data: pointer to buffer to write message into + * @len: length of data we want + **/ +int comm_recv(om_link_t *mlink, void *data, int len) +{ + struct iovec iov; + struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0, MSG_WAITALL | MSG_NOSIGNAL }; + mm_segment_t oldfs; + int error = -1; + + BUG_ON(len > PAGE_SIZE); + BUG_ON(!mlink); + + iov.iov_base = data; + iov.iov_len = len; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + error = comm_dorecv(mlink->sock, &msg, len); + if (error != len) { + printk("comm_recv(): got %d of %d\n", error, len); + if (error >= 0) + error = -EFAULT; + comm_shutdown(mlink); + } + + set_fs(oldfs); + + return error; +} + + + +/** + * comm_send - send data and returns the bytes number of data sent + * @mlink: openmosix_link we're using + * @data: data to send + * @len: length of data + **/ +int comm_send(om_link_t *mlink , void *data, int len) +{ + struct iovec iov; + struct msghdr msg = { NULL, 0, &iov, 1, NULL, 0, MSG_NOSIGNAL }; + mm_segment_t oldfs; + int error; + + BUG_ON(!mlink); + + iov.iov_base = data; + iov.iov_len = len; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + + error = sock_sendmsg(mlink->sock, &msg, len); + if (error != len) + printk("sock_sendmsg: sent %d of %d\n", error, len); + + set_fs(oldfs); + + return error; +} + +/* ---------- openmosix specifics start here ------------ */ +#include + +void set_our_addr(int type, struct sockaddr *sa, int port) +{ + struct sockaddr_in *sa_in; + struct sockaddr_in6 *sa_in6; + + switch (type) { + case AF_INET: + sa_in = (struct sockaddr_in *) sa; + sa_in->sin_family = type; + sa_in->sin_addr.s_addr = INADDR_ANY; + sa_in->sin_port = port; + return; + case AF_INET6: + sa_in6 = (struct sockaddr_in6 *) sa; + return; + } +} + +/* lazy helper functions */ +om_link_t * comm_setup_listen(struct sockaddr *sa) +{ + om_link_t *link; + int error; + + link = comm_socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP); + if (!link) + return NULL; + + error = comm_bind(link->sock, sa); + if (error < 0) + goto fail; + + error = comm_listen(link->sock); + if (error < 0) + goto fail; + + return link; + +fail: + comm_close(link); + return NULL; +} + +om_link_t * comm_setup_connect(struct sockaddr *sa, int timo) +{ + om_link_t *link; + struct sockaddr_in *sa_in = (struct sockaddr_in *) sa; + + link = comm_socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP); + if (!link) + return NULL; + + /* FIXME: protocol independant please */ + sa_in->sin_port = REMOTE_DAEMON_PORT; + + if (comm_connect(link, sa, timo)) + goto fail; + + return link; + +fail: + comm_close(link); + return NULL; +} + +int comm_send_hd(om_link_t *link, int type, void *data, int dlen) +{ + struct mig_req_h req; + int error; + + req.type = type; + req.dlen = dlen; + + error = comm_send(link, &req, sizeof(req)); + if (error < 0) + return -1; + + error = comm_send(link, data, dlen); + if (error < 0) + return -1; + + return 0; +} + + +int comm_send_req(om_link_t *link, int type) +{ + struct mig_req_h req; + req.type = type; + return comm_send(link, &req, sizeof(req)); +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/comm-ipv4.c linux-2.6.7/hpc/comm-ipv4.c --- linux-2.6.7.org/hpc/comm-ipv4.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/comm-ipv4.c 2004-09-02 14:46:54.178252128 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include + +inline int inet_to_string(struct sockaddr_in *address, char *buffer) +{ + return sprintf(buffer, "%u.%u.%u.%u", + NIPQUAD(address->sin_addr.s_addr)); +} + +inline int inet_equal(struct sockaddr_in *a1, struct sockaddr_in *a2) +{ + return (a1->sin_addr.s_addr == a2->sin_addr.s_addr); +} + +inline int inet_diff(struct sockaddr_in *a, struct sockaddr_in *b) +{ + return a->sin_addr.s_addr - b->sin_addr.s_addr; +} + +int string_to_inet(char *buf, struct sockaddr_in *address) +{ + u32 iaddr; + unsigned int arr[4], ret; + char *endbuf; + + ret = sscanf(buf, "%u.%u.%u.%u", &arr[0], &arr[1], &arr[2], &arr[3]); + if (ret != 4 || !(arr[0] < 256 && arr[1] < 256 + && arr[2] < 256 && arr[3] < 256)) + return 0; + iaddr = (arr[0] << 24) + (arr[1] << 16) + (arr[2] << 8) + arr[3]; + address->sin_addr.s_addr = htonl(iaddr); + + endbuf = buf; + while (*endbuf && (*endbuf == '.' || (isdigit(*endbuf)))) + endbuf++; + address->sin_family = AF_INET; + return endbuf - buf; +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/comm-ipv6.c linux-2.6.7/hpc/comm-ipv6.c --- linux-2.6.7.org/hpc/comm-ipv6.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/comm-ipv6.c 2004-09-02 14:46:54.179251976 +0200 @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include + +int inet6_to_string(struct sockaddr_in6 *address, char *buffer) +{ + return sprintf(buffer, "%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x", + NIP6(address->sin6_addr)); +} + + +inline int inet6_equal(struct sockaddr_in6 *a1, struct sockaddr_in6 *a2) +{ + return (memcmp((char *) &a1->sin6_addr, (char *) &a2->sin6_addr, + sizeof(struct in6_addr)) == 0); +} + + +int string_to_inet6(char *buf, struct sockaddr_in6 *address) +{ + char *endbuf; + int arr[8], ret; + + ret = sscanf(buf, "%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x", + &arr[0], &arr[1], &arr[2], &arr[3], + &arr[4], &arr[5], &arr[6], &arr[7]); + if (ret != 8) + return 0; + + for (ret = 0; ret < 8; ret++) + address->sin6_addr.s6_addr16[ret] = htons(arr[ret]); + + endbuf = buf; + while (*endbuf && (*endbuf == ':' || (isxdigit(*endbuf)))) + endbuf++; + address->sin6_family = AF_INET6; + return endbuf - buf; +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/debug.c linux-2.6.7/hpc/debug.c --- linux-2.6.7.org/hpc/debug.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/debug.c 2004-09-02 14:46:54.214246656 +0200 @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +void debug_mlink(om_link_t *x) +{ + printk("mlink:\n"); + printk("socket @ = %p, ", x->sock); + printk("flags = %d, ", x->flags); + printk("dlen = %d\n", x->dlen); + printk("peer = %d, ", x->peer); + printk("hidelen = %d\n", x->hidelen); +} + + +void debug_page(unsigned long addr) +{ + unsigned long digest = 0; + char *ptr = (char *) addr; + int i; + + for (i = 0; i < 4096; i++) + digest += ptr[i] * i; + + printk("sum of 0x%p is %lu\n", (void *) addr, digest); +} + +void debug_vmas(struct mm_struct *mm) +{ + struct vm_area_struct *vma; + + if (!mm) { + printk(KERN_ERR "debug_vma(): no mm !\n"); + return; + } + + printk(KERN_ERR "======== [LISTING VMA] ========\n"); + for (vma = mm->mmap; vma; vma = vma->vm_next) { + printk(KERN_ERR "vma: [%.8lx:%.8lx]\n", vma->vm_start, + vma->vm_end); + } +} + +void debug_signals(struct task_struct *p) +{ + struct signal_struct *signal; + + signal = p->signal; + + printk(KERN_ERR "=========== [DEBUG SIGNALS] ========\n"); + printk(KERN_ERR "blocked: %lx real_blocked: %lx\n", p->blocked, + p->real_blocked); + printk(KERN_ERR "sigpending: %lx\n", p->pending.signal); +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/debug-i386.c linux-2.6.7/hpc/debug-i386.c --- linux-2.6.7.org/hpc/debug-i386.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/debug-i386.c 2004-09-02 14:46:54.215246504 +0200 @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void debug_regs(void) +{ + struct pt_regs *reg; + reg = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) current->thread_info)) - 1; + + printk("pt_regs:\n"); + printk("ebx: 0x%lx, ecx: 0x%lx, edx: 0x%lx\n", reg->ebx, reg->ecx, reg->edx); + printk("esi: 0x%lx, edi: 0x%lx, ebp: 0x%lx\n", reg->esi, reg->edi, reg->ebp); + printk("eax: 0x%lx, xds: 0x%x, xes: 0x%x\n", reg->eax, reg->xds, reg->xes); + printk("orig_eax: 0x%lx, eip: 0x%lx, xcs: 0x%x\n", reg->orig_eax, reg->eip, reg->xcs); + printk("eflags: 0x%lx, esp: 0x%lx, xss: 0x%x\n", reg->eflags, reg->esp, reg->xss); +} + + +void inline debug_thread(struct thread_struct *t) +{ + printk("thread_struct:\n"); + printk("esp0: 0x%lx, sysenter_cs: 0x%lx\n",t->esp0, t->sysenter_cs); + printk("eip: 0x%lx, esp: 0x%lx", t->eip, t->esp); + +} + +/* shamelessly stolen, this is useful to debug a user space + * process when it dies on remote */ +void show_user_registers(task_t *p) +{ + int i; + unsigned long esp; + unsigned short ss; + unsigned long prev_code; + struct pt_regs *regs; + + if (!p->mm) { + printk(KERN_ERR "show_user_registers(): no mm !\n"); + return; + } + regs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; + + esp = regs->esp; + ss = regs->xss & 0xffff; + + printk("CPU: %d\nEIP: %04x:[<%08lx>] %s\nEFLAGS: %08lx\n", + smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags); + print_symbol("EIP is at %s\n", regs->eip); + printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", + regs->eax, regs->ebx, regs->ecx, regs->edx); + printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", + regs->esi, regs->edi, regs->ebp, esp); + printk("ds: %04x es: %04x ss: %04x\n", + regs->xds & 0xffff, regs->xes & 0xffff, ss); + printk("Process %s (pid: %d, BOGUSthreadinfo=%p task=%p)", + p->comm, p->pid, current_thread_info(), p); + + printk("\nStack: "); + show_stack(NULL, (unsigned long*)esp); + + prev_code = regs->eip - 20; + + printk("code before eip: "); + for(i = 0; i < 20 ; i++) + { + unsigned char c; + if(__get_user(c, &((unsigned char*)prev_code)[i])) + break; + printk("%02x ", c); + } + printk("\n"); + + + printk("Code: "); + for(i = 0; i < 20 ; i++) + { + unsigned char c; + if(__get_user(c, &((unsigned char*)regs->eip)[i])) { + printk(" Bad EIP value."); + break; + } + printk("%02x ", c); + } + printk("\n"); +} + diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/debug-ppc.c linux-2.6.7/hpc/debug-ppc.c --- linux-2.6.7.org/hpc/debug-ppc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/debug-ppc.c 2004-09-02 14:46:54.217246200 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void debug_regs(void) +{ + struct pt_regs *reg; + reg = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) current->thread_info)) - 1; +} + + +void inline debug_thread(struct thread_struct *t) +{ +} + + +/* shamelessly stolen, this is useful to debug a user space + * process when it dies on remote */ +void show_user_registers(task_t *p) +{ +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/debug-x86_64.c linux-2.6.7/hpc/debug-x86_64.c --- linux-2.6.7.org/hpc/debug-x86_64.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/debug-x86_64.c 2004-09-02 14:46:54.220245744 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void debug_regs(void) +{ + struct pt_regs *reg; + reg = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) current->thread_info)) - 1; + + printk("pt_regs:\n"); +} + + +void inline debug_thread(struct thread_struct *t) +{ + printk("thread_struct:\n"); +} + + +void show_user_registers(task_t *p) +{ +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/deputy.c linux-2.6.7/hpc/deputy.c --- linux-2.6.7.org/hpc/deputy.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/deputy.c 2004-09-02 14:46:54.221245592 +0200 @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include + +NORET_TYPE void deputy_die_on_communication(void) +{ + printk("deputy communication died.\n"); + do_exit(SIGKILL); +} + +typedef long (*function_t)(); + +extern function_t sys_call_table[]; + +/** + * deputy_do_syscall - process a syscall coming from remote + **/ +static int deputy_do_syscall(task_t *p) +{ + struct mig_syscall_h s; + struct mig_syscall_ret_h r; + int error; + long (*fct)(); + + error = comm_recv(p->om.contact, &s, sizeof(s)); + if (error < 0) + return -1; + + printk(KERN_ERR "oM: deputy receive syscall %d\n", s.n); + + /* do the syscall and put reply in r */ + fct = sys_call_table[s.n]; + + error = comm_send_hd(p->om.contact, REM_SYSCALL | REPLY, &r, sizeof(r)); + if (error < 0) + return -1; + + printk(KERN_ERR "oM: deputy reply to syscall %d\n", s.n); + + return 0; +} + +static int deputy_do_signal(task_t *p) +{ + struct mig_signal_h s; + int error; + + error = comm_recv(p->om.contact, &s, sizeof(s)); + if (error < 0) + return -1; + + /* + while (s.sigs.sig) { + sig = ffz(~s.sigs.sig) + 1; + send_sig(sig, current, 1); + s.sigs.sig &= ~(1 << (sig - 1)); + } + */ + return 0; +} + +/** + * deputy_main_loop - process has receive an interrupt in communication + **/ +static void deputy_process_misc(task_t *p) +{ + printk(KERN_ERR "oM: deputy_process_misc\n"); + if (has_pending_signals(p->signal, p->blocked)) { + printk(KERN_ERR "signals\n"); + debug_signals(p); + flush_signals(p); + } +} + +/** + * deputy_process_communication - process has receive communication in deputy + **/ +static void deputy_process_communication(task_t *p) +{ + struct mig_req_h req; + int error; + + error = comm_recv(p->om.contact, &req, sizeof(req)); + if (error < 0) + return; + + switch (req.type) + { + case 0: + deputy_die_on_communication(); + break; + case REM_BRING_HOME: + task_go_home(p); + break; + case REM_SYSCALL: + deputy_do_syscall(p); + break; + case REM_SIGNAL: + deputy_do_signal(p); + break; + default: + printk(KERN_ERR "oM: Process [%s] uid [%d] killed." + "received unexpected message type [0x%x]" + "from remote.\n", + p->comm, p->pid, req.type); + } +} + +/** + * deputy_main_loop - process loop when process is deputy + **/ +void deputy_main_loop(void) +{ + int has_communication; + + while (task_test_dflags(current, DDEPUTY)) + { + has_communication = comm_wait(current->om.contact->sock); + if (!has_communication) + deputy_process_misc(current); + else + deputy_process_communication(current); + } +} + +/** + * deputy_startup - startup deputy process + **/ +void deputy_startup(task_t *p) +{ + printk(KERN_ERR "oM: deputy_startup()\n"); + task_set_dflags(p, DDEPUTY); + /* exit_mm(p); */ +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/fs.c linux-2.6.7/hpc/fs.c --- linux-2.6.7.org/hpc/fs.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/fs.c 2004-09-02 14:46:54.225244984 +0200 @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#define for_each_remote_dentry(d) \ + for (d = rinode_list; d; d = (struct dentry *) d->d_fsdata) + + +static void remote_dentry_iput(struct dentry *dp, struct inode *ip) +{ + /* DUMMY */ +} + + +spinlock_t rinode_list_lock = SPIN_LOCK_UNLOCKED; + +static struct dentry *rinode_list = 0; + +struct super_operations all_bad_super_operations = { + .alloc_inode = 0, + .destroy_inode = 0, + .read_inode = 0, + .write_inode = 0, +}; + +struct super_block bad_super_block = { + .s_dev = 0, + .s_op = &all_bad_super_operations, +}; + +static struct vfsmount remote_vfsmnt = { + +}; + +static int remote_dentry_delete(struct dentry *dentry) +{ + struct dentry *it; + + /* is the dentry the head of the list */ + spin_lock(&rinode_list_lock); + if (dentry == rinode_list) + rinode_list = (struct dentry *) dentry->d_fsdata; + else + for_each_remote_dentry(it) { + if (dentry == (struct dentry *) it->d_fsdata) { + it->d_fsdata = dentry->d_fsdata; + break; + } + } + spin_unlock(&rinode_list_lock); + return 1; +} + +static struct dentry_operations remote_dentry_ops = +{ + .d_delete = remote_dentry_delete, + .d_iput = remote_dentry_iput, +}; + +struct vm_operations_struct rinode_mmap = +{ + .nopage = filemap_nopage, +}; + +static int remote_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + if (vma->vm_flags & VM_SHARED) + panic("REMOTE VM_SHARED mmap"); + vma->vm_ops = &rinode_mmap; + return 0 ; +} + +static struct file_operations remote_file_operations = +{ + .mmap = remote_file_mmap, +}; + +struct address_space_operations remote_aops = +{ + .readpage = remote_readpage, +}; + +/** + * task_held_files_clear - clear all held files + **/ +void task_held_files_clear(struct task_struct *p) +{ + unsigned int i; + int n; + struct held_file *h; + + n = p->om.held_allocated; + if (!n) + return; + h = p->om.held_files; + + task_lock(p); + p->om.held_files = NULL; + p->om.held_allocated = 0; + task_unlock(p); + + for (i = 0; i < n; i++) + { + if (!h[i].f) + continue; + + if (h[i].denywrite) + allow_write_access(h[i].f); + + fput(h[i].f); + } + kfree(h); +} + +#define DEFAULT_ALLOCATION 10 + +#define ALLOCATED_NEW 1 +#define ALLOCATED_NEW_AND_DENY 2 +#define ADDED_A_DENY 3 +#define FOUND_OLD 4 +int task_held_files_add(task_t *p, struct file *fp, int denywrite) +{ + struct held_file *nh, *oh; + struct mm_struct *mm; + int i, new; + + if (!p->om.held_allocated) + { + mm = p->mm; + if (mm && atomic_read(&mm->mm_realusers) > 1) + return 0; + for (i = DEFAULT_ALLOCATION; i > 0; i >>= 1) + if ((nh = (struct held_file *) + kmalloc(i * sizeof(struct held_file), + GFP_KERNEL))) + break; + + if (!nh) + return -ENOMEM; + + memset(nh, 0, i * sizeof(struct held_file)); + + task_lock(p); + p->om.held_files = nh; + p->om.held_allocated = i; + task_unlock(p); + + new = 0; + } + else + { + new = -1; + for (i = 0; i < p->om.held_allocated; i++) + if ((struct file *)p->om.held_files[i].f == fp) + { + if (!denywrite || p->om.held_files[i].denywrite) + return FOUND_OLD; + if (deny_write_access(fp)) + return -ETXTBSY; + p->om.held_files[i].denywrite = 1; + return ADDED_A_DENY; + } + else if (new == -1 && !p->om.held_files[i].f) + new = i; + if (new == -1) + { + nh = NULL;/* COMPILER BUG -- hope it is optimized out */ + for (i = DEFAULT_ALLOCATION; i > 0; i >>= 1) + if ((nh = (struct held_file *) + kmalloc(i * sizeof(struct held_file), + GFP_KERNEL))) + break; + if (!i) + return -ENOMEM; + + for (new = p->om.held_allocated + i - 1; + new >= p->om.held_allocated; new--) + nh[new].f = NULL; + + for (new = 0; new < p->om.held_allocated; new++) + nh[new] = p->om.held_files[new]; + + oh = p->om.held_files; + + task_lock(p); + p->om.held_files = nh; + p->om.held_allocated += i; + task_unlock(p); + + kfree(oh); + } + } + get_file(fp); + + task_lock(p); + p->om.held_files[new].f = fp; + task_unlock(p); + + if ((p->om.held_files[new].denywrite = denywrite)) + { + if (deny_write_access(fp)) + { + task_lock(p); + p->om.held_files[new].f = NULL; + task_unlock(p); + return -ETXTBSY; + } + return ALLOCATED_NEW_AND_DENY; + } + else + return ALLOCATED_NEW; +} + +void task_held_files_undo(task_t *p, struct file *fp, int result) +{ + unsigned int i; + + if (result == FOUND_OLD) + return; + for (i = 0; i < p->om.held_allocated; i++) + { + if ((struct file *)p->om.held_files[i].f != fp) + continue; + + switch (result) + { + case ADDED_A_DENY: + case ALLOCATED_NEW_AND_DENY: + if (!p->om.held_files[i].denywrite) + printk("%d: mosix_undo_last_file_registration - no denywrite\n", p->pid); + + else + allow_write_access(fp); + if (result == ADDED_A_DENY) + break; + case ALLOCATED_NEW: + fput(fp); + task_lock(current); + p->om.held_files[i].f = NULL; + task_unlock(current); + break; + } + return; + } + printk("%d: mosix_undo_last_file_registration - not found\n", + p->pid); +} + +int task_held_files_rebuild(task_t *p) +{ + struct vm_area_struct *vma, *vmb; + struct mm_struct *mm = p->mm; + struct held_file *hf = NULL, *old; + unsigned int i, n; + int oldn; + unsigned int denywrite; + struct file *this; + + if (task_test_dflags(p, DDEPUTY)) + { + if (task_test_dflags(p, DINCOMING)) + task_set_dflags(p, DDELAYHELD); + /* FIXME + else + mosix_update_remote_files(); + */ + return 0; + } + + if (atomic_read(&mm->mm_realusers) > 1) + { + task_held_files_clear(p); /* discard old */ + return -EBUSY; /* thread */ + } + + /* because we are the only clone, no MM lock is needed */ + /* and the initial count cannot change */ + + for (n = 0, vma = mm->mmap; vma; vma = vma->vm_next) + { + this = vma->vm_file; + if (!this) + continue; + + for (vmb = mm->mmap; vmb != vma; vmb = vmb->vm_next) + if (vmb->vm_file == vma->vm_file) + break; + if (vmb == vma) + { + if (this->f_dentry->d_inode->i_mapping->i_mmap_writable != 0) + goto monkey; + n++; + } + } + + if (n && !(hf = kmalloc(n * sizeof(struct held_file), GFP_KERNEL))) + { + task_held_files_clear(p); /* discard old */ + return -ENOMEM; + } + + for (n = 0, vma = mm->mmap; vma; vma = vma->vm_next) + { + this = vma->vm_file; + if (!this) + continue; + + for (vmb = mm->mmap; vmb != vma; vmb = vmb->vm_next) + if (vmb->vm_file == this) + goto already_placed; + denywrite = 0; + for (; vmb; vmb = vmb->vm_next) + if (vmb->vm_file == this && (vmb->vm_flags & VM_DENYWRITE)) + { + denywrite = 1; + atomic_dec(&this->f_dentry->d_inode->i_writecount); + break; + } + get_file(this); + hf[n].f = this; + hf[n++].denywrite = denywrite; + already_placed:; + } + /* must not use "task_held_files_clear" because it could sleep */ + /* in 'fput' when another held file becomes VMONKEY */ + oldn = p->om.held_allocated; + old = p->om.held_files; + + task_lock(p); + p->om.held_files = hf; + p->om.held_allocated = n; + task_unlock(p); + + if (old) + { + for (i = 0; i < oldn; i++) + { + this = old[i].f; + if (!this) + continue; + if (old[i].denywrite) + allow_write_access(this); + fput(this); + } + kfree(old); + } + /* final race check: has any file been made monkey meanwhile? */ + for (i = 0; i < n; i++) + if (hf[i].f->f_dentry->d_inode->i_mapping->i_mmap_writable != 0) + goto monkey; + return 0; +monkey: + task_held_files_clear(p); + tell_process(p, DREQ_CHECKSTAY); + return -EDOM; +} + +/** + * task_maps_inode - Check if a task @p maps the inode @ip + **/ +int task_maps_inode(struct task_struct *p, struct inode *ip) +{ + unsigned int i; + int n, ret = 0; + struct held_file *h; + + task_lock(p); + n = p->om.held_allocated; + if (!n) + goto out; + + for (h = p->om.held_files, i = 0; i < n; i++) + if (h[i].f && (h[i].f)->f_dentry->d_inode == ip) + { + ret = 1; + break; + } +out: + task_unlock(p); + return ret; +} + +/** + * get_remote_file - Get a struct file + * @origin: node of origin + * @fpr: struct file address on deputy + * @dpr: struct dentry address on deputy + * @uniq: ?? on deputy + * @isize: size on deputy + * @nopage: nopage prototype address on deputy + **/ +struct file * get_remote_file(u32 origin, struct file *fpr, + struct dentry *dpr, u64 uniq, off_t isize, + nopage_t nopage) +{ + struct file *file; + struct dentry *dentry, *dentry2; + struct inode *inode, *inode2; + struct vm_area_struct *vma; + int cng; + struct dentry *to_dput = NULL; + struct inode *to_iput = NULL; + + /* search file already mapped which got same params, then return it */ + for (vma = current->mm->mmap; vma; vma = vma->vm_next) + { + file = vma->vm_file; + if (!file || home_file(file) != fpr) + continue; + + inode = file->f_dentry->d_inode; + if (inode->u.remote_i.origin == origin + && inode->u.remote_i.dp == dpr + && inode->u.remote_i.unique == uniq + && inode->i_size == isize + && inode->u.remote_i.nopage == nopage) + { + get_file(file); + return file; + } + } + + file = get_empty_filp(); + if (!file) + return NULL; + file->f_vfsmnt = &remote_vfsmnt; + + spin_lock(&rinode_list_lock); + for_each_remote_dentry(dentry) + { + inode = dentry->d_inode; + if (inode->u.remote_i.origin == origin + && inode->u.remote_i.dp == dpr) + goto join_in; + } + spin_unlock(&rinode_list_lock); + + inode = new_inode(&bad_super_block); + if (!inode) + { + put_filp(file); + return NULL; + } + inode->i_mode = S_IFREG; + inode->u.remote_i.origin = origin; + inode->u.remote_i.dp = dpr; + inode->u.remote_i.unique = uniq; + inode->u.remote_i.nopage = nopage; + inode->i_size = isize; + inode->i_fop = &remote_file_operations; + inode->i_mapping->a_ops = &remote_aops; + dentry = d_alloc(NULL, &(const struct qstr) { 0, "/", 1 }); + if (!dentry) + { + put_filp(file); + iput(inode); + return NULL; + } + dentry->d_parent = dentry; + + /* any copy created while we slept? */ + spin_lock(&rinode_list_lock); + for_each_remote_dentry(dentry2) + { + inode2 = dentry2->d_inode; + if (inode2->u.remote_i.origin == origin + && inode2->u.remote_i.dp == dpr) + { + to_iput = inode; + to_dput = dentry; + dentry = dentry2; + inode = inode2; + goto join_in; + } + } + dentry->d_op = &remote_dentry_ops; + dentry->d_inode = inode; + dentry->d_fsdata = (void *) rinode_list; + rinode_list = dentry; + file->f_dentry = dentry; + file->f_op = &remote_file_operations; + file->f_mode = 1; + file->f_mapping = inode->i_mapping; + home_file(file) = fpr; + spin_unlock(&rinode_list_lock); + + return file; + +join_in: + cng = (inode->u.remote_i.unique != uniq) || + (inode->u.remote_i.nopage != nopage) || + (isize < inode->i_size); + inode->i_size = isize; + if (cng) + { + inode->u.remote_i.unique = uniq; + inode->u.remote_i.nopage = nopage; + } + dget(dentry); + + spin_unlock(&rinode_list_lock); + + if (to_iput) + iput(to_iput); + if (to_dput) + dput(to_dput); + if (cng) + { + down(&inode->i_sem); + truncate_inode_pages(inode->i_mapping, 0); + up(&inode->i_sem); + } + file->f_dentry = dentry; + file->f_op = &remote_file_operations; + file->f_mode = FMODE_READ; + file->f_mapping = inode->i_mapping; + home_file(file) = fpr; + + return file; +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/Kconfig linux-2.6.7/hpc/Kconfig --- linux-2.6.7.org/hpc/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/Kconfig 2004-09-02 14:46:54.226244832 +0200 @@ -0,0 +1,44 @@ +# +# HPC configuration +# + +menu "HPC options" + +config OPENMOSIX + bool "Enable OpenMosix clustering" + help + Say Y to support process migration and automatic + load-balancing within a cluster + +config OPENMOSIX_VERBOSE + bool "Enable OpenMosix to be more verbose" + depends OPENMOSIX + default n + +config OPENMOSIX_MIGRATION_VERBOSE + bool "Add some message when migrating" + depends OPENMOSIX_VERBOSE + default n + help + Say Y will throw message about migration into syslog + +config OPENMOSIX_DEBUG + bool "Enable OpenMosix debug" + depends OPENMOSIX + default n + +config OPENMOSIX_MIGRATION_DEBUG + bool "Add lots of message and print step when migrating" + depends OPENMOSIX_DEBUG + default n + help + Say Y will throw lot of debug message about migration into syslog + +config OPENMOSIX_PROC_DEBUG + bool "Add debug files on procfs" + depends OPENMOSIX_DEBUG + default n + help + Export some variables through /proc for debugging + +endmenu diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/kernel.c linux-2.6.7/hpc/kernel.c --- linux-2.6.7.org/hpc/kernel.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/kernel.c 2004-09-02 14:46:54.257240120 +0200 @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct openmosix_options om_opts; + +/* kernel calls hooks */ +int openmosix_pre_clone(void) +{ + task_t *p = current; + struct mm_struct *mm = p->mm; + + if (mm) + atomic_inc(&mm->mm_realusers); + + task_set_stay(p, DSTAY_FOR_CLONE); + return 0; +} + +void openmosix_post_clone(void) +{ + task_t *p = current; + struct mm_struct *mm = p->mm; + + if (atomic_read(&mm->mm_realusers) == 1) + task_clear_stay(p, DSTAY_FOR_CLONE); +} + +void openmosix_no_longer_monkey(struct inode *ip) +{ + task_t *p; + + read_lock(&tasklist_lock); + for_each_process(p) { + if (task_maps_inode(p, ip)) + { + task_set_dreqs(p, DREQ_CHECKSTAY); + if (task_test_om_wakeable(p)) + task_om_wake(p); + } + } + read_unlock(&tasklist_lock); +} + +int remote_need_while_asleep(task_t *p) +{ + return ((process_told(p, DREQ_CHECKCONF) && p->om.whereto != MUSTGOHOME) + || process_told(p, DREQ_EXITDFSA) + || (URGENT_REMOTE_CONDITIONS(p) && !(p->om.dflags & + (DSENTURGENT | DPASSING | DINCOMING)))); +} + + +int om_wakeable(task_t *p) +{ + return task_test_om_wakeable(p); +} + +int stay_me_and_my_clones(int reasons) +{ + task_t *p, *me = current; + struct mm_struct *mm = me->mm; + + task_lock(me); + task_set_stay(me, reasons); + task_unlock(me); + if (atomic_read(&mm->mm_realusers) > 1) { + read_lock(&tasklist_lock); + for_each_process(p) { + if (p->mm == mm && p != me) { + task_lock(p); + task_set_stay(p, reasons); + task_unlock(p); + } + } + read_unlock(&tasklist_lock); + } + return 0; +} + +void unstay_mm(struct mm_struct *mm) +{ + task_t *p; + + if (atomic_read(&mm->mm_realusers) == 1 && mm == current->mm) + { + task_set_dreqs(current, DREQ_CHECKSTAY); + return; + } + read_lock(&tasklist_lock); + for_each_process(p) + if (p->mm == mm) + task_set_dreqs(p, DREQ_CHECKSTAY); + read_unlock(&tasklist_lock); +} + +/** + * openmosix_events_need - Return if task need some oM events to be completed + **/ +int openmosix_events_need(task_t *p) +{ + om_task_t *om = &p->om; + + if (task_test_dreqs(p, (DREQ_NICECNG|DREQ_UPDOVERHEADS|DREQ_CHECKCONF| + DREQ_INFOCNG|DREQ_DFSASYNC|DREQ_CAPCNG| + DREQ_CHECKSTAY|DREQ_URGENT))) + return 1; + + if (om->whereto) + return 1; + + return 0; +} + +/** + * openmosix_events_run - Process events that need to be completed + **/ +void openmosix_events_run(task_t *p) +{ + if (task_test_dreqs(p, DREQ_CHECKSTAY)) + task_check_stay(p); +} + + +static inline int remote_pre_usermode(void) +{ + task_t *p = current; + + if (comm_peek(p->om.contact->sock)) + remote_do_comm(p); + return 0; +} + +static inline int deputy_pre_usermode(void) +{ + deputy_main_loop(); + return 0; +} + +/** + * openmosix_pre_usermode - process some pre usermode events for current + **/ +asmlinkage int openmosix_pre_usermode(struct pt_regs regs) +{ + if (task_test_dflags(current, DINCOMING)) + return 0; + local_irq_enable(); + if (task_test_dflags(current, DREMOTE)) + return remote_pre_usermode(); + if (task_test_dflags(current, DDEPUTY)) + return deputy_pre_usermode(); + return 0; +} + +void openmosix_init(void) +{ + /* kick off the kernel threads: */ + kernel_thread(openmosix_mig_daemon, NULL, 0); + kernel_thread(openmosix_migsend_daemon, NULL, 0); +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/Makefile linux-2.6.7/hpc/Makefile --- linux-2.6.7.org/hpc/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/Makefile 2004-09-02 14:46:54.258239968 +0200 @@ -0,0 +1,21 @@ +obj-y := \ + kernel.o \ + proc.o \ + task.o \ + service.o \ + comm.o \ + mig_recv.o \ + mig_send.o \ + mig_ctrl.o \ + mem.o \ + fs.o \ + remote.o \ + syscalls.o \ + deputy.o + +obj-y += arch-$(ARCH).o + +obj-$(CONFIG_INET) += comm-ipv4.o +obj-$(CONFIG_IPV6) += comm-ipv6.o + +obj-$(CONFIG_OPENMOSIX_DEBUG) += debug.o debug-$(ARCH).o diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/mem.c linux-2.6.7/hpc/mem.c --- linux-2.6.7.org/hpc/mem.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/mem.c 2004-09-02 14:46:54.259239816 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * obtain_mm - obtain an mm context + * + * Description: + * Get an mm_struct and initialize it. Associate + * with our process. + **/ +int obtain_mm(task_t *p) +{ + struct mm_struct *mm, *active_mm; + int err; + + if (p->mm && !task_test_dflags(p, DDEPUTY)) + panic("openmosix: process->mm context had already"); + /* + if (p->mm && task_test_dflags(p, DDEPUTY)) + exit_mm(p); + */ + if (!(mm = mm_alloc())) + return -ENOMEM; + if ((err = init_new_context(p, mm))) + { + task_unlock(p); + mmdrop(mm); + return err; + } + + spin_lock(&mmlist_lock); + list_add(&mm->mmlist, &init_mm.mmlist); + mmlist_nr++; + spin_unlock(&mmlist_lock); + + task_lock(p); + active_mm = p->active_mm; + p->mm = mm; + p->active_mm = mm; + task_unlock(p); + + activate_mm(active_mm, mm); + mmdrop(active_mm); + return 0; +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/mig_ctrl.c linux-2.6.7/hpc/mig_ctrl.c --- linux-2.6.7.org/hpc/mig_ctrl.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/mig_ctrl.c 2004-09-02 14:46:54.263239208 +0200 @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * task_remote_expel - call from REMOTE to send a task to DEPUTY + * @p: task which will come back + **/ +int task_remote_expel(task_t *p) +{ + BUG_ON(!task_test_dflags(p, DREMOTE)); + + if (mig_send_hshake(p, p->om.contact, HSHAKE_MIG_REQUEST)) + goto failed; + + if (mig_do_send(p)) { + goto failed; + } + + /* FIXME exit task */ + + return 0; +failed: + printk(KERN_ERR "oM: task_remote_expel() failed\n"); + return -1; +} + +/** + * task_remote_wait_expel - call from REMOTE to send a task to DEPUTY + * @p: task which will come back + **/ +int task_remote_wait_expel(task_t *p) +{ + int error; + struct mig_req_h req; + + comm_send_req(p->om.contact, REM_BRING_HOME); + + error = comm_recv(p->om.contact, &req, sizeof(req)); + if (error < 0) + return -1; + if (req.type != DEP_COMING_HOME) { + printk(KERN_ERR "oM: task_remote_wait_expel: !DEP_COMING_HOME\n"); + return -1; + } + + return task_remote_expel(p); +} + +/** + * task_local_send - Send a local task to remote + * @p: task to send + * @whereto: destination sockaddr + * @reason: reason to send there (if any) + **/ +static int task_local_send(task_t *p, struct sockaddr *whereto, int reason) +{ + om_link_t *mlink; + int error = 0; + + /* + if (!p->om.held_files) + if ((error = task_held_files_rebuild(p))) + { + printk(KERN_ERR "oM: error held_files rebuilding\n"); + return error; + } + */ + + mlink = comm_setup_connect(whereto, 0); + if (!mlink) { + printk(KERN_ERR "oM: error comm_setup_connect\n"); + error = -1; + goto failed; + } + + task_set_comm(p, mlink); + task_set_dflags(p, DDEPUTY); + + /* see if other part is with on this */ + if (mig_send_hshake(p, mlink, HSHAKE_MIG_REQUEST)) + goto failed; + + if (mig_do_send(p)) { + printk(KERN_ERR "oM: task_move_local2remote(): mig_do_send failed\n"); + error = -1; + goto failed; + } + + deputy_startup(p); + return 0; + +failed: + printk(KERN_ERR "oM: local2remote() failed\n"); + task_clear_dflags(p, DDEPUTY); + if (mlink) + comm_close(mlink); + return error; +} + + + +/** + * task_local_bring - Receive task back in the deputy stub + * @p: deputy task to receive + * @reason: reason to send (if any) + **/ +static int task_local_bring(task_t *p, int reason) +{ + int error; + om_link_t *link; + + printk(KERN_ERR "oM: remote2local()\n"); + + if (obtain_mm(p)) { + printk(KERN_ERR "unable to obtain mm\n"); + goto failed; + } + + /* send remote request */ + comm_send_req(p->om.contact, DEP_COMING_HOME); + + /* see if other part is with on this */ + if (mig_recv_hshake(p->om.contact)) + goto failed; + + /* receive the process back */ + error = mig_do_receive(p); + if (error) + goto failed; + + task_clear_dflags(p, DDEPUTY); + link = task_set_comm(p, NULL); + comm_close(link); + + return 0; +failed: + printk(KERN_ERR "oM: remote2local() failed\n"); + return -1; +} + +/** + * task_move_remote2remote - migrate a task from remote to remote + * @p: task to send + * @whereto: whereto + * @reason: reason to send (if any) + **/ +static int task_move_remote2remote(task_t *p, struct sockaddr * whereto, + int reason) +{ + printk(KERN_ERR "oM: remote2remote not implemented.\n"); + return 0; +} + +/** + * task_move_to_node - send a task to a node + * @p: task to send + * @whereto: destination sockaddr + * @reason: why + **/ +int task_move_to_node(struct task_struct *p, struct sockaddr * whereto, + int reason) +{ + int error; + + if (task_test_stay(p, DSTAY)) { + printk(KERN_DEBUG "oM: Task can't move. check stay reason\n"); + return -1; + } + + task_set_dflags(p, DPASSING); + + if (!task_test_dflags(p, DREMOTE) && whereto) + error = task_local_send(p, whereto, reason); + else { + error = (whereto) + ? task_move_remote2remote(p, whereto, reason) + : task_local_bring(p, reason); + } + task_clear_dflags(p, DPASSING); + + if (error) + return -1; + + return 0; +} + +/** + * task_go_home - Migrate task to home + **/ +int task_go_home(task_t *p) +{ + if (!task_test_dflags(p, DMIGRATED)) { + printk(KERN_INFO "oM: task is already home.\n"); + return -1; + } + + if (task_test_dflags(p, DDEPUTY)) + task_move_to_node(p, 0, 0); + else if (task_test_dflags(p, DREMOTE)) + task_remote_wait_expel(p); + + if (task_test_dflags(p, DMIGRATED)) + printk(KERN_ERR "oM: task %d fail to go back home\n", p->pid); + return 0; +} + +/** + * task_go_home_for_reason - Migrate back a task for a reason + **/ +int task_go_home_for_reason(task_t *p, int reason) +{ + int ret; + + task_lock(p); + if (task_test_stay(p, reason) && task_test_dflags(p, DMIGRATED)) + printk(KERN_ERR "oM: task should had migrated back earlier\n"); + task_set_stay(p, reason); + task_unlock(p); + + ret = task_go_home(p); + if (!ret) + task_clear_stay(p, reason); + return ret; +} + +/*****************************************************************************/ + +rwlock_t om_migsend_lock = RW_LOCK_UNLOCKED; +DECLARE_WAIT_QUEUE_HEAD(wait_migsend); + +#define MIGQUEUE_SIZE 20 + +struct migsend_queue +{ + struct sockaddr where; + struct task_struct *task; +}; + +static struct migsend_queue om_migsend_queue[MIGQUEUE_SIZE]; + +/** + * migsend_wake_up - wake up migsend daemon + **/ +void migsend_wake_up(void) +{ + wake_up(&wait_migsend); +} + +/** + * migsend_wait - put daemon to sleep + **/ +static inline void migsend_wait(void) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(&wait_migsend, &wait); + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + + remove_wait_queue(&wait_migsend, &wait); + set_current_state(TASK_RUNNING); +} + +/** + * migsend_task_register - Try to add the task the sending queue + * @p: task we want to send + * @whereto: where to send the task + **/ +int migsend_task_register(task_t *p, struct sockaddr * whereto) +{ + int i; + + write_lock(&om_migsend_lock); + for (i = 0; i < MIGQUEUE_SIZE; i++) + if (!om_migsend_queue[i].task) + { + om_migsend_queue[i].task = p; + memcpy(&om_migsend_queue[i].where, whereto, + sizeof(struct sockaddr)); + break; + } + write_unlock(&om_migsend_lock); + return 0; +} + +/** + * migsend_task_unregister - Remove the task from the sending queue + * @p: task we want to remove + **/ +int migsend_task_unregister(task_t *p) +{ + int i; + + write_lock(&om_migsend_lock); + for (i = 0; i < MIGQUEUE_SIZE; i++) + if (om_migsend_queue[i].task == p) + { + om_migsend_queue[i].task = 0; + memset(&om_migsend_queue[i].where, 0, sizeof(struct sockaddr)); + break; + } + write_unlock(&om_migsend_lock); + return 0; +} + +/** + * openmosix_spawn_daemon - openMosix send migration daemon + * @nothing: unused + **/ +int openmosix_migsend_daemon(void *nothing) +{ + int i; + + om_daemonize("omkspawnd", 0); + + /* init migsend_queue */ + write_lock(&om_migsend_lock); + for (i = 0; i < MIGQUEUE_SIZE; i++) + om_migsend_queue[i].task = 0; + write_unlock(&om_migsend_lock); + + /* daemon loop */ + while (1) { + task_t *p; + + /* check if there's task to send */ + write_lock(&om_migsend_lock); + for (i = 0; i < MIGQUEUE_SIZE; i++) + { + p = om_migsend_queue[i].task; + if (!p) + continue; + + OM_MIGRATION_DEBUG(KERN_DEBUG "oM: sending task %s\n", + p->comm); + task_move_to_node(p, &om_migsend_queue[i].where, 0); + om_migsend_queue[i].task = 0; + } + write_unlock(&om_migsend_lock); + + migsend_wait(); + } + return 0; +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/mig_recv.c linux-2.6.7/hpc/mig_recv.c --- linux-2.6.7.org/hpc/mig_recv.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/mig_recv.c 2004-09-02 14:46:54.268238448 +0200 @@ -0,0 +1,431 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define debug_show_migrations(p) printk(KERN_NOTICE "oM: migrated task received.\n"); + +/* handshake with the remote part */ +int mig_recv_hshake(om_link_t *mlink) +{ + int error; + struct mig_handshake_h hshake; + + /* receive request of whatever */ + error = comm_recv(mlink, &hshake, sizeof(hshake)); + if (error < 0) { + printk("mig_recv_request(): recv failed %d\n", error); + return -1; + } + + /* FIXME: sanity checks here */ + + /* reply of mig_requests */ + hshake.type = hshake.type | HSHAKE_REPLY; + hshake.version = OPENMOSIX_VERSION; + + error = comm_send(mlink, &hshake, sizeof(hshake)); + if (error < 0) { + printk("mig_recv_request(): send failed %d\n", error); + return -1; + } + + return 0; +} + +/*****************************************************************************/ + +/** + * mig_do_receive_mm_stats - Receive some parameters for a mm + **/ +static void mig_do_receive_mm_stats(task_t *p, struct mm_stats_h *s) +{ + /* copy all mm's parameter from start_code to env_end */ + memcpy((caddr_t) &p->mm->start_code, (caddr_t) s, sizeof(*s)); +} + +/** + * mig_do_receive_mm_area - Set up an mmap + **/ +static int mig_do_receive_mm_area(task_t *p, struct mmap_parameters_h *a) +{ + unsigned long result, prot, flags; + struct mm_struct *old_mm = NULL; + extern asmlinkage long sys_madvise(unsigned long, size_t, int); + + if (task_test_dflags(p, DREMOTE)) + return remote_mmap(a, 1); + + /* unconvert prot+flags: */ + flags = MAP_FIXED | MAP_PRIVATE; + prot = 0; + if (a->flags & VM_GROWSDOWN) + flags |= MAP_GROWSDOWN; + if (a->flags & VM_DENYWRITE) + flags |= MAP_DENYWRITE; + if (a->flags & VM_EXECUTABLE) + flags |= MAP_EXECUTABLE; + + /* copy VM_(READ|WRITE|EXEC) bits to prot */ + prot |= (a->flags & (VM_READ | VM_WRITE | VM_EXEC)); + + /* mmap stuff */ + task_deeper_sleep(p); + if (p != current) { + old_mm = current->mm; + current->mm = p->mm; + } + result = do_mmap_pgoff(a->fp, a->addr, a->len, prot, flags, a->pgoff); + if (old_mm) + current->mm = old_mm; + task_lighter_sleep(p); + + if (a->flags & VM_READHINTMASK) + sys_madvise(a->addr, a->len, (a->flags & VM_SEQ_READ) + ? MADV_RANDOM + : MADV_SEQUENTIAL); + return IS_ERR((const void *) result); +} + + +/** + * mig_do_receive_page - Receive one page + **/ +static int mig_do_receive_page(task_t *p, unsigned long addr) +{ + struct mm_struct *mm = p->mm; + struct vm_area_struct *vma; + struct page *recv_page = NULL; + void *kmpage; /* kmapped page */ + int error; + pgd_t * pgd; + pmd_t * pmd; + pte_t * pte; + + vma = find_vma(mm, addr); + if (!vma) { + printk(KERN_ERR "didn't find VMA (mm = %p, addr = %p)\n", + mm, (caddr_t) addr); + return -1; + } + + /* check if enough memory */ + + /* alloc page */ + recv_page = alloc_page(GFP_HIGHUSER); + if (!recv_page) { + printk(KERN_ERR "oM: recv page: unable to allocate page\n"); + return -ENOMEM; + } + + kmpage = kmap(recv_page); + + /* receive the data into the page */ + error = comm_recv(p->om.contact, kmpage, PAGE_SIZE); + + kunmap(kmpage); + if (error < 0) { + printk(KERN_ERR "oM: recv page: failed to receive data\n"); + goto out_alloc; + } + + /* add the page at correct place */ + pgd = pgd_offset(mm, addr); + spin_lock(&mm->page_table_lock); + if (!(pmd = pmd_alloc(mm, pgd, addr))) + goto out_spinlock; + if (!(pte = pte_alloc_kernel(mm, pmd, addr))) + goto out_spinlock; + if (!pte_none(*pte)) + printk(KERN_ERR "oM: recv page: double page at addr %p\n", + (void *) addr); + + set_pte(pte, pte_mkdirty(mk_pte(recv_page, vma->vm_page_prot))); + page_dup_rmap(recv_page); + mm->rss++; + spin_unlock(&mm->page_table_lock); + + return 0; + +out_spinlock: + spin_unlock(&mm->page_table_lock); +out_alloc: + printk(KERN_ERR "oM: receive page failed at addr %p\n", (void *) addr); + __free_page(recv_page); + return -1; +} + +/** + * mig_do_receive_fp - Receive floating points registers + * @p: task + * @fpr: floating point registers + * @e: extra parameter pass to architecture specific function + **/ +static void mig_do_receive_fp(task_t *p, struct mig_fp_h *fp) +{ + p->used_math = 1; + arch_mig_receive_fp(p, fp); +} + +/** + * mig_do_receive_misc - Receive normal registers, limits + **/ +static void mig_do_receive_proc_context(task_t *p, struct mig_task_h *m) +{ + /* arch specific proc receive context */ + arch_mig_receive_proc_context(p, m); + + /* copy om_task_t stuff */ + p->om.dflags |= m->dflags; + + /* copy id */ + p->om.pid = m->pid; + p->om.tgid = m->tgid; + + /* copy credentials */ + p->uid = m->uid; + p->euid = m->euid; + p->suid = m->suid; + p->fsuid = m->fsuid; + + p->gid = m->gid; + p->egid = m->egid; + p->sgid = m->sgid; + p->fsgid = m->fsgid; + + /* signals stuffs */ + p->blocked = m->blocked; + p->real_blocked = m->real_blocked; + + /* copy task_t stuff */ + p->it_prof_incr = m->it_prof_incr; + p->it_virt_incr = m->it_virt_incr; + + /* copy limits */ + p->rlim[RLIMIT_CPU] = m->rlim_cpu; + p->rlim[RLIMIT_DATA] = m->rlim_data; + p->rlim[RLIMIT_STACK] = m->rlim_stack; + p->rlim[RLIMIT_RSS] = m->rlim_rss; + p->rlim[RLIMIT_AS] = m->rlim_as; +} + +/** + * mig_do_receive - Receive all process stuff (mm, pages, fpr, ..) + **/ +int mig_do_receive(task_t *p) +{ + task_t *old_task; + struct mm_struct *oldmm, *mm; + int error; + unsigned int got_not_coming = 0; + unsigned long data; + struct mig_req_h req; + + old_task = current; + oldmm = old_task->active_mm; + mm = p->mm; + + data = __get_free_page(GFP_KERNEL); + if (!data) + goto fail; + + task_set_dflags(p, DINCOMING); + p->used_math = 0; + + /* no comment */ + switch_mm(oldmm, mm, p); + old_task->mm = mm; + + while (1) { + error = comm_recv(p->om.contact, &req, sizeof(req)); + if (error < 0) + goto fail; + + error = comm_recv(p->om.contact, (void *) data, req.dlen); + if (error < 0) + goto fail; + + switch (req.type) { + case MIG_MM_STATS: + printk("mig_do_recv(): got MIG_MM_STATS\n"); + mig_do_receive_mm_stats(p, (struct mm_stats_h *) data); + break; + case MIG_MM_AREA: + printk("mig_do_recv(): got MIG_MM_AREA\n"); + if (mig_do_receive_mm_area(p, (struct mmap_parameters_h *) data)) + goto fail; + break; + case MIG_PAGE: + //printk("mig_do_recv(): got MIG_PAGE\n"); + if (mig_do_receive_page(p, *((unsigned long *) data))) + goto fail; + break; + case MIG_FP: + printk("mig_do_recv(): got MIG_FP\n"); + mig_do_receive_fp(p, (struct mig_fp_h *) data); + break; + case MIG_ARCH: + if (arch_mig_receive_specific(p, (struct mig_arch_h *) data)) + goto fail; + break; + /* this is the last thing we do in the chain of receiving, + * so return 0 after we're done */ + case MIG_TASK: + printk("mig_do_recv(): got MIG_TASK\n"); + mig_do_receive_proc_context(p, (struct mig_task_h *) data); + comm_send_req(p->om.contact, MIG_TASK | REPLY); + task_clear_dflags(p, DINCOMING); + + old_task->mm = oldmm; + switch_mm(mm, oldmm, old_task); + + flush_tlb_mm(p->mm); /* for all the new pages */ + return 0; + case MIG_NOT_COMING: + printk("mig_do_recv(): got MIG_NOT_COMING\n"); + got_not_coming = 1; + goto fail; + default: + printk("mig_do_recv(): got default\n"); + /* + if (m->dflags & DDEPUTY) + deputy_communication_failed(); + */ + goto fail; + } + } +fail: + old_task->mm = oldmm; + switch_mm(mm, oldmm, old_task); + + comm_flushdata(p->om.contact); + task_clear_dflags(p, DINCOMING); + free_page(data); + + printk("mig_do_receive failed\n"); + return -1; +} + +static int mig_handle_migration(void *ptr) +{ + task_t *p = current; + /* link against the other end */ + om_link_t *link = (om_link_t *) ptr; + int error; + /* tab: make sure we don't do buffer overflow: DO NOT REMOVE IT */ + struct pt_regs not_used; + + task_set_comm(p, link); + + error = obtain_mm(p); + if (error) + goto fail; + if (mig_recv_hshake(link)) + goto fail; + + error = mig_do_receive(p); + + if (error) + goto fail; + + arch_kickstart(p); + /*NOTREACHED*/ + +fail: + printk(KERN_ERR "oM: fail to handle_migration\n"); + do_exit(SIGKILL); + /*NOTREACHED*/ +} + +/** + * openmosix_mig_daemon - openMosix migration daemon + * @nothing: unused + * + * Description: + * start the migration daemon. + * wait for communication, and if it is a remote request + * then start a user-thread with the new program to run + **/ +int openmosix_mig_daemon(void *nothing) +{ + task_t *p = current; + int error; + om_link_t *mlink; + struct sockaddr saddr; + + om_daemonize("omkmigd", 0); + + task_set_dflags(p, DREMOTEDAEMON); + + set_our_addr(AF_INET, &saddr, REMOTE_DAEMON_PORT); + +restart: + if (!p->om.contact) { + p->om.contact = comm_setup_listen(&saddr); + if (!p->om.contact) { + printk(KERN_WARNING + "omkmigd: failed to open mig service\n"); + flush_signals(p); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + goto restart; + } + } + + /* migration daemon loop */ + while (1) + { + error = comm_accept(p->om.contact, &mlink, &saddr, 0UL); + if (error == -EINTR || error == -ERESTART || error == -EAGAIN + || error == -ERESTARTSYS) + { + flush_signals(p); + continue; + } else if (error) { + printk(KERN_ERR "omkmigd: failed to accept\n"); + comm_close(mlink); + goto restart; + } + + printk("starting a migration_receive_process()\n"); + error = user_thread(mig_handle_migration, (void *) mlink, 0); + if (error < 0) + comm_close(mlink); + } +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/mig_send.c linux-2.6.7/hpc/mig_send.c --- linux-2.6.7.org/hpc/mig_send.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/mig_send.c 2004-09-02 14:46:54.269238296 +0200 @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* handle sending of migration request, and check answer */ +int mig_send_hshake(task_t *p, om_link_t *mlink, int type) +{ + struct mig_handshake_h hshake, hshake_recv; + int error; + + hshake.type = type; + hshake.version = OPENMOSIX_VERSION; + hshake.personality = p->personality; + + error = comm_send(mlink, &hshake, sizeof(hshake)); + if (error < 0) { + printk(KERN_ERR "oM: mig_handle_request(): send failed\n"); + return -1; + } + + error = comm_recv(mlink, &hshake_recv, sizeof(hshake_recv)); + if (error < 0) { + printk(KERN_ERR "oM: mig_handle_request(): recv failed\n"); + return -1; + } + + if (hshake_recv.type != (hshake.type | HSHAKE_REPLY)) { + /* it's a no go ... */ + printk(KERN_ERR "oM: mig_handle_request(): no go\n"); + return -1; + } + + return 0; +} + +static int mig_send_fp(task_t *p) +{ + struct mig_fp_h m; + + arch_mig_send_fp(p, &m); + return comm_send_hd(p->om.contact, MIG_FP, &m, sizeof(m)); +} + + +static int mig_send_mm_stats(task_t *p) +{ + struct mm_stats_h s; + + memcpy((caddr_t)&s, (caddr_t)&p->mm->start_code, sizeof(s)); + + return comm_send_hd(p->om.contact, MIG_MM_STATS, &s, sizeof(s)); +} + +static int mig_send_mm_areas(task_t *p) +{ + struct vm_area_struct *vma; + struct mmap_parameters_h m; + int ret = 0; + + for (vma = p->mm->mmap; vma; vma = vma->vm_next) + { + m.addr = vma->vm_start; + m.len = vma->vm_end - vma->vm_start; + m.flags = vma->vm_flags; + m.fp = NULL; + m.pgoff = 0; + if (vma->vm_file) + { + struct inode *ip = vma->vm_file->f_dentry->d_inode; + + m.pgoff = vma->vm_pgoff; + m.fp = vma->vm_file; + m.dp = m.fp->f_dentry; + m.isize = ip->i_size; + } + ret = comm_send_hd(p->om.contact, MIG_MM_AREA, &m, sizeof(m)); + if (ret < 0) { + printk(KERN_ERR "send mm area failed\n"); + break; + } + + } + return ret; +} + + +static int mig_send_pages(task_t *p) +{ + struct vm_area_struct * vma; + unsigned long addr; + int error; + + for (vma = p->mm->mmap; vma; vma = vma->vm_next) + { + for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) + { + //printk("mig_send_pages() sending %p\n", (void *) addr); + error = comm_send_hd(p->om.contact, MIG_PAGE, &addr, + sizeof(addr)); + if (error < 0) + goto fail; + + error = comm_send(p->om.contact, (void *) addr, + PAGE_SIZE); + if (error < 0) + goto fail; + } + } + return 0; +fail: + printk(KERN_ERR "oM: sending context failed\n"); + return -1; +} + + +static int mig_send_proc_context(task_t *p) +{ + struct mig_task_h m; + struct mig_req_h req; + int error; + + m.ptrace = p->ptrace; + m.dflags = p->om.dflags & (DTRACESYS1|DTRACESYS2); + + m.pid = p->pid; + m.tgid = p->tgid; + + /* credentials */ + m.uid = p->uid; + m.euid = p->euid; + m.suid = p->suid; + m.fsuid = p->fsuid; + + m.gid = p->gid; + m.egid = p->egid; + m.sgid = p->sgid; + m.fsgid = p->fsgid; + + /* signals */ + m.blocked = p->blocked; + m.real_blocked = p->real_blocked; + + m.nice = task_nice(p); + m.caps = p->cap_effective; + p->om.remote_caps = m.caps; + m.it_prof_incr = p->it_prof_incr; + m.it_virt_incr = p->it_virt_incr; + + /* send task limits */ + m.rlim_cpu = p->rlim[RLIMIT_CPU]; + m.rlim_data = p->rlim[RLIMIT_DATA]; + m.rlim_stack = p->rlim[RLIMIT_STACK]; + m.rlim_rss = p->rlim[RLIMIT_RSS]; + m.rlim_as = p->rlim[RLIMIT_AS]; + + arch_mig_send_proc_context(p, &m); + + error = comm_send_hd(p->om.contact, MIG_TASK, &m, sizeof(m)); + if (error < 0) + goto fail; + + error = comm_recv(p->om.contact, &req, sizeof(req)); + + if (req.type == (MIG_TASK | REPLY)) + return 0; /* commit point */ + +fail: + printk(KERN_ERR "oM: sending context failed\n"); + return -1; +} + +int mig_do_send(task_t *p) +{ + task_t *old_task = current; + struct mm_struct *mm = p->mm; + struct mm_struct *oldmm = old_task->active_mm; + + arch_mig_send_pre(p); + + /* no comment */ + switch_mm(oldmm, mm, p); + old_task->mm = mm; + + if (mig_send_mm_stats(p)) + goto fail_mig; + if (mig_send_mm_areas(p)) + goto fail_mig; + if (mig_send_pages(p)) + goto fail_mig; + if (p->used_math && mig_send_fp(p)) + goto fail_mig; + if (arch_mig_send_specific(p)) + goto fail_mig; + if (mig_send_proc_context(p)) + goto fail_mig; + + arch_mig_send_post(p); + + old_task->mm = oldmm; + switch_mm(mm, oldmm, old_task); + return 0; + +fail_mig: + comm_send_req(p->om.contact, MIG_NOT_COMING); + switch_mm(mm, oldmm, old_task); + return -1; +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/proc.c linux-2.6.7/hpc/proc.c --- linux-2.6.7.org/hpc/proc.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/proc.c 2004-09-02 14:46:54.273237688 +0200 @@ -0,0 +1,524 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * PID set/get accessor + */ +static int proc_pid_set_where(struct task_struct *p, char *buf, size_t size) +{ + int ret; + struct sockaddr destination; + + if (size >= 4 && strnicmp(buf, "home", 4) == 0) { + printk("HOME detected\n"); + ret = task_go_home(p); + } else { + ret = string_to_sockaddr(buf, &destination); + if (ret >= 0) { + migsend_task_register(p, &destination); + migsend_wake_up(); + } + } + + return size; +} + +static int proc_pid_get_where(struct task_struct *p, char *buf, size_t size) +{ + int length; + struct sockaddr address; + + if (p->om.contact) { + comm_getname(p->om.contact, &address); + length = sockaddr_to_string(&address, buf); + length += sprintf(buf + length, "\n"); + } else + length = sprintf(buf, "home\n"); + + return length; +} + +#ifdef CONFIG_OPENMOSIX_DEBUG +static int proc_debug_get_verbose_migration(char *buf, size_t size) +{ + int length; + + length = sprintf(buf, "%d\n", om_opts.debug_verbose_migration); + return length; +} + +static int proc_debug_set_verbose_migration(char *buf, size_t size) +{ + long value; + char *endp; + + endp = buf + size; + value = simple_strtoul(buf, &endp, 10); + if (value >= 0 && value <= 10) { + om_opts.debug_verbose_migration = value; + } + return size; +} +#endif /* CONFIG_OPENMOSIX_DEBUG */ + +static char *stayreason_string[32] = { + "monkey", "mmap_dev", "VM86_mode", "daemon", + "priv_inst", "mem_lock", "clone_vm", "rt_sched", + "direct_io", "init_proc", "kiobuf", 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + "extern_1", "extern_2", "extern_3", "extern_4", + 0, 0, 0, "user_lock" +}; + +static int proc_pid_get_stay(struct task_struct *p, char *buf, size_t size) +{ + int length, i; + + length = 0; + for (i = 0; i < 31; i++) + if (task_test_stay(p, 1 << i)) + length += snprintf(buf + length, size - length, + "%s\n", stayreason_string[i]); + if (!length) + buf[0] = 0; + return length; +} + +static int proc_pid_get_debug(struct task_struct *p, char *buf, size_t size) +{ + int length; + + length = sprintf(buf, "debug: dflags: 0x%.8x\n", p->om.dflags); + return length; +} + +static int proc_admin_set_bring(char *buf, size_t size) +{ + printk(KERN_DEBUG "oM: proc: set bring"); + return size; +} + +static int proc_admin_set_expel(char *buf, size_t size) +{ + printk(KERN_DEBUG "oM: proc: set expel"); + return size; +} + +static int proc_admin_get_version(char *buf, size_t size) +{ + int length; + + length = sprintf(buf, "openMosix version: %d.%d.%d\n", + OPENMOSIX_VERSION_TUPPLE); + return length; +} + +/* create /proc/hpc/admin/ entry */ +#define E(name,mode,s,g) {0,sizeof(name)-1,(name),(mode), \ + proc_admin_set_##s, \ + proc_admin_get_##g } + +static om_proc_entry_t proc_om_entry_admin[] = +{ + E("bring", S_IFREG|S_IRUGO|S_IWUGO, bring, 0), + E("expel", S_IFREG|S_IRUGO|S_IWUGO, expel, 0), + E("version", S_IFREG|S_IRUGO|S_IWUGO, 0, version), + {0,0,NULL,0, 0, 0} +}; + +#undef E + +/* create /proc/${pid}/ entry */ +#define E(name,s,g) {0,sizeof(name)-1,(name),0, \ + proc_pid_set_##s, \ + proc_pid_get_##g} + +static om_proc_pid_entry_t proc_om_entry_pid[] = +{ + E("where", where, where), + E("stay", 0, stay), + E("debug", 0, debug), + { 0, 0, NULL, 0, 0, 0 } +}; + +#undef E + +#ifdef CONFIG_OPENMOSIX_PROC_DEBUG +/* create /proc/hpc/debug entry */ + +#define E(name,mode,s,g) {0,sizeof(name)-1,(name),(mode), \ + proc_debug_set_##s, \ + proc_debug_get_##g} + +static om_proc_entry_t proc_om_entry_debug[] = +{ + E("verbose_migration", S_IFREG|S_IRUGO|S_IWUGO, verbose_migration, verbose_migration), + { 0, 0, NULL, 0, 0, 0 } +}; + +#undef E +#endif /* CONFIG_OPENMOSIX_PROC_DEBUG */ + +/** + * openmosix_proc_pid_getattr - Get attributes from task + * @p: the task we want attributes + * @name: name of the attributes + * @buf: the page to write the value to + * @size: unused + **/ +int openmosix_proc_pid_getattr(struct task_struct *p, + char *name, void *buf, size_t size) +{ + int length, i; + + if (!size) + return -ERANGE; + + length = -EINVAL; + for (i = 0; proc_om_entry_pid[i].name; i++) + { + om_proc_pid_entry_t * tmpentry = &proc_om_entry_pid[i]; + if (!strncmp(name, tmpentry->name, tmpentry->len)) + { + length = (tmpentry->get)(p, buf, size); + break; + } + } + return length; +} + +/** + * openmosix_proc_pid_setattr - Set attributes to task + * @p: the task we want attributes + * @name: name of the attributes + * @buf: the page to get the value from + * @size: size bytes to read + **/ +int openmosix_proc_pid_setattr(struct task_struct *p, + char *name, void *buf, size_t size) +{ + int error, i; + + error = -EINVAL; + for (i = 0; proc_om_entry_pid[i].name; i++) + { + om_proc_pid_entry_t * tmpentry = &proc_om_entry_pid[i]; + if (!strncmp(name, tmpentry->name, tmpentry->len)) + { + error = (tmpentry->set)(p, buf, size); + break; + } + } + return error; +} + +/** + * proc_callback_read - read an attribute and return to userspace + * + * Handle page creation and correct verification then call the callback + **/ +static ssize_t proc_callback_read(struct file * file, char * buf, + size_t count, loff_t *ppos, + om_proc_entry_t *entry) +{ + unsigned long page; + ssize_t length; + ssize_t end; + char *name; + int i; + + if (count > PAGE_SIZE) + count = PAGE_SIZE; + if (!(page = __get_free_page(GFP_KERNEL))) + return -ENOMEM; + + name = (char *) file->f_dentry->d_name.name; + + length = -EINVAL; + /* browse entry to find callback for file name */ + for (i = 0; entry[i].name; i++) + { + om_proc_entry_t * tmpentry = &entry[i]; + if (!strncmp(name, tmpentry->name, tmpentry->len)) + { + length = (tmpentry->get)((char *) page, count); + break; + } + } + + if (length < 0) { + free_page(page); + return length; + } + /* Static 4kB (or whatever) block capacity */ + if (*ppos >= length) { + free_page(page); + return 0; + } + if (count + *ppos > length) + count = length - *ppos; + end = count + *ppos; + if (copy_to_user(buf, (char *) page + *ppos, count)) + count = -EFAULT; + else + *ppos = end; + free_page(page); + return count; +} + +/** + * proc_callback_write - set an attribute from userspace buf + * + * Handle page creation and correct verification then call the callback + **/ +static ssize_t proc_callback_write(struct file * file, const char * buf, + size_t count, loff_t *ppos, + om_proc_entry_t *entry) +{ + char *page, *name; + ssize_t length; + int i; + + if (count > PAGE_SIZE) + count = PAGE_SIZE; + if (*ppos != 0) { + /* No partial writes. */ + return -EINVAL; + } + page = (char*)__get_free_page(GFP_USER); + if (!page) + return -ENOMEM; + length = -EFAULT; + if (copy_from_user(page, buf, count)) + goto out; + + name = (char *) file->f_dentry->d_name.name; + + /* browse entry to find callback for file name */ + for (i = 0; entry[i].name; i++) + { + om_proc_entry_t * tmpentry = &entry[i]; + if (!strncmp(name, tmpentry->name, tmpentry->len)) + { + length = (tmpentry->set)(page, count); + break; + } + } + +out: + free_page((unsigned long) page); + return length; +} + +/* + * openMosix proc dir file_ops handler + */ +#define PROC_OM_SUBSYS_READ(subsys) \ + static ssize_t proc_om_read_##subsys(struct file * file, \ + char *buf, \ + size_t count, \ + loff_t *ppos) \ + { \ + return proc_callback_read(file, buf, count, \ + ppos, proc_om_entry_##subsys); \ + } + +#define PROC_OM_SUBSYS_WRITE(subsys) \ + static ssize_t proc_om_write_##subsys(struct file * file, \ + const char *buf, \ + size_t count, \ + loff_t *ppos) \ + { \ + return proc_callback_write(file, buf, count, \ + ppos, proc_om_entry_##subsys); \ + } + +PROC_OM_SUBSYS_READ(admin) +PROC_OM_SUBSYS_WRITE(admin) + +#ifdef CONFIG_OPENMOSIX_PROC_DEBUG +PROC_OM_SUBSYS_READ(debug) +PROC_OM_SUBSYS_WRITE(debug) +#endif + +#undef PROC_OM_SUBSYS_READ +#undef PROC_OM_SUBSYS_WRITE + +static struct file_operations proc_om_admin_operations = { + .read = proc_om_read_admin, + .write = proc_om_write_admin, +}; + +#ifdef CONFIG_OPENMOSIX_PROC_DEBUG +static struct file_operations proc_om_debug_operations = { + .read = proc_om_read_debug, + .write = proc_om_write_debug, +}; +#endif + + +/** + * proc_nodes_readdir - readdir function for nodes + **/ +static int proc_nodes_readdir(struct file *filp, void *dirent, + filldir_t filldir) +{ + int i, len; + struct dentry *dentry = filp->f_dentry; + struct inode *inode = dentry->d_inode; + ino_t ino; + int ret; + char nodestr[12]; /* 12 == max(u32) */ + + ret = 0; + i = filp->f_pos; + switch (i) { + case 0: + ino = inode->i_ino; + if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) + goto out; + i++; + filp->f_pos++; + /* fall through */ + case 1: + ino = parent_ino(dentry); + if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) + goto out; + i++; + filp->f_pos++; + /* fall through */ + default: + i -= 2; + /* + get_nodes(); + while (nodes) { + */ + if (filp->f_pos == 2) + { + len = snprintf(nodestr, 12, "%u", 1); + nodestr[len] = 0; + if (filldir(dirent, nodestr, len, filp->f_pos, + ((i + 1)<<16|i), DT_DIR) < 0) + goto out; + filp->f_pos++; + } + /* + } + */ + } + ret = 1; +out: + return ret; +} + +static struct file_operations proc_om_nodes_operations = { + .read = generic_read_dir, + .readdir = proc_nodes_readdir, +}; + + +/** + * openmosix_proc_create_entry - create @entry in @dir with their callbacks + * @dir: directory to create the entries into + * @entry: entries to add into directory + * @r: read callback + * @w: write callback + */ +static void openmosix_proc_create_entry(struct proc_dir_entry *dir, + om_proc_entry_t *entry, + struct file_operations *fileops) +{ + struct proc_dir_entry *de; + int i; + + for (i = 0; entry[i].name; i++) + { + om_proc_entry_t * tmp = &entry[i]; + de = create_proc_entry(tmp->name, tmp->mode, dir); + if (!de) { + printk(KERN_ERR "oM: proc: unable to create entry\n"); + continue; + } + de->proc_fops = fileops; + } +} + +/* + * init hpc proc debug directory + */ +#ifdef CONFIG_OPENMOSIX_PROC_DEBUG +void openmosix_proc_debug_init(void) +{ + struct proc_dir_entry *dir_debug; + + dir_debug = proc_mkdir("hpc/debug", 0); + if (dir_debug) + openmosix_proc_create_entry(dir_debug, proc_om_entry_debug, + &proc_om_debug_operations); +} +#else +void openmosix_proc_debug_init(void) { } +#endif /* CONFIG_OPENMOSIX_PROC_DEBUG */ + + + +/* + * init hpc proc directory + */ +void openmosix_proc_init(void) +{ + struct proc_dir_entry *dir_root, *dir_admin, *dir_nodes; + + dir_root = proc_mkdir("hpc", 0); + if (!dir_root) { + printk(KERN_ERR "oM: proc: unable to create root directory\n"); + return; + } + + dir_admin = proc_mkdir("hpc/admin", 0); + dir_nodes = proc_mkdir("hpc/nodes", 0); + + if (!dir_admin || !dir_nodes) { + printk(KERN_ERR "oM: proc: unable to create sub directory\n"); + return; + } + + openmosix_proc_create_entry(dir_admin, proc_om_entry_admin, + &proc_om_admin_operations); + + openmosix_proc_debug_init(); + + dir_nodes->proc_fops = &proc_om_nodes_operations; +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/remote.c linux-2.6.7/hpc/remote.c --- linux-2.6.7.org/hpc/remote.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/remote.c 2004-09-02 14:46:54.323230088 +0200 @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +NORET_TYPE void remote_disappear(void) +{ + do_exit(SIGKILL); + /*NOTREACHED*/ +} + +/* + * the following routine, if called within process-migration, + * returns the fact of an error, rather than sends back a reply: + */ +int remote_mmap(struct mmap_parameters_h *m, int inmig) +{ + unsigned long result; + struct file *rf; + unsigned long prot, flags; + + printk("entering remote_mmap...\n"); + rf = NULL; + + /* unconvert prot+flags: */ + prot = 0; + flags = MAP_PRIVATE | MAP_FIXED; + if (m->flags & VM_GROWSDOWN) + flags |= MAP_GROWSDOWN; + if (m->flags & VM_DENYWRITE) + flags |= MAP_DENYWRITE; + if (m->flags & VM_EXECUTABLE) + flags |= MAP_EXECUTABLE; + + prot |= (m->flags & (VM_READ | VM_WRITE | VM_EXEC)); + + /* FIXME: NULL till we get those files up and running */ + result = do_mmap_pgoff(NULL, m->addr, m->len, prot, flags, m->pgoff); + + printk("remote_mmap: addr: 0x%p, len %ld, is_err %ld\n", + (caddr_t) m->addr, m->len, IS_ERR((const void *)result)); + + if (m->flags & VM_READHINTMASK) + sys_madvise(m->addr, m->len, (m->flags & VM_SEQ_READ) ? + MADV_RANDOM : MADV_SEQUENTIAL); + + if (inmig) + return IS_ERR((const void *)result); + /* + return comm_send(current, DEP_MMAP|REPLY, &result, sizeof(result), NULL, 0, 0); + */ + return 0; +} + +int remote_readpage(struct file *fp, struct page *page) +{ + /* FIXME I'm a dummy */ + printk(KERN_ERR "dummy remote_readpage(%p, %p) called\n", + (caddr_t) fp, (caddr_t) page); + return 0; +} + +/** + * remote_wait - wait @expect packet from deputy + **/ +int remote_wait(task_t *p, int expect, void *data, int len) +{ + int error; + struct mig_req_h req; + + error = comm_recv(p->om.contact, &req, sizeof(req)); + if (error < 0) + goto comm_error; + + if (req.type != expect) { + printk(KERN_ERR "oM: unexpected type [0x%x] received, " + "expecting type [0x%x]\n", req.type, expect); + return -1; + } + + if (req.dlen != len) { + printk(KERN_ERR "oM: unexpected size\n"); + return -1; + } + + error = comm_recv(p->om.contact, data, len); + if (error < 0) + goto comm_error; + return 0; +comm_error: + printk(KERN_ERR "oM: unexpected error in comm layer.\n"); + return -1; +} + +/** + * remote_do_comm - process a communication + **/ +int remote_do_comm(task_t *p) +{ + int error; + struct mig_req_h req; + + printk("remote_do_comm()\n"); + error = comm_recv(p->om.contact, &req, sizeof(req)); + if (error < 0) + goto fail; + + switch (req.type) { + case DEP_COMING_HOME: + printk("remote_do_comm(): got DEP_COMING_HOME\n"); + error = task_remote_expel(p); + break; + default: + printk("remote_do_comm(): got default\n"); + goto fail; + } + + return 0; +fail: + printk(KERN_ERR "remote_do_comm fail\n"); + return -1; +} + +/** + * remote_do_syscall - process a remote syscall + * @n: the syscall number + * @regs: userspace registers + **/ +long remote_do_syscall(int n, struct pt_regs *regs) +{ + struct mig_syscall_h s; + struct mig_syscall_ret_h r; + int error, i; + + s.n = n; + for (i = 0; i < 6; i++) + s.arg[i] = arch_get_sys_arg(i, regs); + + printk(KERN_ERR "oM: dummy remote syscall %d\n", n); + /* send the syscall with parameters */ + error = comm_send_hd(current->om.contact, REM_SYSCALL, &s, sizeof(s)); + if (error < 0) + remote_disappear(); + + printk(KERN_ERR "oM: waiting deputy answer.\n"); + + /* wait for syscall result */ + error = remote_wait(current, REM_SYSCALL | REPLY, &r, sizeof(r)); + if (error < 0) + remote_disappear(); + + printk(KERN_ERR "oM: deputy answered.\n"); + + return r.ret; +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/service.c linux-2.6.7/hpc/service.c --- linux-2.6.7.org/hpc/service.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/service.c 2004-09-02 14:46:54.324229936 +0200 @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * om_daemonize - create an oM daemon + * @name: kernel thread name + * @highpri: is this kernel thread high priority + * + * Description: + * Create a kernel thread, and set priority. + * SCHED_FIFO for high priority, hence stay for realtime + **/ +void om_daemonize(char *name, int highpri) +{ + task_t *p = current; + + daemonize(name); + p->it_real_incr = 0; + p->it_prof_incr = 0; + p->it_virt_incr = 0; + p->it_real_value = 0; + p->it_prof_value = 0; + p->it_virt_value = 0; + + p->euid = 0; + p->suid = 0; + p->gid = 0; + p->group_info = groups_alloc(0); + + /* clean blocked signal set */ + spin_lock_irq(&p->sighand->siglock); + sigemptyset(&p->blocked); + recalc_sigpending_tsk(p); + spin_unlock_irq(&p->sighand->siglock); + + memcpy(p->rlim, init_task.rlim, sizeof(p->rlim)); + + /* set priority and stay reason of the task */ + task_lock(p); + if (highpri) + { + p->policy = SCHED_FIFO; + task_set_stay(p, DSTAY_FOR_RT); + p->rt_priority = 0; + } + else + { + p->policy = SCHED_NORMAL; + task_clear_stay(p, DSTAY_FOR_RT); + set_user_nice(p, 0); + } + task_set_stay(p, DSTAY_ITS_DAEMON); + task_unlock(p); +} + +/** + * sockaddr_equal - check if a1 got same address than a2 + **/ +int sockaddr_equal(struct sockaddr *a1, struct sockaddr *a2) +{ + switch (a1->sa_family) { + case AF_INET: + return inet_equal((struct sockaddr_in *) a1, + (struct sockaddr_in *) a2); + case AF_INET6: + return inet6_equal((struct sockaddr_in6 *) a1, + (struct sockaddr_in6 *) a2); + } + printk(KERN_ERR "oM: network type not supported\n"); + return -1; +} + +/** + * netaddress_to_string - write an net address to a buffer returning length + **/ +int sockaddr_to_string(struct sockaddr *address, char *buf) +{ + switch (address->sa_family) { + case AF_INET: + return inet_to_string((struct sockaddr_in *) address, buf); + case AF_INET6: + return inet6_to_string((struct sockaddr_in6 *) address, buf); + } + printk(KERN_ERR "oM: network type not supported\n"); + return 0; +} + + +/** + * string_to_sockaddr - convert a buffer, to a sockaddr + **/ +int string_to_sockaddr(char *buf, struct sockaddr *address) +{ + int l; + + address->sa_family = 0; + /* try to parse an ipv4 */ + l = string_to_inet(buf, (struct sockaddr_in *) address); + if (l > 0) + return l; + /* try to parse an ipv6 */ + l = string_to_inet6(buf, (struct sockaddr_in6 *) address); + if (l > 0) + return l; + return 0; +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/syscalls.c linux-2.6.7/hpc/syscalls.c --- linux-2.6.7.org/hpc/syscalls.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/syscalls.c 2004-09-02 14:46:54.328229328 +0200 @@ -0,0 +1,493 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include + +/* invalid syscalls on remote are list there */ +INVALID_REMOTE_SYSCALL(long, msync) +INVALID_REMOTE_SYSCALL(long, munlock) +INVALID_REMOTE_SYSCALL(long, munlockall) +DO_REMOTE_SYSCALL(long, sys_mlock) +DO_REMOTE_SYSCALL(long, sys_mlockall) + +/* old syscalls (compatilibity) */ +DO_REMOTE_SYSCALL(long, sys_waitpid) +DO_REMOTE_SYSCALL(long, sys_sysctl) + +DO_REMOTE_SYSCALL(long, sys_nanosleep) + +/* rt signals */ +DO_REMOTE_SYSCALL(long, sys_rt_sigreturn) +DO_REMOTE_SYSCALL(long, sys_rt_sigaction) +DO_REMOTE_SYSCALL(long, sys_rt_sigprocmask) +DO_REMOTE_SYSCALL(long, sys_rt_sigpending) +DO_REMOTE_SYSCALL(long, sys_rt_sigtimedwait) +DO_REMOTE_SYSCALL(long, sys_rt_sigqueueinfo) +DO_REMOTE_SYSCALL(long, sys_rt_sigsuspend) + +/* mq ipc */ +DO_REMOTE_SYSCALL(long, sys_mq_open) +DO_REMOTE_SYSCALL(long, sys_mq_unlink) +DO_REMOTE_SYSCALL(long, sys_mq_timedsend) +DO_REMOTE_SYSCALL(long, sys_mq_timedreceive) +DO_REMOTE_SYSCALL(long, sys_mq_notify) +DO_REMOTE_SYSCALL(long, sys_mq_getsetattr) + +/* io */ +DO_REMOTE_SYSCALL(long, sys_io_setup) +DO_REMOTE_SYSCALL(long, sys_io_destroy) +DO_REMOTE_SYSCALL(long, sys_io_getevents) +DO_REMOTE_SYSCALL(long, sys_io_submit) +DO_REMOTE_SYSCALL(long, sys_io_cancel) + +/* epoll */ +DO_REMOTE_SYSCALL(long, sys_epoll_create) +DO_REMOTE_SYSCALL(long, sys_epoll_ctl) +DO_REMOTE_SYSCALL(long, sys_epoll_wait) + +/* timer */ +DO_REMOTE_SYSCALL(long, sys_timer_create) +DO_REMOTE_SYSCALL(long, sys_timer_settime) +DO_REMOTE_SYSCALL(long, sys_timer_gettime) +DO_REMOTE_SYSCALL(long, sys_timer_getoverrun) +DO_REMOTE_SYSCALL(long, sys_timer_delete) + +/* clock */ +DO_REMOTE_SYSCALL(long, sys_clock_settime) +DO_REMOTE_SYSCALL(long, sys_clock_gettime) +DO_REMOTE_SYSCALL(long, sys_clock_getres) +DO_REMOTE_SYSCALL(long, sys_clock_nanosleep) + +DO_REMOTE_SYSCALL(long, sys_mincore) + +DO_REMOTE_SYSCALL(long, sys_sched_setparam) +DO_REMOTE_SYSCALL(long, sys_sched_getparam) +DO_REMOTE_SYSCALL(long, sys_sched_setscheduler) +DO_REMOTE_SYSCALL(long, sys_sched_getscheduler) +DO_REMOTE_SYSCALL(long, sys_sched_yield) +DO_REMOTE_SYSCALL(long, sys_sched_rr_get_interval) + + +DO_REMOTE_SYSCALL(int, sys_nfsservctl) + +/* file related syscalls */ +DO_REMOTE_SYSCALL(long, sys_fchdir) +DO_REMOTE_SYSCALL(long, sys_llseek) +DO_REMOTE_SYSCALL(long, sys_getdents) +DO_REMOTE_SYSCALL(ssize_t, sys_read) +DO_REMOTE_SYSCALL(ssize_t, sys_write) +DO_REMOTE_SYSCALL(long, sys_open) +DO_REMOTE_SYSCALL(long, sys_close) +DO_REMOTE_SYSCALL(long, sys_creat) +DO_REMOTE_SYSCALL(long, sys_link) +DO_REMOTE_SYSCALL(long, sys_unlink) +DO_REMOTE_SYSCALL(int, sys_execve) +DO_REMOTE_SYSCALL(long, sys_chdir) +DO_REMOTE_SYSCALL(long, sys_mknod) +DO_REMOTE_SYSCALL(long, sys_chmod) +DO_REMOTE_SYSCALL(long, sys_lchown16) +DO_REMOTE_SYSCALL(long, sys_stat) +DO_REMOTE_SYSCALL(off_t, sys_lseek) +DO_REMOTE_SYSCALL(long, sys_dup) +DO_REMOTE_SYSCALL(long, sys_dup2) +DO_REMOTE_SYSCALL(long, old_select) +DO_REMOTE_SYSCALL(long, sys_truncate) +DO_REMOTE_SYSCALL(long, sys_fchmod) +DO_REMOTE_SYSCALL(long, sys_fchown16) +DO_REMOTE_SYSCALL(long, sys_fsync) +DO_REMOTE_SYSCALL(ssize_t, sys_readv) +DO_REMOTE_SYSCALL(ssize_t, sys_writev) +DO_REMOTE_SYSCALL(long, sys_fdatasync) +DO_REMOTE_SYSCALL(long, sys_poll) +DO_REMOTE_SYSCALL(long, sys_lchown) +DO_REMOTE_SYSCALL(long, sys_fchown) +DO_REMOTE_SYSCALL(long, sys_getdents64) +DO_REMOTE_SYSCALL(long, sys_chown16) +DO_REMOTE_SYSCALL(long, sys_getcwd) +DO_REMOTE_SYSCALL(long, sys_truncate64) +DO_REMOTE_SYSCALL(long, sys_ftruncate64) +DO_REMOTE_SYSCALL(long, sys_stat64) +DO_REMOTE_SYSCALL(long, sys_lstat64) +DO_REMOTE_SYSCALL(long, sys_fstat64) +DO_REMOTE_SYSCALL(long, sys_setxattr) +DO_REMOTE_SYSCALL(long, sys_lsetxattr) +DO_REMOTE_SYSCALL(long, sys_fsetxattr) +DO_REMOTE_SYSCALL(long, sys_getxattr) +DO_REMOTE_SYSCALL(long, sys_lgetxattr) +DO_REMOTE_SYSCALL(long, sys_fgetxattr) +DO_REMOTE_SYSCALL(long, sys_listxattr) +DO_REMOTE_SYSCALL(long, sys_llistxattr) +DO_REMOTE_SYSCALL(long, sys_flistxattr) +DO_REMOTE_SYSCALL(long, sys_removexattr) +DO_REMOTE_SYSCALL(long, sys_lremovexattr) +DO_REMOTE_SYSCALL(long, sys_fremovexattr) +DO_REMOTE_SYSCALL(long, sys_statfs64) +DO_REMOTE_SYSCALL(long, sys_fstatfs64) +DO_REMOTE_SYSCALL(long, sys_pread64) +DO_REMOTE_SYSCALL(long, sys_pwrite64) +DO_REMOTE_SYSCALL(long, sys_mkdir) +DO_REMOTE_SYSCALL(long, sys_rmdir) +DO_REMOTE_SYSCALL(long, sys_pipe) +DO_REMOTE_SYSCALL(long, sys_fcntl64) +DO_REMOTE_SYSCALL(long, sys_statfs) +DO_REMOTE_SYSCALL(long, sys_fstatfs) +DO_REMOTE_SYSCALL(long, sys_chown) +DO_REMOTE_SYSCALL(long, sys_chroot) +DO_REMOTE_SYSCALL(long, sys_umount) +DO_REMOTE_SYSCALL(long, sys_mount) +DO_REMOTE_SYSCALL(long, sys_oldumount) +DO_REMOTE_SYSCALL(long, sys_fstat) +DO_REMOTE_SYSCALL(long, sys_ioctl) +DO_REMOTE_SYSCALL(long, sys_fcntl) +DO_REMOTE_SYSCALL(long, sys_newstat) +DO_REMOTE_SYSCALL(long, sys_newlstat) +DO_REMOTE_SYSCALL(long, sys_newfstat) +DO_REMOTE_SYSCALL(long, sys_select) +DO_REMOTE_SYSCALL(long, sys_flock) +DO_REMOTE_SYSCALL(long, sys_lstat) +DO_REMOTE_SYSCALL(long, old_readdir) +DO_REMOTE_SYSCALL(long, sys_bdflush) +DO_REMOTE_SYSCALL(long, sys_sendfile64) +DO_REMOTE_SYSCALL(long, sys_readahead) +DO_REMOTE_SYSCALL(long, sys_fadvise64) +DO_REMOTE_SYSCALL(long, sys_fadvise64_64) +DO_REMOTE_SYSCALL(long, sys_ftruncate) +DO_REMOTE_SYSCALL(long, sys_sync) +DO_REMOTE_SYSCALL(long, sys_rename) +DO_REMOTE_SYSCALL(long, sys_sendfile) +DO_REMOTE_SYSCALL(long, sys_symlink) +DO_REMOTE_SYSCALL(long, sys_readlink) +DO_REMOTE_SYSCALL(long, sys_uselib) +DO_REMOTE_SYSCALL(long, sys_vhangup) + +DO_REMOTE_SYSCALL(long, sys_sched_get_priority_max) +DO_REMOTE_SYSCALL(long, sys_sched_get_priority_min) +DO_REMOTE_SYSCALL(long, sys_prctl) +DO_REMOTE_SYSCALL(long, sys_capget) +DO_REMOTE_SYSCALL(long, sys_capset) +DO_REMOTE_SYSCALL(long, sys_sigaltstack) +DO_REMOTE_SYSCALL(long, sys_vfork) +DO_REMOTE_SYSCALL(long, sys_getrlimit) +DO_REMOTE_SYSCALL(long, sys_setgroups) +DO_REMOTE_SYSCALL(long, sys_getgroups) +DO_REMOTE_SYSCALL(long, sys_pivot_root) +DO_REMOTE_SYSCALL(long, sys_futex) +DO_REMOTE_SYSCALL(long, sys_sched_setaffinity) +DO_REMOTE_SYSCALL(long, sys_sched_getaffinity) +DO_REMOTE_SYSCALL(long, sys_set_thread_area) +DO_REMOTE_SYSCALL(long, sys_get_thread_area) +DO_REMOTE_SYSCALL(long, sys_exit_group) +DO_REMOTE_SYSCALL(long, sys_lookup_dcookie) +DO_REMOTE_SYSCALL(long, sys_remap_file_pages) +DO_REMOTE_SYSCALL(long, sys_set_tid_address) +DO_REMOTE_SYSCALL(long, sys_tgkill) +DO_REMOTE_SYSCALL(long, sys_utimes) +DO_REMOTE_SYSCALL(long, sys_restart_syscall) +DO_REMOTE_SYSCALL(long, sys_exit) +DO_REMOTE_SYSCALL(long, sys_fork) +DO_REMOTE_SYSCALL(long, sys_stime) +DO_REMOTE_SYSCALL(long, sys_ptrace) +DO_REMOTE_SYSCALL(long, sys_alarm) +DO_REMOTE_SYSCALL(long, sys_pause) +DO_REMOTE_SYSCALL(long, sys_utime) +DO_REMOTE_SYSCALL(long, sys_access) +DO_REMOTE_SYSCALL(long, sys_nice) +DO_REMOTE_SYSCALL(long, sys_times) +DO_REMOTE_SYSCALL(long, sys_signal) +DO_REMOTE_SYSCALL(long, sys_acct) +DO_REMOTE_SYSCALL(long, sys_setpgid) +DO_REMOTE_SYSCALL(long, sys_olduname) +DO_REMOTE_SYSCALL(long, sys_umask) +DO_REMOTE_SYSCALL(long, sys_ustat) +DO_REMOTE_SYSCALL(long, sys_getppid) +DO_REMOTE_SYSCALL(long, sys_getpgrp) +DO_REMOTE_SYSCALL(long, sys_setsid) +DO_REMOTE_SYSCALL(long, sys_sigaction) +DO_REMOTE_SYSCALL(long, sys_sgetmask) +DO_REMOTE_SYSCALL(long, sys_ssetmask) +DO_REMOTE_SYSCALL(long, sys_sigsuspend) +DO_REMOTE_SYSCALL(long, sys_sigpending) +DO_REMOTE_SYSCALL(long, sys_sethostname) +DO_REMOTE_SYSCALL(long, sys_setrlimit) +DO_REMOTE_SYSCALL(long, sys_old_getrlimit) +DO_REMOTE_SYSCALL(long, sys_getrusage) +DO_REMOTE_SYSCALL(long, sys_gettimeofday) +DO_REMOTE_SYSCALL(long, sys_settimeofday) +DO_REMOTE_SYSCALL(long, sys_getgroups16) +DO_REMOTE_SYSCALL(long, sys_setgroups16) +DO_REMOTE_SYSCALL(long, sys_swapon) +DO_REMOTE_SYSCALL(long, sys_reboot) +DO_REMOTE_SYSCALL(long, sys_getpriority) +DO_REMOTE_SYSCALL(long, sys_setpriority) +DO_REMOTE_SYSCALL(long, sys_socketcall) +DO_REMOTE_SYSCALL(long, sys_syslog) +DO_REMOTE_SYSCALL(long, sys_setitimer) +DO_REMOTE_SYSCALL(long, sys_getitimer) +DO_REMOTE_SYSCALL(long, sys_uname) +DO_REMOTE_SYSCALL(long, sys_wait4) +DO_REMOTE_SYSCALL(long, sys_swapoff) +DO_REMOTE_SYSCALL(long, sys_sysinfo) +DO_REMOTE_SYSCALL(long, sys_ipc) +DO_REMOTE_SYSCALL(long, sys_sigreturn) +DO_REMOTE_SYSCALL(long, sys_clone) +DO_REMOTE_SYSCALL(long, sys_setdomainname) +DO_REMOTE_SYSCALL(long, sys_newuname) +DO_REMOTE_SYSCALL(long, sys_modify_ldt) +DO_REMOTE_SYSCALL(long, sys_adjtimex) +DO_REMOTE_SYSCALL(long, sys_sigprocmask) +DO_REMOTE_SYSCALL(long, sys_init_module) +DO_REMOTE_SYSCALL(long, sys_delete_module) +DO_REMOTE_SYSCALL(long, sys_quotactl) +DO_REMOTE_SYSCALL(long, sys_getpgid) +DO_REMOTE_SYSCALL(long, sys_sysfs) +DO_REMOTE_SYSCALL(long, sys_personality) +DO_REMOTE_SYSCALL(long, sys_get_mempolicy) +DO_REMOTE_SYSCALL(long, sys_set_mempolicy) +DO_REMOTE_SYSCALL(long, sys_kill); +DO_REMOTE_SYSCALL(long, sys_tkill); + +asmlinkage int remote_sys_gettid(struct pt_regs regs) +{ + return current->om.pid; +} + +asmlinkage int remote_sys_getpid(struct pt_regs regs) +{ + return current->om.tgid; +} + +asmlinkage unsigned long remote_sys_brk(struct pt_regs regs) +{ + return sys_brk((unsigned long) SYSARG(0)); +} + +asmlinkage unsigned long remote_sys_mremap(struct pt_regs regs) +{ + return sys_mremap((unsigned long) SYSARG(0), + (unsigned long) SYSARG(1), + (unsigned long) SYSARG(2), + (unsigned long) SYSARG(3), + (unsigned long) SYSARG(4)); +} + +asmlinkage long remote_sys_mprotect(struct pt_regs regs) +{ + return sys_mprotect((unsigned long) SYSARG(0), + (unsigned long) SYSARG(1), + (unsigned long) SYSARG(2)); +} + +asmlinkage long remote_sys_madvise(struct pt_regs regs) +{ + return sys_madvise((unsigned long) SYSARG(0), + (size_t) SYSARG(1), + (int) SYSARG(2)); +} + +asmlinkage long remote_sys_mmap2(struct pt_regs regs) +{ + return sys_mmap2(SYSARG(0), SYSARG(1), SYSARG(2), + SYSARG(3), SYSARG(4), SYSARG(5)); +} + +asmlinkage long remote_sys_mbind(struct pt_regs regs) +{ + return sys_mbind((unsigned long) SYSARG(0), + (unsigned long) SYSARG(1), + (unsigned long) SYSARG(2), + (unsigned long __user *) SYSARG(3), + (unsigned long) SYSARG(4), + (unsigned long) SYSARG(5)); +} + +asmlinkage long remote_sys_munmap(struct pt_regs regs) +{ + return sys_munmap((unsigned long) SYSARG(0), (size_t) SYSARG(1)); +} + +asmlinkage long remote_sys_time(struct pt_regs regs) +{ + return sys_time((int __user *) SYSARG(0)); +} + +/* credentials */ +#ifdef CONFIG_UID16 + +asmlinkage long remote_sys_setresuid16(struct pt_regs regs) +{ + return sys_setresuid16((old_uid_t) SYSARG(0), (old_uid_t) SYSARG(1), + (old_uid_t) SYSARG(2)); +} + +asmlinkage long remote_sys_getresuid16(struct pt_regs regs) +{ + return sys_getresuid16((old_uid_t __user *) SYSARG(0), + (old_uid_t __user *) SYSARG(1), + (old_uid_t __user *) SYSARG(2)); +} + +asmlinkage long remote_sys_setreuid16(struct pt_regs regs) +{ + return sys_setreuid16((old_uid_t) SYSARG(0), (old_uid_t) SYSARG(1)); +} + +asmlinkage long remote_sys_setregid16(struct pt_regs regs) +{ + return sys_setreuid16((old_gid_t) SYSARG(0), (old_gid_t) SYSARG(1)); +} + +asmlinkage long remote_sys_setresgid16(struct pt_regs regs) +{ + return sys_setresgid16((old_gid_t) SYSARG(0), (old_gid_t) SYSARG(1), + (old_gid_t) SYSARG(2)); +} + +asmlinkage long remote_sys_getresgid16(struct pt_regs regs) +{ + return sys_getresgid16((old_gid_t __user *) SYSARG(0), + (old_gid_t __user *) SYSARG(1), + (old_gid_t __user *) SYSARG(2)); +} + +asmlinkage long remote_sys_setfsuid16(struct pt_regs regs) +{ + return sys_setfsuid16((old_uid_t) SYSARG(0)); +} + +asmlinkage long remote_sys_setfsgid16(struct pt_regs regs) +{ + return sys_setfsgid16((old_gid_t) SYSARG(0)); +} + +asmlinkage long remote_sys_setuid16(struct pt_regs regs) +{ + return sys_setuid16((old_uid_t) SYSARG(0)); +} + +asmlinkage long remote_sys_getuid16(struct pt_regs regs) +{ + return sys_getuid16(); +} + +asmlinkage long remote_sys_setgid16(struct pt_regs regs) +{ + return sys_setgid16((old_gid_t) SYSARG(0)); +} + +asmlinkage long remote_sys_getgid16(struct pt_regs regs) +{ + return sys_getgid16(); +} + +asmlinkage long remote_sys_geteuid16(struct pt_regs regs) +{ + return sys_geteuid16(); +} + +asmlinkage long remote_sys_getegid16(struct pt_regs regs) +{ + return sys_getegid16(); +} + +#endif /* CONFIG_UID16 */ + +asmlinkage long remote_sys_setresgid(struct pt_regs regs) +{ + return sys_setresgid((gid_t) SYSARG(0), (gid_t) SYSARG(1), + (gid_t) SYSARG(2)); +} + +asmlinkage long remote_sys_getresgid(struct pt_regs regs) +{ + return sys_getresgid((gid_t __user *) SYSARG(0), + (gid_t __user *) SYSARG(1), + (gid_t __user *) SYSARG(2)); +} + +asmlinkage long remote_sys_setuid(struct pt_regs regs) +{ + return sys_setuid((uid_t) SYSARG(0)); +} + +asmlinkage long remote_sys_setgid(struct pt_regs regs) +{ + return sys_setgid((gid_t) SYSARG(0)); +} + +asmlinkage long remote_sys_setfsuid(struct pt_regs regs) +{ + return sys_setfsuid((uid_t) SYSARG(0)); +} + +asmlinkage long remote_sys_setfsgid(struct pt_regs regs) +{ + return sys_setfsgid((gid_t) SYSARG(0)); +} + +asmlinkage long remote_sys_setresuid(struct pt_regs regs) +{ + return sys_setresuid((uid_t) SYSARG(0), (uid_t) SYSARG(1), + (uid_t) SYSARG(2)); +} + +asmlinkage long remote_sys_getresuid(struct pt_regs regs) +{ + return sys_getresuid((uid_t __user *) SYSARG(0), + (uid_t __user *) SYSARG(1), + (uid_t __user *) SYSARG(2)); +} + +asmlinkage long remote_sys_getuid(struct pt_regs regs) +{ + return sys_getuid(); +} + +asmlinkage long remote_sys_getgid(struct pt_regs regs) +{ + return sys_getgid(); +} + +asmlinkage long remote_sys_geteuid(struct pt_regs regs) +{ + return sys_geteuid(); +} + +asmlinkage long remote_sys_getegid(struct pt_regs regs) +{ + return sys_getegid(); +} + +asmlinkage long remote_sys_setreuid(struct pt_regs regs) +{ + return sys_setreuid((uid_t) SYSARG(0), (uid_t) SYSARG(1)); +} + +asmlinkage long remote_sys_setregid(struct pt_regs regs) +{ + return sys_setregid((gid_t) SYSARG(0), (gid_t) SYSARG(1)); +} + +asmlinkage long remote_sys_getsid(struct pt_regs regs) +{ + return sys_getsid((pid_t) SYSARG(0)); +} diff -Nur --exclude '*.orig' linux-2.6.7.org/hpc/task.c linux-2.6.7/hpc/task.c --- linux-2.6.7.org/hpc/task.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/hpc/task.c 2004-09-02 14:46:54.330229024 +0200 @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * task_set_comm - swap openMosix link for a process (return old one) + * @p: task to swap link + * @mlink: new openMosix link + * + * Description: + * Remove old link from task @p + * Set @p openmosix_link to the new one @mlink + **/ +om_link_t * task_set_comm(task_t *p, om_link_t *mlink) +{ + om_link_t *oldmlink; + + spin_lock_irq(&skown_lock); + oldmlink = p->om.contact; + if (oldmlink) + oldmlink->sock->sk->owner = NULL; + + p->om.contact = mlink; + if (mlink) + mlink->sock->sk->owner = p; + + spin_unlock_irq(&skown_lock); + if (test_bit(SOCK_OOB_IN, &mlink->sock->flags)) + tell_process(p, DREQ_URGENT); + return oldmlink; +} + +int task_test_om_wakeable(task_t *p) +{ + if (p->om.dflags & (DINSCHED | DFAKESIGNAL | DHEAVYSLEEP | DFINISHED)) + return 0; + if (p->state & TASK_UNINTERRUPTIBLE) + return 0; + /* + if (p->om.dflags & DREMOTE && !remote_need_while_asleep(p)) + return 0; + */ + return 1; +} + +void task_om_wake(task_t *p) +{ + struct runqueue * rq; + unsigned long flags; + + rq = task_rq_lock(p, &flags); + + write_lock(&p->om.state_lock); // not irq! + if (p->om.bstate != TASK_SAME) + p->state = TASK_RUNNING; + write_unlock(&p->om.state_lock); + + task_rq_unlock(rq, &flags); +} + +/** + * task_deeper_sleep - Put a task in deeper sleep + **/ +inline void task_deeper_sleep(task_t *p) +{ + unsigned long flags; + runqueue_t *rq; + + if (p->om.hsleep_count++) + return; + rq = task_rq_lock(p, &flags); + task_set_dflags(p, DHEAVYSLEEP); + task_rq_unlock(rq, &flags); + + spin_lock_irqsave(&p->sighand->siglock, flags); + clear_thread_flag(TIF_SIGPENDING); + spin_unlock_irqrestore(&p->sighand->siglock, flags); +} + +/** + * task_om_evaluate_pending_signals - Evaluate signals + * Description: + * evaluate pending signals in openMosix context + **/ +inline void task_om_evaluate_pending_signals(task_t *p) +{ + unsigned long flags; + + spin_lock_irqsave(&p->sighand->siglock, flags); + if (p->om.ignoreoldsigs) + if (task_test_dflags(p, DFAKESIGNAL|DHEAVYSLEEP) == DFAKESIGNAL) + set_tsk_thread_flag(p, TIF_SIGPENDING); + else + clear_tsk_thread_flag(p, TIF_SIGPENDING); + else + recalc_sigpending_tsk(p); + spin_unlock_irqrestore(&p->sighand->siglock, flags); +} + +/** + * task_lighter_sleep - Put a task in lighter sleep + **/ +inline void task_lighter_sleep(task_t *p) +{ + unsigned long flags; + runqueue_t *rq; + + if (--p->om.hsleep_count) + return; + rq = task_rq_lock(p, &flags); + task_clear_dflags(p, DHEAVYSLEEP); + task_rq_unlock(rq, &flags); + task_om_evaluate_pending_signals(p); +} + +static int task_file_check_stay(struct vm_area_struct *vma) +{ + struct inode *inode; + mode_t mode; + int stay = 0; + + inode = vma->vm_file->f_dentry->d_inode; + if (!inode) + return 0; + + mode = inode->i_mode; + + /* FIXME Tab: maybe wrong */ + if (!(vma->vm_flags & VM_NONLINEAR)) { + if (!prio_tree_empty(&inode->i_mapping->i_mmap)) + stay |= DSTAY_FOR_MONKEY; + } else { + if (!list_empty(&vma->shared.vm_set.list)) + stay |= DSTAY_FOR_MONKEY; + } + if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) + stay |= DSTAY_FOR_DEV; + + return stay; +} + +/** + * task_check_stay - adjust stay reason of a task (considering mm) + **/ +int task_check_stay(task_t *p) +{ + struct mm_struct *mm; + int stay; + struct vm_area_struct *vma; + + task_clear_dreqs(p, DREQ_CHECKSTAY); + + /* check if there's a stay reason we can clean, else pass */ + if (!task_test_stay(p, DSTAY_PER_MM | DSTAY_FOR_CLONE)) + return 0; + + task_lock(p); + mm = p->mm; + stay = p->om.stay & ~(DSTAY_PER_MM | DSTAY_FOR_CLONE); + if (!mm) + stay |= DSTAY_FOR_CLONE; + else { + /* FIXME: need verifying KIOBUF */ + if (atomic_read(&mm->mm_realusers) > 1) + stay |= DSTAY_FOR_CLONE; + if (mm->def_flags & VM_LOCKED) + stay |= DSTAY_FOR_MLOCK; + + for (vma = mm->mmap; vma; vma = vma->vm_next) + { + /* does vma map a file */ + if (vma->vm_file) + stay |= task_file_check_stay(vma); + if (vma->vm_flags & VM_LOCKED) + stay |= DSTAY_FOR_MLOCK; + } + } + if (p->om.stay != stay) + p->om.stay = stay; + task_unlock(p); + return 0; +} + +/** + * openmosix_task_init - Init all openMosix structure of a task @p + **/ +int openmosix_task_init(task_t *p) +{ + task_t *parent = current; + om_task_t *om = &p->om; + + memset(om, 0, sizeof(om_task_t)); + + if (p->pid == 1) + task_set_stay(p, DSTAY_ITS_INIT); + + /* if father of task is a DREMOTEDAEMON, then the task is DREMOTE */ + if (task_test_dflags(parent, DREMOTEDAEMON)) + task_set_dflags(p, DREMOTE); + + return 0; +} + +/** + * task_wait_contact - wait until the process got a contact with deputy + **/ +static inline void task_wait_contact(task_t *p) +{ + DECLARE_WAITQUEUE(wait, p); + + add_wait_queue(&p->om.wait_dist, &wait); + while (!p->om.contact) + { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule(); + } + remove_wait_queue(&p->om.wait_dist, &wait); + set_current_state(TASK_RUNNING); +} diff -Nur --exclude '*.orig' linux-2.6.7.org/include/asm-ppc/atomic.h linux-2.6.7/include/asm-ppc/atomic.h --- linux-2.6.7.org/include/asm-ppc/atomic.h 2004-06-16 07:19:02.000000000 +0200 +++ linux-2.6.7/include/asm-ppc/atomic.h 2004-09-02 14:46:54.363224008 +0200 @@ -14,7 +14,8 @@ #define atomic_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) -extern void atomic_clear_mask(unsigned long mask, unsigned long *addr); +extern void atomic_clear_mask(unsigned long mask, atomic_t *addr); +extern void atomic_set_mask(unsigned long mask, atomic_t *addr); #ifdef CONFIG_SMP #define SMP_SYNC "sync" diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/arch.h linux-2.6.7/include/hpc/arch.h --- linux-2.6.7.org/include/hpc/arch.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/arch.h 2004-09-02 14:46:54.364223856 +0200 @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_ARCH_H +#define _HPC_ARCH_H + +#include + +void arch_kickstart(struct task_struct *); +int arch_mig_receive_proc_context(struct task_struct *, struct mig_task_h *); +void arch_mig_receive_fp(struct task_struct *, struct mig_fp_h *); +int arch_mig_receive_specific(task_t *p, struct mig_arch_h *m); + +void arch_mig_send_pre(struct task_struct *); +void arch_mig_send_post(struct task_struct *); +int arch_mig_send_fp(task_t *p, struct mig_fp_h *); +int arch_mig_send_proc_context(struct task_struct *, struct mig_task_h *); +int arch_mig_send_specific(struct task_struct *); + +#include +#include +#include + +#endif /* _HPC_ARCH_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/arch-i386.h linux-2.6.7/include/hpc/arch-i386.h --- linux-2.6.7.org/include/hpc/arch-i386.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/arch-i386.h 2004-09-02 14:46:54.366223552 +0200 @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifdef CONFIG_X86 +#ifndef _HPC_ARCH_ARCH_H +#define _HPC_ARCH_ARCH_H + +int cpu_feature_has_fxsr(void); +void fxsave_to_fsave(union i387_union *, union i387_union *); +void fsave_to_fxsave(union i387_union *, union i387_union *); + +static inline long arch_get_sys_arg(unsigned int n, struct pt_regs *regs) +{ + BUG_ON(n >= 6); + return *(((long *) regs) + n); +} + +static inline int arch_get_sys_nb(struct pt_regs *regs) +{ + return regs->eax; +} + +#endif /* _HPC_ARCH_ARCH_H */ +#endif /* CONFIG_X86 */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/arch-ppc.h linux-2.6.7/include/hpc/arch-ppc.h --- linux-2.6.7.org/include/hpc/arch-ppc.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/arch-ppc.h 2004-09-02 14:46:54.370222944 +0200 @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifdef CONFIG_PPC +#ifndef _HPC_ARCH_ARCH_H +#define _HPC_ARCH_ARCH_H + +static inline long arch_get_sys_arg(unsigned int n, struct pt_regs *regs) +{ + /* FIXME */ + return (long) 0; +} + +static inline int arch_get_sys_nb(struct pt_regs *regs) +{ + return 0; +} + +#endif /* _HPC_ARCH_ARCH_H */ +#endif /* CONFIG_PPC */ + diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/arch-x86_64.h linux-2.6.7/include/hpc/arch-x86_64.h --- linux-2.6.7.org/include/hpc/arch-x86_64.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/arch-x86_64.h 2004-09-02 14:46:54.371222792 +0200 @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifdef CONFIG_X86_64 +#ifndef _HPC_ARCH_ARCH_H +#define _HPC_ARCH_ARCH_H + +static inline long arch_get_sys_arg(unsigned int n, struct pt_regs *regs) +{ + /* FIXME */ + return (long) 0; +} + +static inline long arch_get_sys_nb(struct pt_regs *regs) +{ + return regs->rax; +} + +#endif /* _HPC_ARCH_ARCH_H */ +#endif /* CONFIG_X86_64 */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/comm.h linux-2.6.7/include/hpc/comm.h --- linux-2.6.7.org/include/hpc/comm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/comm.h 2004-09-02 14:46:54.372222640 +0200 @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_COMM_H +#define _HPC_COMM_H + +#include +#include + +/* this was put in include/linux/net.h ..., me no like */ +#define SOCK_INTER_OPENMOSIX 3 /* used internally in kernel-mode */ +#define SOCK_WAIT_MFSDATA 4 /* waiting for MFS data */ +#define SOCK_OOB_IN 5 /* OOB received on openmosix socket */ + + + +#define COMM_DEF_HEADSIZE 256 + + +/* + * openmosix specific data per contact + */ +#define COMM_HEADINUSE 0x01 +#define COMM_WAITACCEPT 0x02 +#define COMM_HIDEDATA 0x04 +#define COMM_FULLLINK 0x08 +#define COMM_INFOLINK 0x10 + + +/* + * message flags: + * lower 16 bits used for message types (see hpc/protocol.h) + * next 8 bits used for message flags (see below) + * upper 8 bits used for mosix logging + */ +#define COMM_MFREGS 0x00800000 +#define COMM_MFDATA 0x00400000 +#define COMM_MFIDENT 0x00100000 +#define COMM_MFOPTIONS 0x00ff0000 +#define COMM_MFHEADOPTS (COMM_MFREGS|COMM_MFIDENT) +#define COMM_ZEROCOPYOK 0x40000000 + +/* + * other flags + */ +#define COMM_ALLDATA (-1) /* copy/flush all available data */ + +/* + * values for mos# (e.g. in comm_open) + * 1..65535 -> valid mos# (mig) + * -1..-65535 -> valid mos# (info) + */ +#define COMM_TOADDR (70001) +#define COMM_ACCEPT (70002) +#define COMM_MIGD (70003) +#define COMM_INFO (70004) +#define COMM_LOOSE (70005) + +#define COMM_SOCKET_SPARE 2048 +#define COMM_SOCKET_DATA 16384 +/* FIXME: was commented out in 2.6-broken +#define COMM_SOCKET_BUFFER (COMM_SOCKET_SPARE + COMM_SOCKET_DATA) +*/ +#define COMM_SOCKET_BUFFER 131072 + +/* node-disconnection timeout: */ +#define OPENMOSIX_CONNECTION_KEEPALIVE_INTERVAL 30 +#define OPENMOSIX_CONNECTION_KEEPALIVE_MAXTRIES 6 +#define OPENMOSIX_CONNECTION_KEEPALIVE_TOTAL 150 /* changed from 180 */ + +#define COMM_REMOTE_TIMO ((unsigned long) 200 * HZ) +#define COMM_CONNECT_TIMO ((unsigned long) 4 * HZ) +#define COMM_RECONN_TIMO ((unsigned long) 10 * HZ) + +/* the ports we use */ +#define MIG_DAEMON_PORT 0x3412 + + +/* Describes an openmosix communication link */ +typedef struct openmosix_link { + /* the first 2 elements are common to both types and must stay there */ + struct socket *sock; /* socket for communications */ + u32 flags; /* status flags */ + u32 dlen; /* length of pending data */ + u32 peer; /* mosix # of peer */ + char *hideptr; /* pointer to hidden data (current) */ + char *hidebuf; /* pointer to start of hidden data buffer */ + u32 hidelen; /* dlen of hidden data */ + char head[COMM_DEF_HEADSIZE]; +} om_link_t; + +/* openmosix_link flags */ +#define COMM_FULLINK 0x01 + +/* external variables that need to be available */ +extern spinlock_t skown_lock; +extern int nmosnet; +extern struct openmosixnet *mosnet; +extern unsigned long comm_remote_timo; +extern unsigned long comm_connect_timo; +extern unsigned long comm_reconn_timo; + +#include +#include + +/* routines inside comm.c */ +void comm_data_ready(struct sock *, int); +om_link_t * comm_socket(int, int, int); +int comm_bind(struct socket *, struct sockaddr *); +int comm_peek(struct socket *); +void comm_close(om_link_t *); +int comm_wait(struct socket *); +int comm_connect(om_link_t *, struct sockaddr *, unsigned long); +int comm_accept(om_link_t *, om_link_t **, struct sockaddr *, unsigned long); +void comm_flushdata(om_link_t *); +int comm_recv(om_link_t *, void *, int); +int comm_send(om_link_t *, void *, int); +int comm_getname(om_link_t *, struct sockaddr *); + +void set_our_addr(int, struct sockaddr *, int); +om_link_t * comm_setup_listen(struct sockaddr *); +om_link_t * comm_setup_connect(struct sockaddr *, int); +int comm_send_hd(om_link_t *, int, void *, int); +int comm_send_req(om_link_t *link, int type); + +/* FIXME: oM task routines, this really should be in task.h, + * but it causes problems there */ +om_link_t * task_set_comm(task_t *, om_link_t *); + +#endif /* _HPC_COMM_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/comm-ipv4.h linux-2.6.7/include/hpc/comm-ipv4.h --- linux-2.6.7.org/include/hpc/comm-ipv4.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/comm-ipv4.h 2004-09-02 14:46:54.374222336 +0200 @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_COMM_IPV4_H +#define _HPC_COMM_IPV4_H + +#ifdef CONFIG_INET +#include + +int inet_to_string(struct sockaddr_in *, char *); +int inet_equal(struct sockaddr_in *, struct sockaddr_in *); +void inet_add_offset(struct sockaddr_in *, struct sockaddr_in *, u16); +int inet_diff(struct sockaddr_in *, struct sockaddr_in *); +int string_to_inet(char *, struct sockaddr_in *); + +#else + +#endif /* CONFIG_INET */ +#endif /* _HPC_COMM_DEP_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/comm-ipv6.h linux-2.6.7/include/hpc/comm-ipv6.h --- linux-2.6.7.org/include/hpc/comm-ipv6.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/comm-ipv6.h 2004-09-02 14:46:54.403217928 +0200 @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_COMM_DEP_H +#define _HPC_COMM_DEP_H + +#ifdef CONFIG_IPV6 + +#include + +int inet6_to_string(struct sockaddr_in6 *, char *); +int inet6_equal(struct sockaddr_in6 *, struct sockaddr_in6 *); +void inet6_add_offset(struct sockaddr_in6 *, struct sockaddr_in6 *, u16); +int inet6_diff(struct sockaddr_in6 *, struct sockaddr_in6 *); +int string_to_inet6(char *, struct sockaddr_in6 *); + +#else + +#define inet6_to_string(s, c) -1 +#define inet6_equal(s, s2) -1 +#define inet6_add_offset(s, s2, i) +#define inet6_diff(s, s2) -1 +#define inet6_in_network(s, net) -1 +#define string_to_inet6(str, s) -1 +#endif /* CONFIG_IPV6 */ +#endif /* _HPC_COMM_DEP_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/debug.h linux-2.6.7/include/hpc/debug.h --- linux-2.6.7.org/include/hpc/debug.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/debug.h 2004-09-02 14:46:54.404217776 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_DEBUG_H +#define _HPC_DEBUG_H + +#include +#include + +int proc_debug_get_loadinfo(char *value, size_t size); +int proc_debug_get_admin(char *value, size_t size); + +int proc_debug_get_lfree_mem(char *value, size_t size); +int proc_debug_get_pkeep_free(char *value, size_t size); + +int proc_debug_get_nodes(char *value, size_t size); + + +/* for packets */ +void debug_mlink(om_link_t *); + +void debug_page(unsigned long); +void debug_regs(void); +void debug_vmas(struct mm_struct *); + +#ifdef CONFIG_OPENMOSIX_MIGRATION_DEBUG +#define OM_MIGRATION_DEBUG(f, a...) printk (f, ## a) +#else +#define OM_MIGRATION_DEBUG(f, a...) /**/ +#endif + +#endif /* _HPC_DEBUG_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/deputy.h linux-2.6.7/include/hpc/deputy.h --- linux-2.6.7.org/include/hpc/deputy.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/deputy.h 2004-09-02 14:46:54.405217624 +0200 @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_DEPUTY_H +#define _HPC_DEPUTY_H + +NORET_TYPE void deputy_die_on_communication(void); +void deputy_main_loop(void); +void deputy_startup(task_t *p); + +#endif /* _HPC_DEPUTY_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/fs.h linux-2.6.7/include/hpc/fs.h --- linux-2.6.7.org/include/hpc/fs.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/fs.h 2004-09-02 14:46:54.407217320 +0200 @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_FS_H +#define _HPC_FS_H + +#include +#include + +void task_held_files_clear(struct task_struct *); +int task_held_files_add(struct task_struct *, struct file *, int); +void task_held_files_undo(struct task_struct *, struct file *, int); +int task_held_files_rebuild(struct task_struct *); +int task_maps_inode(struct task_struct *, struct inode *); +struct file * get_remote_file(u32 origin, struct file *fpr, + struct dentry *dpr, u64 uniq, off_t isize, + nopage_t nopage); + +#endif /* _HPC_FS_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/hpc.h linux-2.6.7/include/hpc/hpc.h --- linux-2.6.7.org/include/hpc/hpc.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/hpc.h 2004-09-02 14:46:54.409217016 +0200 @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_HPC_H +#define _HPC_HPC_H + +#include +#include + +/* arch specific */ +int user_thread(int (*fn)(void *), void * arg, unsigned long flags); + +/* init.c */ +void openmosix_init(void); +void info_startup(void); + +/* info.c */ +void info_init(void); +void info_update_costs(void); +void info_update_timeout(void); +int openmosix_info_daemon(void *); + +/* proc.c */ +int openmosix_proc_pid_getattr(struct task_struct *, char *, void *, size_t); +int openmosix_proc_pid_setattr(struct task_struct *, char *, void *, size_t); +void openmosix_proc_init(void); +void proc_update_costs(void); + +/* load.c */ +void load_init(void); +void openmosix_snap_load(unsigned long); + +/* kernel.c */ +int om_wakeable(task_t *); + +int openmosix_pre_clone(void); +void openmosix_post_clone(void); + +int stay_me_and_my_clones(int); +void openmosix_no_longer_monkey(struct inode *); +void unstay_mm(struct mm_struct *); + +int openmosix_events_need(task_t *p); +void openmosix_events_run(task_t *p); + +/* kernel/fork.c */ +void openmosix_free_task_struct(struct task_struct *); + +/* kernel/user.c */ +int get_free_guest_slots(void); + +/* task.c */ +int openmosix_task_init(struct task_struct *); + +struct openmosix_options +{ + int debug_verbose_migration; +}; + +extern struct openmosix_options om_opts; + +#endif /* _HPC_HPC_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/lock.h linux-2.6.7/include/hpc/lock.h --- linux-2.6.7.org/include/hpc/lock.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/lock.h 2004-09-02 14:46:54.412216560 +0200 @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_LOCK_H +#define _HPC_LOCK_H + +#include + +/* + * the big openMosix lock + */ + +extern spinlock_t om_lock; + +static inline void openmosix_lock(unsigned long *om_flags) +{ + spin_lock_irqsave(&om_lock, *om_flags); +} + +static inline void openmosix_unlock(unsigned long *om_flags) +{ + spin_unlock_irqrestore(&om_lock, *om_flags); +} + + +#endif /* _HPC_LOCK_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/mem.h linux-2.6.7/include/hpc/mem.h --- linux-2.6.7.org/include/hpc/mem.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/mem.h 2004-09-02 14:46:54.414216256 +0200 @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ +#ifndef _HPC_FREEMEM_H +#define _HPC_FREEMEM_H + +int memory_badly_required(void); +int memory_relief_quality(task_t *, int); +int openmosix_mem_daemon(void *); +int obtain_mm(struct task_struct *); +int dirty_all_remote_pages(unsigned long, unsigned long, int); +int export_mem(void); +int run_over_dirty_pages(struct task_struct *, + int (*func)(struct task_struct *, unsigned long, int), + int); +int count_migrating_pages(struct task_struct *); + +#endif /* _HPC_FREEMEM_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/mig.h linux-2.6.7/include/hpc/mig.h --- linux-2.6.7.org/include/hpc/mig.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/mig.h 2004-09-02 14:46:54.415216104 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_MIG_H +#define _HPC_MIG_H + +#include +#include +#include + +#define REMOTE_DAEMON_PORT 0x3412 + +/* PROTOTYPES */ +int openmosix_mig_daemon(void *); +int mig_do_receive(task_t *); + +int openmosix_migsend_daemon(void *); +int migsend_task_register(task_t *, struct sockaddr *); +int migsend_task_unregister(task_t *); +void migsend_wake_up(void); + +int task_move_to_node(task_t *, struct sockaddr *, int); + +int mig_do_send(task_t *); +int mig_do_receive(task_t *); + +int mig_send_hshake(task_t *, om_link_t *, int); +int mig_recv_hshake(om_link_t *); + +int task_remote_expel(task_t *); + +#define OM_COND_DEBUG(var, cond, ...) if (om_opts.var cond) { printk(##); } + +#endif /* _HPC_MIG_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/omtask.h linux-2.6.7/include/hpc/omtask.h --- linux-2.6.7.org/include/hpc/omtask.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/omtask.h 2004-09-02 14:46:54.417215800 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_OMTASK_H +#define _HPC_OMTASK_H + +struct held_file +{ + struct file *f; /* file in use */ + char denywrite; /* do we hold i_write down */ +}; + +/* temporary fix for ppc */ +#ifndef NCAPINTS +# define NCAPINTS 1 +#endif + +typedef struct openmosix_task { + volatile u32 dflags; /* distributed flags */ + atomic_t dreqs; /* bits that others may request */ + volatile u32 whereto; /* migration request */ + volatile u32 bstate; /* backed-up state while in oM */ + rwlock_t state_lock; /* changes of bstate */ + volatile u32 stay; /* reasons why process must stay */ + char hsleep_count; /* count on DHEAVYSLEEP */ + volatile char ignoreoldsigs; /* deliberately cleared ->sigpending */ + struct openmosix_link *contact; /* DEPUTY <==> REMOTE connection */ + volatile char commpri; /* prioririty for oM communication */ + kernel_cap_t remote_caps; /* effective capabilities on REMOTE */ + pid_t pid; /* original PID */ + pid_t tgid; /* original TGID */ + struct held_file *held_files; /* held files */ + int held_allocated; /* # of entries in "held_inodes" */ + wait_queue_head_t wait_dist; /* misc. wait for process */ + /* arch dependant */ + u32 features[NCAPINTS]; /* CPU features on original node */ + +} om_task_t; + +#endif /* _HPC_OMTASK_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/proc.h linux-2.6.7/include/hpc/proc.h --- linux-2.6.7.org/include/hpc/proc.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/proc.h 2004-09-02 14:46:54.468208048 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_PROC_H +#define _HPC_PROC_H + +int proc_pid_set_0(task_t *p, char *value, size_t size) { return -EINVAL; } +int proc_pid_get_0(task_t *p, char *value, size_t size) { return -EINVAL; } +int proc_admin_set_0(char *value, size_t size) { return -EINVAL; } +int proc_admin_get_0(char *value, size_t size) { return -EINVAL; } +int proc_info_set_0(char *value, size_t size) { return -EINVAL; } +int proc_info_get_0(char *value, size_t size) { return -EINVAL; } +int proc_debug_set_0(char *value, size_t size) { return -EINVAL; } +int proc_debug_get_0(char *value, size_t size) { return -EINVAL; } + +typedef struct om_proc_entry { + int type; + int len; + char *name; + mode_t mode; + int (*set)(char *dummy, size_t); + int (*get)(char *dummy, size_t); +} om_proc_entry_t; + +typedef struct om_proc_pid_entry { + int type; + int len; + char *name; + mode_t mode; + int (*set)(task_t *t, char *dummy, size_t); + int (*get)(task_t *t, char *dummy, size_t); +} om_proc_pid_entry_t; + +#endif /* _HPC_PROC_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/protocol.h linux-2.6.7/include/hpc/protocol.h --- linux-2.6.7.org/include/hpc/protocol.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/protocol.h 2004-09-02 14:46:54.469207896 +0200 @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ +#ifndef _HPC_PROTOCOL_H +#define _HPC_PROTOCOL_H + +#include +#include +#include +#include +#include +#include + +/* Migration handshake*/ +struct mig_handshake_h { + int type; /* which type (look below) */ + long version; /* openmosix version */ + int reason; /* reason for mig or command */ + int personality; /* of process to be sent */ +}; +/* handshake types */ +#define HSHAKE_MIG_REQUEST 0x01 +#define HSHAKE_DEPUTY_PROBE 0x02 +#define HSHAKE_REPLY 0x04 +#define HSHAKE_NOTOK 0x08 + + +/* main structure for passing messages between + * DEPUTY and REMOTE. Denotes the type of request, + * and the length of if it */ +struct mig_req_h +{ + int type; + int dlen; + int aux; /* auxillary info, used by type */ +}; + +#define DEP_FLG 0x100 +#define MIG_FLG 0x200 +#define REM_FLG 0x400 +#define REPLY 0x800 + +/* what are we migrating? */ +#define MIG_MM_STATS (MIG_FLG | 0x10) +#define MIG_MM_AREA (MIG_FLG | 0x11) +#define MIG_PAGE (MIG_FLG | 0x12) +#define MIG_FP (MIG_FLG | 0x13) +#define MIG_ARCH (MIG_FLG | 0x14) +#define MIG_TASK (MIG_FLG | 0x15) +#define MIG_NOT_COMING (MIG_FLG | 0x16) +#define MIG_OM (MIG_FLG | 0x17) + +/* commands from remote -> deputy */ +#define DEP_COMING_HOME (DEP_FLG | 0x10) +#define DEP_FORCE_SIG (DEP_FLG | 0x11) + +/* commands from deputy -> remote */ +#define REM_BRING_HOME (REM_FLG | 0x10) +#define REM_NULLMSG (REM_FLG | 0x11) +#define REM_SYSCALL (REM_FLG | 0x12) +#define REM_SIGNAL (REM_FLG | 0x13) + +struct mmap_parameters_h +{ + unsigned long addr; + unsigned long len; + unsigned long flags; + unsigned long pgoff; + struct file *fp; + struct dentry *dp; + u64 uniq; + off_t isize; +// nopage_t nopage; +}; + +/* task_struct values that need to be passed */ +struct mig_task_h +{ + unsigned long ptrace; + unsigned long dflags; + long nice; + + kernel_cap_t caps; + unsigned long it_prof_value, it_prof_incr, it_virt_value, it_virt_incr; + struct rlimit rlim_cpu, rlim_data, rlim_stack, rlim_rss, rlim_as; + + pid_t pid, tgid; + + /* process credentials */ + uid_t uid,euid,suid,fsuid; + gid_t gid,egid,sgid,fsgid; + + /* signals */ + sigset_t blocked, real_blocked; + + /* saved user space regs */ + struct pt_regs regs; + + struct mig_arch_task_h arch; +}; + +/* openmosix specific values */ +struct mig_om_h +{ + int pagecredit; + int lastxcpu; +}; + +/* mm_struct values */ +struct mm_stats_h { + unsigned long start_code, end_code, start_data, end_data; + unsigned long start_brk, brk, start_stack; + unsigned long arg_start, arg_end, env_start, env_end; +}; + +struct mig_syscall_h { + int n; + unsigned long arg[6]; +}; + +struct mig_syscall_ret_h { + long ret; +}; + +struct mig_signal_h { + sigset_t sigs; +}; + +#endif /* _HPC_PROTOCOL_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/protocol-i386.h linux-2.6.7/include/hpc/protocol-i386.h --- linux-2.6.7.org/include/hpc/protocol-i386.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/protocol-i386.h 2004-09-02 14:46:54.473207288 +0200 @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifdef CONFIG_X86 +#ifndef _HPC_ARCHPROTOCOL_H +#define _HPC_ARCHPROTOCOL_H + +#include + +#define MIG_ARCH_I386_LDT 1 + +struct mig_fp_h +{ + int has_fxsr; + union i387_union data; +}; + +struct mig_arch_h +{ + int type; + +}; + +struct mig_arch_task_h +{ + u32 features[NCAPINTS]; + long debugreg[8]; +}; + +#endif /* _HPC_ARCHPROTOCOL_H */ +#endif /* CONFIG_X86 */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/protocol-ppc.h linux-2.6.7/include/hpc/protocol-ppc.h --- linux-2.6.7.org/include/hpc/protocol-ppc.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/protocol-ppc.h 2004-09-02 14:46:54.474207136 +0200 @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifdef CONFIG_PPC +#ifndef _HPC_ARCHPROTOCOL_H +#define _HPC_ARCHPROTOCOL_H +struct mig_fp_h +{ + int has_altivec; + double fpr[32]; + unsigned long fpscr_pad; + unsigned long fpscr; +}; + +struct mig_arch_h +{ +}; + +struct mig_arch_task_h +{ +}; + +#endif /* _HPC_ARCHPROTOCOL_H */ +#endif /* CONFIG_PPC */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/protocol-x86_64.h linux-2.6.7/include/hpc/protocol-x86_64.h --- linux-2.6.7.org/include/hpc/protocol-x86_64.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/protocol-x86_64.h 2004-09-02 14:46:54.476206832 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifdef CONFIG_X86_64 +#ifndef _HPC_ARCHPROTOCOL_H +#define _HPC_ARCHPROTOCOL_H + +#include + +#define MIG_ARCH_I386_LDT 1 + +struct mig_fp_h +{ + union i387_union data; +}; + +struct mig_arch_h +{ + int type; +}; + +struct mig_arch_task_h +{ +}; + +#endif /* _HPC_ARCHPROTOCOL_H */ +#endif /* CONFIG_X86_64 */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/remote_fs_i.h linux-2.6.7/include/hpc/remote_fs_i.h --- linux-2.6.7.org/include/hpc/remote_fs_i.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/remote_fs_i.h 2004-09-02 14:46:54.477206680 +0200 @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ +#ifndef _REMOTE_FS_I_H +#define _REMOTE_FS_I_H + + +struct vm_area_struct; +typedef struct page * (*nopage_t)(struct vm_area_struct *, unsigned long, int *); + +struct remote_inode_info +{ + int origin; /* node of origin */ + struct dentry *dp; /* dentry pointer on origin */ + uint64_t unique; /* unique version on origin */ + nopage_t nopage; /* nopage routine */ +}; + +#define home_file(f) (*((struct file **)(&(f)->f_pos))) + +#endif /* _REMOTE_FS_I_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/remote.h linux-2.6.7/include/hpc/remote.h --- linux-2.6.7.org/include/hpc/remote.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/remote.h 2004-09-02 14:46:54.480206224 +0200 @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_REMOTE_H +#define _HPC_REMOTE_H + +#include + +NORET_TYPE void remote_disappear(void); +int remote_mmap(struct mmap_parameters_h *, int); +int remote_readpage(struct file *, struct page *); +long remote_do_syscall(int, struct pt_regs); +int remote_do_comm(task_t *); + +#endif /* _HPC_REMOTE_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/service.h linux-2.6.7/include/hpc/service.h --- linux-2.6.7.org/include/hpc/service.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/service.h 2004-09-02 14:46:54.481206072 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_SERVICE_H +#define _HPC_SERVICE_H + +#include +#include + +#define MILLION 1000000 +#define DMILLION 1000000.0 + + +#if MILLION % HZ +#define ticks_to_ms(ticks) (((int64_t)(ticks)) * MILLION / HZ) +#define ms_to_ticks(ms) ((ms) * HZ / MILLION) +#else +#define ticks_to_ms(ticks) (((int64_t)(ticks)) * (MILLION / HZ)) +#define ms_to_ticks(ms) ((ms) / (MILLION / HZ)) +#endif + +int sockaddr_equal(struct sockaddr *a1, struct sockaddr *a2); +int sockaddr_to_string(struct sockaddr *address, char *buffer); +int string_to_sockaddr(char *buf, struct sockaddr *address); + +void om_daemonize(char *, int); + +#endif /* _HPC_SERVICE_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/syscalls.h linux-2.6.7/include/hpc/syscalls.h --- linux-2.6.7.org/include/hpc/syscalls.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/syscalls.h 2004-09-02 14:46:54.482205920 +0200 @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_SYSCALL_H +#define _HPC_SYSCALL_H + +#define INVALID_REMOTE_SYSCALL(ret, name) \ +ret remote_sys_##name (struct pt_regs regs) { \ + printk(KERN_ERR "oM: invalid syscall " #name "called.\n"); \ + BUG(); \ + return (ret) 0; \ +} + +#define DO_REMOTE_SYSCALL(ret, name) \ +asmlinkage ret remote_##name (struct pt_regs regs) { \ + return (ret) remote_do_syscall(arch_get_sys_nb(®s), regs); \ +} + +#define SYSARG(n) arch_get_sys_arg(n, ®s) +#define SYSNB() arch_get_sys_nb(®s) + +#endif /* _HPC_SYSCALL_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/task.h linux-2.6.7/include/hpc/task.h --- linux-2.6.7.org/include/hpc/task.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/task.h 2004-09-02 14:46:54.510201664 +0200 @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_TASK_H +#define _HPC_TASK_H + +#include +#include +#include + +#define OPENMOSIX_INIT_TASK(tsk) .om = { \ + .dreqs = ATOMIC_INIT(0), \ + .bstate = TASK_SAME, \ + .state_lock = RW_LOCK_UNLOCKED, \ +} + +#define OPENMOSIX_INIT_MM() \ + .mm_realusers = ATOMIC_INIT(1), \ + + +/* for kernel/sched.c */ +#define TASK_SAME 32 + + +/* + * distributed flags (dflags) that are set only by the process itself, + * (but may be read by others): + * the following locks (in correct order of locking) are required to + * modify those bits: + * + * DINSCHED: runqueue_lock + * DHEAVYSLEEP: runqueue_lock + * DREMOTEDFSA: runqueue_lock + * DPASSING: runqueue_lock + * DINCOMING: runqueue_lock + * DDEPUTY: lock_mosix, tasklist_lock, runqueue_lock, task_lock + * DFINISHED: lock_mosix, runqueue_lock, task_lock + * DPAGEIN: runqueue_lock + * DSENTURGENT: runqueue_lock + * DFAKESIGNAL: sometimes sigmask_lock + */ +#define DDEPUTY 0x00000001 /* process is a DEPUTY stub */ +#define DREMOTE 0x00000002 /* process is running remotely */ +#define DINSCHED 0x00000004 /* task within "schedule" */ +#define DSYNC 0x00000008 /* remote process is synced and waits */ +#define DPSYNC DSYNC /* deputy must tell us to continue */ +#define DNESTED 0x00000010 /* nested requests from remote */ +#define DSENTURGENT 0x00000020 /* REMOTE has already sent OOB */ +#define DINCOMING 0x00000040 /* process coming here */ +#define DPASSING 0x00000080 /* process is in migration */ +#define DPAGEIN 0x00000100 /* in pagein, considered running */ +#define DFINISHED 0x00000200 /* wants to become zombie */ +#define DREMOTEDAEMON 0x00000400 /* set DREMOTE on "fork" */ +#define DFAKESIGNAL 0x00000800 /* produce a fake signal */ +#define DHEAVYSLEEP 0x00001000 /* prevent signals/events when asleep */ +#define DTRACESYS1 0x00002000 /* PT_TRACESYS done before syscall */ +#define DTRACESYS2 0x00004000 /* PT_TRACESYS done before 2nd syscall*/ +#define DMUSTBEBACK 0x00008000 /* MUST arrive back home */ +#define DDUMPABLE 0x00010000 /* copy of dumpable when DEPUTY */ +#define DDELAYHELD 0x00020000 /* rebuild held_files later */ +#define DTDUMPABLE 0x00040000 /* copy of task_dumpable when DEPUTY */ +#define DMIGFILTER 0x00040000 /* process migration is conditioned */ + +#define DMIGRATED (DDEPUTY | DREMOTE) /* if task has been migrated */ + +/* + * bits in "dreqs" (anything that others can set): + */ +#define DREQ_NICECNG 0x00000001 /* priority changed */ +#define DREQ_UPDOVERHEADS 0x00000002 /* update overheads */ +#define DREQ_HOMEWAKE 0x00000004 /* wake when arrived home */ +#define DREQ_CHECKCONF 0x00000008 /* check oM configuration */ +#define DREQ_CHECKSTAY 0x00000010 /* check whether still stay */ +#define DREQ_URGENT 0x00000020 /* something urgent (R=>D) */ +#define DREQ_CAPCNG 0x00000040 /* capabilities changed */ +#define DREQ_INFOCNG 0x00000080 /* disclosed info changed */ +#define DREQ_FILEUNMAP 0x00000100 /* file(s) were unmapped */ +/* we don't actually use these but they're hanging around in some code */ +#define DREQ_DFSASYNC 0 +#define DREQ_EXITDFSA 0 + +#define tell_process(p,what) task_set_dreqs(p, what) +#define process_ack(p,what) task_clear_dreqs(p, what) +#define process_told(p,what) task_test_dreqs(p, what) + +/* + * reasons to stay: + */ + +#define DSTAY_FOR_MONKEY 0x00000001 /* using monkey vnode */ +#define DSTAY_FOR_DEV 0x00000002 /* mapping a device */ +#define DSTAY_FOR_86 0x00000004 /* running in 86 mode */ +#define DSTAY_ITS_DAEMON 0x00000008 /* daemon process */ +#define DSTAY_FOR_PRIV 0x00000010 /* privilleged inst. access (in/out) */ +#define DSTAY_FOR_MLOCK 0x00000020 /* has locked memory */ +#define DSTAY_FOR_CLONE 0x00000040 /* shared VM, eliminate this once DSM*/ +#define DSTAY_FOR_RT 0x00000080 /* Real-Time scheduling */ +#define DSTAY_FOR_IOPL 0x00000100 /* direct I/O permission */ +#define DSTAY_ITS_INIT 0x00000200 /* init process */ +#define DSTAY_FOR_KIOBUF 0x00000400 /* using kiobuf */ +#define DSTAY_OTHER1 0x01000000 /* external reason for stay (1) */ +#define DSTAY_OTHER2 0x02000000 /* external reason for stay (2) */ +#define DSTAY_OTHER3 0x04000000 /* external reason for stay (3) */ +#define DSTAY_OTHER4 0x08000000 /* external reason for stay (4) */ +#define DNOMIGRATE 0x80000000 /* user requested no auto-migrations */ + +#define DSTAY (~DNOMIGRATE) +#define DSTAY_PER_MM (DSTAY_FOR_MONKEY|DSTAY_FOR_DEV|DSTAY_FOR_MLOCK|DSTAY_FOR_KIOBUF) + + +/* + * where to go (whereto) + */ +#define GOBACKHOME (-1) /* just go back home */ +#define BALANCE (-2) /* perform load balancing */ +#define IOBALANCE (-3) /* perform load balancing for I/O */ +#define MEMBALANCE (-4) /* perform balancing for memory */ +#define MFSBALANCE (-5) /* must go back home */ +#define MUSTGOHOME (-6) /* must go back home */ + +#define URGENT_REMOTE_CONDITIONS(m) ((p)->om.whereto) + +int task_set_where(struct task_struct *p, int value); +int task_get_where(struct task_struct *p); + +struct runqueue; +typedef struct runqueue runqueue_t; +runqueue_t *task_rq_lock(struct task_struct *p, unsigned long *flags); +void task_rq_unlock(runqueue_t *rq, unsigned long *flags); + +/* dreqs */ +static inline void task_set_dreqs(struct task_struct *p, unsigned int val) +{ + atomic_set_mask(val, &p->om.dreqs); +} + +static inline void task_clear_dreqs(struct task_struct *p, unsigned int val) +{ + atomic_clear_mask(val, &p->om.dreqs); +} + +static inline int task_test_dreqs(struct task_struct *p, unsigned int val) +{ + return atomic_read(&p->om.dreqs) & val; +} + +/* dflags */ + +static inline void task_set_dflags(struct task_struct *p, unsigned int val) +{ + p->om.dflags |= val; +} + +static inline void task_clear_dflags(struct task_struct *p, unsigned int val) +{ + p->om.dflags &= ~val; +} + +static inline int task_test_dflags(struct task_struct *p, unsigned int val) +{ + return (p->om.dflags & val); +} + +/* stay */ + +static inline void task_set_stay(struct task_struct *p, unsigned int val) +{ + p->om.stay |= val; +} + +static inline void task_clear_stay(struct task_struct *p, unsigned int val) +{ + p->om.stay &= ~val; +} + +static inline int task_test_stay(struct task_struct *p, unsigned int val) +{ + return (p->om.stay & val); +} + +void task_deeper_sleep(struct task_struct *p); +void task_lighter_sleep(struct task_struct *p); + +int task_test_om_wakeable(struct task_struct *p); +void task_om_wake(struct task_struct *p); +void task_add_balance_reason(struct task_struct *p, int w); + +int task_go_home(struct task_struct *p); +int task_go_home_for_reason(struct task_struct *p, int reason); + +int task_check_stay(struct task_struct *p); + +#endif /* _HPC_HPCTASK_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/hpc/version.h linux-2.6.7/include/hpc/version.h --- linux-2.6.7.org/include/hpc/version.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.7/include/hpc/version.h 2004-09-02 14:46:54.511201512 +0200 @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2002-2004 Moshe Bar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Original Mosix code Copyright (C) Amnon Barak, Amnon Shiloh + * + * Changes for 2.6 by Vincent Hanquez and Alexander Nyberg + * + */ + +#ifndef _HPC_VERSION_H +#define _HPC_VERSION_H + +#define OPENMOSIX_VERSION_MAJOR 0 +#define OPENMOSIX_VERSION_MINOR 0 +#define OPENMOSIX_VERSION_MICRO 0 + +#define OPENMOSIX_VERSION (OPENMOSIX_VERSION_MAJOR * 10000) + \ + (OPENMOSIX_VERSION_MINOR * 100) + \ + (OPENMOSIX_VERSION_MICRO) + +#define OPENMOSIX_VERSION_TUPPLE \ + OPENMOSIX_VERSION_MAJOR, \ + OPENMOSIX_VERSION_MINOR, \ + OPENMOSIX_VERSION_MICRO + +/* FIXME : need to create a scheme about version handling */ +#define OPENMOSIX_VERSION_BALANCE 0x1L +#define OPENMOSIX_VERSION_MIGRATION 0x1L + +#endif /* _HPC_VERSION_H */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/compiler.h linux-2.6.7/include/linux/compiler.h --- linux-2.6.7.org/include/linux/compiler.h 2004-09-02 14:42:13.703890712 +0200 +++ linux-2.6.7/include/linux/compiler.h 2004-09-02 14:46:54.513201208 +0200 @@ -17,6 +17,12 @@ #ifdef __KERNEL__ +#ifdef CONFIG_OPENMOSIX +#define OM_NSTATIC +#else +#define OM_NSTATIC static +#endif + #ifndef __ASSEMBLY__ #if __GNUC__ > 3 # include /* catch-all for GCC 4, 5, etc. */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/fs.h linux-2.6.7/include/linux/fs.h --- linux-2.6.7.org/include/linux/fs.h 2004-09-02 14:42:21.948637320 +0200 +++ linux-2.6.7/include/linux/fs.h 2004-09-02 14:46:54.519200296 +0200 @@ -20,6 +20,8 @@ #include #include +#include + struct iovec; struct nameidata; struct pipe_inode_info; @@ -465,10 +467,18 @@ __u32 i_generation; union { void *generic_ip; +#ifdef CONFIG_OPENMOSIX + struct remote_inode_info remote_i; +#endif /* CONFIG_OPENMOSIX */ } u; +#ifdef CONFIG_OPENMOSIX + __u64 i_unique; +#endif /* CONFIG_OPENMOSIX */ + #ifdef __NEED_I_SIZE_ORDERED seqcount_t i_size_seqcount; #endif + }; /* diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/init_task.h linux-2.6.7/include/linux/init_task.h --- linux-2.6.7.org/include/linux/init_task.h 2004-09-02 14:42:14.207814104 +0200 +++ linux-2.6.7/include/linux/init_task.h 2004-09-02 14:46:54.522199840 +0200 @@ -2,6 +2,7 @@ #define _LINUX__INIT_TASK_H #include +#include #define INIT_FILES \ { \ @@ -42,6 +43,7 @@ .mmlist = LIST_HEAD_INIT(name.mmlist), \ .cpu_vm_mask = CPU_MASK_ALL, \ .default_kioctx = INIT_KIOCTX(name.default_kioctx, name), \ + OPENMOSIX_INIT_MM() \ } #define INIT_SIGNALS(sig) { \ @@ -112,6 +114,7 @@ .proc_lock = SPIN_LOCK_UNLOCKED, \ .switch_lock = SPIN_LOCK_UNLOCKED, \ .journal_info = NULL, \ + OPENMOSIX_INIT_TASK(tsk) \ } diff -Nur --exclude '*.orig' linux-2.6.7.org/include/linux/sched.h linux-2.6.7/include/linux/sched.h --- linux-2.6.7.org/include/linux/sched.h 2004-09-02 14:42:21.996630024 +0200 +++ linux-2.6.7/include/linux/sched.h 2004-09-02 14:46:54.553195128 +0200 @@ -30,6 +30,10 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include +#endif /* CONFIG_OPENMOSIX */ + struct exec_domain; struct linux_binprm; @@ -230,6 +234,9 @@ struct kioctx *ioctx_list; struct kioctx default_kioctx; +#ifdef CONFIG_OPENMOSIX + atomic_t mm_realusers; /* nb of processes that uses this mm */ +#endif /* CONFIG_MOSIX */ }; extern int mmlist_nr; @@ -515,7 +522,10 @@ unsigned long ptrace_message; siginfo_t *last_siginfo; /* For ptrace use. */ - + +#ifdef CONFIG_OPENMOSIX + om_task_t om; +#endif /* CONFIG_OPENMOSIX */ #ifdef CONFIG_NUMA struct mempolicy *mempolicy; short il_next; /* could be shared with used_math */ diff -Nur --exclude '*.orig' linux-2.6.7.org/include/net/sock.h linux-2.6.7/include/net/sock.h --- linux-2.6.7.org/include/net/sock.h 2004-09-02 14:42:16.699435320 +0200 +++ linux-2.6.7/include/net/sock.h 2004-09-02 14:46:54.556194672 +0200 @@ -266,6 +266,9 @@ int (*sk_backlog_rcv)(struct sock *sk, struct sk_buff *skb); void (*sk_destruct)(struct sock *sk); +#ifdef CONFIG_OPENMOSIX + struct task_struct *owner; +#endif /* CONFIG_OPENMOSIX */ }; /* diff -Nur --exclude '*.orig' linux-2.6.7.org/init/main.c linux-2.6.7/init/main.c --- linux-2.6.7.org/init/main.c 2004-09-02 14:42:22.415566336 +0200 +++ linux-2.6.7/init/main.c 2004-09-02 14:46:54.562193760 +0200 @@ -49,6 +49,10 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include +#endif /* CONFIG_OPENMOSIX */ + /* * This is one of the first .c files built. Error out early * if we have compiler trouble.. @@ -693,6 +697,9 @@ * initmem segments and start the user-mode stuff.. */ free_initmem(); + + openmosix_init(); + unlock_kernel(); system_state = SYSTEM_RUNNING; numa_default_policy(); diff -Nur --exclude '*.orig' linux-2.6.7.org/kernel/exit.c linux-2.6.7/kernel/exit.c --- linux-2.6.7.org/kernel/exit.c 2004-09-02 14:42:22.240592936 +0200 +++ linux-2.6.7/kernel/exit.c 2004-09-02 14:46:54.591189352 +0200 @@ -815,7 +815,7 @@ asmlinkage NORET_TYPE void do_exit(long code) { struct task_struct *tsk = current; - + if (unlikely(in_interrupt())) panic("Aiee, killing interrupt handler!"); if (unlikely(!tsk->pid)) diff -Nur --exclude '*.orig' linux-2.6.7.org/kernel/fork.c linux-2.6.7/kernel/fork.c --- linux-2.6.7.org/kernel/fork.c 2004-09-02 14:42:22.242592632 +0200 +++ linux-2.6.7/kernel/fork.c 2004-09-02 14:46:54.598188288 +0200 @@ -45,6 +45,10 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include +#endif /* CONFIG_OPENMOSIX */ + /* The idle threads do not count.. * Protected by write_lock_irq(&tasklist_lock) */ @@ -82,6 +86,14 @@ free_task_struct(tsk); } +#ifdef CONFIG_OPENMOSIX +void openmosix_free_task_struct(struct task_struct *tsk) +{ + free_task_struct(tsk); +} +EXPORT_SYMBOL(openmosix_free_task_struct); +#endif /* CONFIG_OPENMOSIX */ + void __put_task_struct(struct task_struct *tsk) { WARN_ON(!(tsk->state & (TASK_DEAD | TASK_ZOMBIE))); @@ -408,6 +420,9 @@ { atomic_set(&mm->mm_users, 1); atomic_set(&mm->mm_count, 1); +#ifdef CONFIG_OPENMOSIX + atomic_set(&mm->mm_realusers, 1); +#endif /* CONFIG_OPENMOSIX */ init_rwsem(&mm->mmap_sem); mm->core_waiters = 0; mm->page_table_lock = SPIN_LOCK_UNLOCKED; @@ -545,6 +560,9 @@ if (clone_flags & CLONE_VM) { atomic_inc(&oldmm->mm_users); +#ifdef CONFIG_OPENMOSIX + atomic_inc(&oldmm->mm_realusers); +#endif /* CONFIG_OPENMOSIX */ mm = oldmm; /* * There are cases where the PTL is held to ensure no @@ -572,6 +590,9 @@ retval = dup_mmap(mm, oldmm); if (retval) goto free_pt; +#ifdef CONFIG_OPENMOSIX + task_clear_stay(tsk, DSTAY_FOR_CLONE); +#endif /* CONFIG_OPENMOSIX */ good_mm: tsk->mm = mm; @@ -983,6 +1004,10 @@ goto bad_fork_cleanup_policy; if ((retval = audit_alloc(p))) goto bad_fork_cleanup_security; +#ifdef CONFIG_OPENMOSIX + if ((retval = openmosix_task_init(p))) + goto bad_fork_cleanup; +#endif /* CONFIG_OPENMOSIX */ /* copy all the process information */ if ((retval = copy_semundo(clone_flags, p))) goto bad_fork_cleanup_audit; diff -Nur --exclude '*.orig' linux-2.6.7.org/kernel/sched.c linux-2.6.7/kernel/sched.c --- linux-2.6.7.org/kernel/sched.c 2004-09-02 14:42:22.266588984 +0200 +++ linux-2.6.7/kernel/sched.c 2004-09-02 14:46:54.635182664 +0200 @@ -50,6 +50,10 @@ #define cpu_to_node_mask(cpu) (cpu_online_map) #endif +#ifdef CONFIG_OPENMOSIX +#include +#endif /* CONFIG_OPENMOSIX */ + /* * Convert user-nice values [ -20 ... 0 ... 19 ] * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ], @@ -259,7 +263,7 @@ * interrupts. Note the ordering: we can safely lookup the task_rq without * explicitly disabling preemption. */ -static runqueue_t *task_rq_lock(task_t *p, unsigned long *flags) +OM_NSTATIC runqueue_t *task_rq_lock(task_t *p, unsigned long *flags) { struct runqueue *rq; @@ -274,7 +278,7 @@ return rq; } -static inline void task_rq_unlock(runqueue_t *rq, unsigned long *flags) +OM_NSTATIC inline void task_rq_unlock(runqueue_t *rq, unsigned long *flags) { spin_unlock_irqrestore(&rq->lock, *flags); } @@ -2241,6 +2245,14 @@ else deactivate_task(prev, rq); } +#ifdef CONFIG_OPENMOSIX + if (openmosix_events_need(prev)) + { + spin_unlock_irq(&rq->lock); + openmosix_events_run(prev); + spin_lock_irq(&rq->lock); + } +#endif /* CONFIG_OPENMOSIX */ cpu = smp_processor_id(); if (unlikely(!rq->nr_running)) { diff -Nur --exclude '*.orig' linux-2.6.7.org/kernel/signal.c linux-2.6.7/kernel/signal.c --- linux-2.6.7.org/kernel/signal.c 2004-09-02 14:42:25.397113072 +0200 +++ linux-2.6.7/kernel/signal.c 2004-09-02 14:46:54.641181752 +0200 @@ -184,7 +184,7 @@ * Re-calculate pending state from the set of locally pending * signals, globally pending signals, and blocked signals. */ -static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked) +OM_NSTATIC inline int has_pending_signals(sigset_t *signal, sigset_t *blocked) { unsigned long ready; long i; diff -Nur --exclude '*.orig' linux-2.6.7.org/kernel/timer.c linux-2.6.7/kernel/timer.c --- linux-2.6.7.org/kernel/timer.c 2004-09-02 14:42:22.281586704 +0200 +++ linux-2.6.7/kernel/timer.c 2004-09-02 14:46:54.644181296 +0200 @@ -38,6 +38,10 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include +#endif /* CONFIG_OPENMOSIX */ + /* * per-CPU timer vector definitions: */ diff -Nur --exclude '*.orig' linux-2.6.7.org/kernel/user.c linux-2.6.7/kernel/user.c --- linux-2.6.7.org/kernel/user.c 2004-09-02 14:42:17.286346096 +0200 +++ linux-2.6.7/kernel/user.c 2004-09-02 14:46:54.646180992 +0200 @@ -167,4 +167,29 @@ return 0; } +#ifdef CONFIG_OPENMOSIX +extern int max_threads; + +struct user_struct remote_guests = +{ + .__count = ATOMIC_INIT(1), + .processes = ATOMIC_INIT(1), + .files = ATOMIC_INIT(0) +}; + +int get_free_guest_slots(void) +{ + int a, b; + + write_lock_irq(&tasklist_lock); + a = max_threads / 6 - atomic_read(&remote_guests.__count); + b = max_threads - nr_threads; + write_unlock_irq(&tasklist_lock); + /* a little paranoid */ + if (a < 0) + a = 0; + return min(a, b); +} +#endif /* CONFIG_OPENMOSIX */ + module_init(uid_cache_init); diff -Nur --exclude '*.orig' linux-2.6.7.org/MAINTAINERS linux-2.6.7/MAINTAINERS --- linux-2.6.7.org/MAINTAINERS 2004-09-02 14:41:28.258799416 +0200 +++ linux-2.6.7/MAINTAINERS 2004-09-02 14:46:54.676176432 +0200 @@ -1561,6 +1561,15 @@ L: linux-scsi@vger.kernel.org S: Maintained +OPENMOSIX +P: Vincent Hanquez +M: tab@snarc.org +P: Alexander Nyberg +M: alexn@telia.com +L: openmosix-general@lists.sourceforge.net +W: http://openmosix.sourceforge.net/ +S: Maintained + OPL3-SA2, SA3, and SAx DRIVER P: Zwane Mwaikambo M: zwane@commfireservices.com diff -Nur --exclude '*.orig' linux-2.6.7.org/Makefile linux-2.6.7/Makefile --- linux-2.6.7.org/Makefile 2004-09-02 14:42:25.556088904 +0200 +++ linux-2.6.7/Makefile 2004-09-02 14:47:16.389875448 +0200 @@ -151,7 +151,7 @@ export srctree objtree VPATH TOPDIR -KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) +KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)-om # SUBARCH tells the usermode build what the underlying arch is. That is set # first, and if a usermode build is happening, the "ARCH=um" on the command @@ -488,7 +488,7 @@ ifeq ($(KBUILD_EXTMOD),) -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ grsecurity/ +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ grsecurity/ hpc/ vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ diff -Nur --exclude '*.orig' linux-2.6.7.org/mm/mlock.c linux-2.6.7/mm/mlock.c --- linux-2.6.7.org/mm/mlock.c 2004-09-02 14:42:22.289585488 +0200 +++ linux-2.6.7/mm/mlock.c 2004-09-02 14:48:47.742987664 +0200 @@ -8,6 +8,11 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include +#include +#endif /* CONFIG_OPENMOSIX */ + #include static int mlock_fixup(struct vm_area_struct * vma, @@ -125,6 +130,10 @@ gr_learn_resource(current, RLIMIT_MEMLOCK, locked, 1); if (locked <= lock_limit) error = do_mlock(start, len, 1); +#ifdef CONFIG_OPENMOSIX + if (!error) /* FIXME len == 0 shouldn't DSTAY MLOCK current & clones */ + stay_me_and_my_clones(DSTAY_FOR_MLOCK); +#endif /* CONFIG_OPENMOSIX */ up_write(¤t->mm->mmap_sem); return error; } @@ -138,6 +147,10 @@ start &= PAGE_MASK; ret = do_mlock(start, len, 0); up_write(¤t->mm->mmap_sem); +#ifdef CONFIG_OPENMOSIX + if (ret) + unstay_mm(current->mm); +#endif /* CONFIG_OPENMOSIX */ return ret; } @@ -188,6 +201,10 @@ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1); if (current->mm->total_vm <= lock_limit) ret = do_mlockall(flags); +#ifdef CONFIG_OPENMOSIX + if (!ret) + stay_me_and_my_clones(DSTAY_FOR_MLOCK); +#endif /* CONFIG_OPENMOSIX */ out: up_write(¤t->mm->mmap_sem); return ret; @@ -200,5 +217,9 @@ down_write(¤t->mm->mmap_sem); ret = do_mlockall(0); up_write(¤t->mm->mmap_sem); +#ifdef CONFIG_OPENMOSIX + if (ret) + unstay_mm(current->mm); +#endif /* CONFIG_OPENMOSIX */ return ret; } diff -Nur --exclude '*.orig' linux-2.6.7.org/mm/mmap.c linux-2.6.7/mm/mmap.c --- linux-2.6.7.org/mm/mmap.c 2004-09-02 14:42:22.294584728 +0200 +++ linux-2.6.7/mm/mmap.c 2004-09-02 14:46:54.723169288 +0200 @@ -29,6 +29,11 @@ #include #include +#ifdef CONFIG_OPENMOSIX +#include +#include +#endif /* CONFIG_OPENMOSIX */ + /* * WARNING: the debugging will use recursive algorithms so never enable this * unless you know what you are doing. @@ -78,10 +83,28 @@ flush_dcache_mmap_lock(mapping); if (unlikely(vma->vm_flags & VM_NONLINEAR)) + { list_del_init(&vma->shared.vm_set.list); +#ifdef CONFIG_OPENMOSIX + if (list_empty(&vma->shared.vm_set.list)) + openmosix_no_longer_monkey(file->f_dentry->d_inode); +#endif /* CONFIG_OPENMOSIX */ + } else + { vma_prio_tree_remove(vma, &mapping->i_mmap); +#ifdef CONFIG_OPENMOSIX + /* FIXME tab: maybe wrong ! */ + if (vma->shared.vm_set.parent && vma->shared.vm_set.head) + openmosix_no_longer_monkey(file->f_dentry->d_inode); +#endif /* CONFIG_OPENMOSIX */ + } flush_dcache_mmap_unlock(mapping); + +#ifdef CONFIG_OPENMOSIX + if (task_test_dflags(current, DSTAY_PER_MM)) + unstay_mm(current->mm); +#endif /* CONFIG_OPENMOSIX */ } /* @@ -751,6 +774,9 @@ struct rb_node ** rb_link, * rb_parent; int accountable = 1; unsigned long charged = 0; +#ifdef CONFIG_OPENMOSIX + int stay_reason = 0; +#endif /* CONFIG_OPENMOSIX */ if (file) { if (is_file_hugepages(file)) @@ -832,9 +858,19 @@ vm_flags |= VM_SHARED | VM_MAYSHARE; if (!(file->f_mode & FMODE_WRITE)) vm_flags &= ~(VM_MAYWRITE | VM_SHARED); +#ifdef CONFIG_OPENMOSIX + if (file->f_mode & FMODE_WRITE) + stay_reason |= DSTAY_FOR_MONKEY; +#endif /* CONFIG_OPENMOSIX */ /* fall through */ case MAP_PRIVATE: +#ifdef CONFIG_OPENMOSIX + if (inode && inode->i_mapping->i_mmap_writable != 0) + stay_reason |= DSTAY_FOR_MONKEY; + if (S_ISCHR(file->f_dentry->d_inode->i_mode)) + stay_reason |= DSTAY_FOR_DEV; +#endif /* CONFIG_OPENMOSIX */ if (!(file->f_mode & FMODE_READ)) return -EACCES; break; @@ -982,6 +1018,10 @@ mm->locked_vm += len >> PAGE_SHIFT; make_pages_present(addr, addr + len); } +#ifdef CONFIG_OPENMOSIX + if (stay_reason) + stay_me_and_my_clones(stay_reason); +#endif /* CONFIG_OPENMOSIX */ if (flags & MAP_POPULATE) { up_write(&mm->mmap_sem); sys_remap_file_pages(addr, len, 0,