diff --exclude=CVS -NBbwur linux-2.4.20/arch/i386/kernel/Makefile linux-2.4.20-aem-12r14/arch/i386/kernel/Makefile --- linux-2.4.20/arch/i386/kernel/Makefile Thu Nov 28 18:53:09 2002 +++ linux-2.4.20-aem-12r14/arch/i386/kernel/Makefile Tue Aug 12 15:13:28 2003 @@ -14,7 +14,11 @@ O_TARGET := kernel.o -export-objs := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o +export-objs := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o process.o i387.o + +ifdef CONFIG_SMP +export-objs += smp.o +endif obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \ diff --exclude=CVS -NBbwur linux-2.4.20/arch/i386/kernel/entry.S linux-2.4.20-aem-12r14/arch/i386/kernel/entry.S --- linux-2.4.20/arch/i386/kernel/entry.S Thu Nov 28 18:53:09 2002 +++ linux-2.4.20-aem-12r14/arch/i386/kernel/entry.S Tue Aug 12 15:13:28 2003 @@ -70,7 +70,11 @@ VM_MASK = 0x00020000 /* - * these are offsets into the task-struct. + * these are offsets into the task-struct. Other task struct + * members should be declare with decl_asm_symbol(). It + * generates an asm variable with the same name as the C member + * containing its offset in task_struct. + * */ state = 0 flags = 4 @@ -210,7 +214,14 @@ call *SYMBOL_NAME(sys_call_table)(,%eax,4) movl %eax,EAX(%esp) # save the return value ENTRY(ret_from_sys_call) + call SYMBOL_NAME(do_event) cli # need_resched and signals atomic test + pushl %eax + movl %ebx, %eax + addl keep_alive, %eax + cmpl $0,(%eax) + popl %eax + jne reschedule cmpl $0,need_resched(%ebx) jne reschedule cmpl $0,sigpending(%ebx) @@ -657,6 +668,11 @@ .long SYMBOL_NAME(sys_ni_syscall) /* 250 sys_alloc_hugepages */ .long SYMBOL_NAME(sys_ni_syscall) /* sys_free_hugepages */ .long SYMBOL_NAME(sys_ni_syscall) /* sys_exit_group */ + .long SYMBOL_NAME(sys_aem_evctl) + .long SYMBOL_NAME(sys_aem_entry) + .long SYMBOL_NAME(sys_aem_evreturn) /* 255 */ + .long SYMBOL_NAME(sys_aem_evshutdn) + .long SYMBOL_NAME(sys_aem_evkeepalive) .rept NR_syscalls-(.-sys_call_table)/4 .long SYMBOL_NAME(sys_ni_syscall) diff --exclude=CVS -NBbwur linux-2.4.20/arch/i386/kernel/i386_ksyms.c linux-2.4.20-aem-12r14/arch/i386/kernel/i386_ksyms.c --- linux-2.4.20/arch/i386/kernel/i386_ksyms.c Fri Aug 2 20:39:42 2002 +++ linux-2.4.20-aem-12r14/arch/i386/kernel/i386_ksyms.c Tue Aug 12 15:13:28 2003 @@ -29,6 +29,8 @@ #include #include +decl_asm_symbol (keep_alive); + extern void dump_thread(struct pt_regs *, struct user *); extern spinlock_t rtc_lock; diff --exclude=CVS -NBbwur linux-2.4.20/arch/i386/kernel/i387.c linux-2.4.20-aem-12r14/arch/i386/kernel/i387.c --- linux-2.4.20/arch/i386/kernel/i387.c Fri Aug 2 20:39:42 2002 +++ linux-2.4.20-aem-12r14/arch/i386/kernel/i387.c Tue Aug 12 15:13:28 2003 @@ -544,3 +544,8 @@ return fpvalid; } + +#include +EXPORT_SYMBOL(save_i387); +EXPORT_SYMBOL(restore_i387); + diff --exclude=CVS -NBbwur linux-2.4.20/arch/i386/kernel/process.c linux-2.4.20-aem-12r14/arch/i386/kernel/process.c --- linux-2.4.20/arch/i386/kernel/process.c Fri Aug 2 20:39:42 2002 +++ linux-2.4.20-aem-12r14/arch/i386/kernel/process.c Tue Aug 12 15:13:28 2003 @@ -824,3 +824,6 @@ } #undef last_sched #undef first_sched + +#include +EXPORT_SYMBOL(copy_thread); diff --exclude=CVS -NBbwur linux-2.4.20/arch/i386/kernel/signal.c linux-2.4.20-aem-12r14/arch/i386/kernel/signal.c --- linux-2.4.20/arch/i386/kernel/signal.c Fri Aug 2 20:39:42 2002 +++ linux-2.4.20-aem-12r14/arch/i386/kernel/signal.c Tue Aug 12 15:13:28 2003 @@ -269,6 +269,7 @@ if (restore_sigcontext(regs, &frame->sc, &eax)) goto badframe; + atomic_dec (¤t->execlvl); return eax; badframe: @@ -304,6 +305,7 @@ call it and ignore errors. */ do_sigaltstack(&st, NULL, regs->esp); + atomic_dec (¤t->execlvl); return eax; badframe: @@ -698,6 +700,7 @@ __asm__("movl %0,%%db7" : : "r" (current->thread.debugreg[7])); /* Whee! Actually deliver the signal. */ + atomic_inc (¤t->execlvl); handle_signal(signr, ka, &info, oldset, regs); return 1; } diff --exclude=CVS -NBbwur linux-2.4.20/arch/i386/kernel/smp.c linux-2.4.20-aem-12r14/arch/i386/kernel/smp.c --- linux-2.4.20/arch/i386/kernel/smp.c Thu Nov 28 18:53:09 2002 +++ linux-2.4.20-aem-12r14/arch/i386/kernel/smp.c Tue Aug 12 15:13:28 2003 @@ -626,3 +626,5 @@ } } +#include +EXPORT_SYMBOL(flush_tlb_mm); diff --exclude=CVS -NBbwur linux-2.4.20/fs/Makefile linux-2.4.20-aem-12r14/fs/Makefile --- linux-2.4.20/fs/Makefile Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/fs/Makefile Tue Aug 12 15:13:28 2003 @@ -7,7 +7,7 @@ O_TARGET := fs.o -export-objs := filesystems.o open.o dcache.o buffer.o +export-objs := filesystems.o open.o dcache.o buffer.o exec.o mod-subdirs := nls obj-y := open.o read_write.o devices.o file_table.o buffer.o \ diff --exclude=CVS -NBbwur linux-2.4.20/fs/exec.c linux-2.4.20-aem-12r14/fs/exec.c --- linux-2.4.20/fs/exec.c Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/fs/exec.c Tue Aug 12 15:13:28 2003 @@ -1000,3 +1000,5 @@ unlock_kernel(); return retval; } + +EXPORT_SYMBOL(put_dirty_page); diff --exclude=CVS -NBbwur linux-2.4.20/fs/open.c linux-2.4.20-aem-12r14/fs/open.c --- linux-2.4.20/fs/open.c Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/fs/open.c Tue Aug 12 15:13:28 2003 @@ -84,9 +84,9 @@ * will follow. */ -void fd_install(unsigned int fd, struct file * file) +void fd_install_task (struct task_struct *task, unsigned int fd, struct file *file) { - struct files_struct *files = current->files; + struct files_struct *files = task->files; write_lock(&files->file_lock); if (files->fd[fd]) @@ -95,6 +95,11 @@ write_unlock(&files->file_lock); } +void fd_install (unsigned int fd, struct file * file) +{ + fd_install_task (current, fd, file); +} + int do_truncate(struct dentry *dentry, loff_t length) { struct inode *inode = dentry->d_inode; diff --exclude=CVS -NBbwur linux-2.4.20/include/asm-i386/events.h linux-2.4.20-aem-12r14/include/asm-i386/events.h --- linux-2.4.20/include/asm-i386/events.h Wed Dec 31 19:00:00 1969 +++ linux-2.4.20-aem-12r14/include/asm-i386/events.h Tue Aug 12 15:17:32 2003 @@ -0,0 +1,143 @@ +/* ------------------------------------------------------------------------ + * + * file: include/asm/events.h + * + * Short description: + * + * ------------------------------------------------------------------------ + * + * Copyright (C) 2001, 2002, 2003 by + * Ericsson Research Canada + * 8400 Decarie Blvd + * Town of Mount Royal + * Quebec H4P 2N2 + * Tel: +1 514 345 7900 + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ------------------------------------------------------------------------ + * + * Created 2001/10/21 12:46:41 by lmcfros (Frederic.Rossi@Ericsson.CA) + * + * ------------------------------------------------------------------------ + * + * $Id: linux-2.4.20-aem-12r14.patch,v 1.1 2003/08/12 20:27:29 fjrossi Exp $ + * + * Revision history: + * ---------------- + * + * * 2001/10/21 - 2002/09/19 Frederic.Rossi@Ericsson.CA + * Initial Revision + * + * * 2003/07/30 + * Use an aligned ESP in get_frame() + * + * ------------------------------------------------------------------------ +*/ + +#ifndef _ASMi_EVENTS_H_ +#define _ASMi_EVENTS_H_ + +#define EVF_EXCL (1<<17) +#define EVF_ONESHOT (1<<18) +#define EVF_CLONE (1<<19) +#define EVF_FORK (1<<20) +#define EVF_NOCLDWAIT (1<<21) +#define EVF_CAPSULE (1<<22) +#define EVF_KEEPALIVE (1<<23) + +#define IRET_EXIT 0 +#define IRET_ASYNC 1 +#define IRET_KEEPALIVE 2 + +#include + +struct context_struct { + struct _fpstate *fpstate; + unsigned long cr2; + unsigned long eflags; + unsigned long trapno; + unsigned long err; + unsigned short gs; + unsigned short fs; + unsigned long eax; + void *ev; + struct pt_regs regs; +}; + +struct frame_struct +{ + char *bfp; + struct context_struct ctxt; + struct _fpstate fpstate; + char bf[8]; +}; + +#include + +struct event_struct +{ + jid_t jid; + + int limit; + + struct thread_struct ts; + struct pt_regs *regs; + + struct task_struct *root; /* task we belong to */ + + unsigned long hasync; /* job handler */ + + struct job_args *jargs; /* arguments for this job + constructor/destructor */ + unsigned long (*ja_cons)(struct job_args **, struct job_args *, void *); + unsigned long (*ja_dest)(struct event_struct *); + + void *hargs; /* arguments for this job's handler + constructor/destructor */ + unsigned long (*ha_cons)(struct task_struct *, struct event_struct *, struct frame_struct *); + unsigned long (*ha_dest)(struct event_struct *); + + spinlock_t lock; + + struct list_head sptr; /* siblings */ + struct list_head cptr; /* child */ + struct list_head dptr; /* direct child for cloner */ + struct list_head active; /* active list of events */ +}; + +#define COPY_REGS(src_regs,dst_regs) \ + (dst_regs)->ebx = (src_regs)->ebx; \ + (dst_regs)->ecx = (src_regs)->ecx; \ + (dst_regs)->edx = (src_regs)->edx; \ + (dst_regs)->esi = (src_regs)->esi; \ + (dst_regs)->edi = (src_regs)->edi; \ + (dst_regs)->ebp = (src_regs)->ebp; \ + (dst_regs)->eax = (src_regs)->eax; \ + (dst_regs)->xds = (src_regs)->xds; \ + (dst_regs)->xes = (src_regs)->xes; \ + (dst_regs)->orig_eax = (src_regs)->orig_eax;\ + (dst_regs)->eip = (src_regs)->eip; \ + (dst_regs)->xcs = (src_regs)->xcs; \ + (dst_regs)->eflags = (src_regs)->eflags; \ + (dst_regs)->esp = (src_regs)->esp; \ + (dst_regs)->xss = (src_regs)->xss; + + +static __inline__ void *get_frame (struct pt_regs *regs, size_t frame_size) +{ + return (void *)((regs->esp & -8ul) - frame_size); +} + +#endif /* #ifndef _ASMi_EVENTS_H_ */ + diff --exclude=CVS -NBbwur linux-2.4.20/include/asm-i386/job.h linux-2.4.20-aem-12r14/include/asm-i386/job.h --- linux-2.4.20/include/asm-i386/job.h Wed Dec 31 19:00:00 1969 +++ linux-2.4.20-aem-12r14/include/asm-i386/job.h Tue Aug 12 15:18:06 2003 @@ -0,0 +1,132 @@ +/* ------------------------------------------------------------------------ + * + * file: include/asm/job.h + * + * Short description: + * + * ------------------------------------------------------------------------ + * + * Copyright (C) 2001, 2002, 2003 by + * Ericsson Research Canada + * 8400 Decarie Blvd + * Town of Mount Royal + * Quebec H4P 2N2 + * Tel: +1 514 345 7900 + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ------------------------------------------------------------------------ + * + * Created 2001/08/10 17:26:06 by lmcfros (Frederic.Rossi@Ericsson.CA) + * + * ------------------------------------------------------------------------ + * + * $Id: linux-2.4.20-aem-12r14.patch,v 1.1 2003/08/12 20:27:29 fjrossi Exp $ + * + * Revision history: + * ---------------- + * + * * 2001/08/10 - 2002/09/16 Frederic.Rossi@Ericsson.CA + * Initial Revision + * + * + * ------------------------------------------------------------------------ +*/ + +#ifndef _ASM_JOB_H_ +#define _ASM_JOB_H_ + +/* + * This file should belong to but has been split + * dut to an SMP chicken and egg compilation issue (caused by the + * tasklet definition precedence in interrupt.h) + */ + +#include +#include +#include +#include + +struct job_args { + struct task_struct *task; + struct event_struct *ev; + unsigned long flags; + + void *data; +}; + +struct job_struct { + struct list_head list; + struct list_head dlist; + struct list_head hash; + struct list_head wq; + + struct tasklet_struct job; + struct job_struct *this; + + unsigned long timeout; + + rwlock_t lock; + + int state; + int limit; + + unsigned char shutdown; + + unsigned long ctime; /* creation time */ + unsigned long age; + unsigned long freq; /* frequency */ + + unsigned long wstate; /* waiting condition */ + unsigned char priority; + + struct list_head task_list; + + jid_t id; +}; + +/* + * add a job to a waitqueue and suspend it. + */ +#define job_suspend_interruptible(job,waitq,lck) \ +do { \ + wlock_job (job); \ + \ + switch ((job)->state) { \ + case JOB_SUSPENDED_NONBLOCK: \ + goto restart; \ + case JOB_SUSPENDED_BLOCK: \ + wunlock_job (job); \ + return; \ + } \ + \ + __job_suspend ((job)); \ + \ + spin_lock (lck); \ + wq_add_job ((waitq), (job)); \ + spin_unlock (lck); \ + \ + wunlock_job (job); \ + return; \ + \ +restart: \ + spin_lock (lck); \ + wq_del_job ((waitq), (job)); \ + spin_unlock (lck); \ + \ + wunlock_job (job); \ +} while (0) + +#endif /* #ifndef _ASM_JOB_H_ */ diff --exclude=CVS -NBbwur linux-2.4.20/include/asm-i386/unistd.h linux-2.4.20-aem-12r14/include/asm-i386/unistd.h --- linux-2.4.20/include/asm-i386/unistd.h Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/include/asm-i386/unistd.h Tue Aug 12 15:13:28 2003 @@ -257,6 +257,11 @@ #define __NR_alloc_hugepages 250 #define __NR_free_hugepages 251 #define __NR_exit_group 252 +#define __NR_aem_evctl 253 +#define __NR_aem_entry 254 +#define __NR_aem_evreturn 255 +#define __NR_aem_evshutdn 256 +#define __NR_aem_evkeepalive 257 /* user-visible error numbers are in the range -1 - -124: see */ diff --exclude=CVS -NBbwur linux-2.4.20/include/linux/file.h linux-2.4.20-aem-12r14/include/linux/file.h --- linux-2.4.20/include/linux/file.h Fri Aug 2 20:39:45 2002 +++ linux-2.4.20-aem-12r14/include/linux/file.h Tue Aug 12 15:13:28 2003 @@ -62,15 +62,20 @@ files->next_fd = fd; } -static inline void put_unused_fd(unsigned int fd) +static inline void put_unused_fd_task (struct task_struct *task, unsigned int fd) { - struct files_struct *files = current->files; + struct files_struct *files = task->files; write_lock(&files->file_lock); __put_unused_fd(files, fd); write_unlock(&files->file_lock); } +static inline void put_unused_fd (unsigned int fd) +{ + put_unused_fd_task (current, fd); +} + void fd_install(unsigned int fd, struct file * file); void put_files_struct(struct files_struct *fs); diff --exclude=CVS -NBbwur linux-2.4.20/include/linux/job.h linux-2.4.20-aem-12r14/include/linux/job.h --- linux-2.4.20/include/linux/job.h Wed Dec 31 19:00:00 1969 +++ linux-2.4.20-aem-12r14/include/linux/job.h Tue Aug 12 15:17:29 2003 @@ -0,0 +1,202 @@ + +/* ------------------------------------------------------------------------ + * + * file: include/linux/job.h + * + * Short description: + * + * ------------------------------------------------------------------------ + * + * Copyright (C) 2001, 2002, 2003 by + * Ericsson Research Canada + * 8400 Decarie Blvd + * Town of Mount Royal + * Quebec H4P 2N2 + * Tel: +1 514 345 7900 + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ------------------------------------------------------------------------ + * + * Created 2001/08/10 17:26:06 by lmcfros (Frederic.Rossi@Ericsson.CA) + * + * ------------------------------------------------------------------------ + * + * $Id: linux-2.4.20-aem-12r14.patch,v 1.1 2003/08/12 20:27:29 fjrossi Exp $ + * + * Revision history: + * ---------------- + * + * * 2001/08/10 - 2002/09/16 Frederic.Rossi@Ericsson.CA + * Initial Revision + * + * + * ------------------------------------------------------------------------ +*/ + +#ifndef _JOB_H_ +#define _JOB_H_ + +#include +#include + +#define wlock_job(j) do{ write_lock_bh (&(j)->lock); } while (0) +#define rlock_job(j) do{ read_lock_bh (&(j)->lock); } while (0) +#define simple_wlock_job(j) do{ write_lock (&(j)->lock); } while (0) +#define simple_rlock_job(j) do{ read_lock (&(j)->lock); } while (0) + +#define wunlock_job(j) do{ write_unlock_bh (&(j)->lock); } while (0) +#define runlock_job(j) do{ read_unlock_bh (&(j)->lock); } while (0) +#define simple_wunlock_job(j) do{ write_unlock (&(j)->lock); } while (0) +#define simple_runlock_job(j) do{ read_unlock (&(j)->lock); } while (0) + +#define local_job_enable() local_bh_enable() +#define local_job_disable() local_bh_disable() + +#define runnable(j) ((atomic_read (&(j)->job.count)>=1)? 0 : 1) +#define __prepare_to_run(j) atomic_dec (&(j)->job.count) +#define __prepare_to_stop(j) atomic_inc (&(j)->job.count) +#define prepare_to_run(j) do { local_bh_disable () ; __prepare_to_run (j) ; local_bh_enable (); } while (0) +#define prepare_to_stop(j) do { local_bh_disable () ; __prepare_to_stop (j) ; local_bh_enable (); } while (0) + +#define __job_limit_inc(j) \ +do { \ + if ((j)->limit>JOB_SCHED_NO_SCHED) \ + (j)->limit++; \ +} while (0) + +#define __job_limit_dec(j) \ +do { \ + if ((j)->limit>JOB_SCHED_NO_SCHED) \ + (j)->limit--; \ +} while (0) + +#define __job_desactivate(j) \ +do { \ + if (runnable (j)) \ + __prepare_to_stop (j); \ +} while (0) + +#define __do_job_activate(j) \ +do { \ + if (!runnable (j)) \ + __prepare_to_run (j); \ + \ + __job_limit_dec (j); \ + tasklet_schedule (&(j)->job); \ +} while (0) + +#define __job_activate(j) \ +do { \ + switch ((j)->state) { \ + case JOB_SUSPENDED_BLOCK: \ + (j)->state = JOB_SUSPENDED_NONBLOCK; \ + __do_job_activate (j); \ + break; \ + case JOB_DISABLED: \ + (j)->state = JOB_ENABLED; \ + __do_job_activate (j); \ + break; \ + default: \ + break; \ + } \ +} while (0) + +typedef void (*job_t)(unsigned long); +typedef unsigned long job_arg_t; +typedef int jid_t; + +struct __wq_job { + rwlock_t lock; + struct job_struct *job; + struct list_head list; +}; +typedef struct __wq_job wq_job_t; + +struct __wq_job_head { + rwlock_t lock; + struct job_struct *job; + struct list_head list; + unsigned int len; +}; +typedef struct __wq_job_head wq_job_head_t; + +/* flags */ +#define JOB_STATE_RUN 0 +#define JOB_STATE_SCHED 1 + +/* job priorities */ +enum { + JOB_BACKGROUND=1, + JOB_LOW, + JOB_NORMAL, + JOB_HIGH +}; + +/* job states */ +enum { + JOB_FREE=0, + JOB_ENABLED, + JOB_SCHED, + JOB_DISABLED, + JOB_SUSPENDED_BLOCK, /* keep these two at the end */ + JOB_SUSPENDED_NONBLOCK, /* */ +}; + +/* job limits */ +enum { + JOB_SCHED_ERR = -2, + JOB_SCHED_NO_LIMIT = -1, + JOB_SCHED_NO_SCHED = 0 +}; + +/* job shutdown state */ +enum { + JOB_SHUTDOWN_INIT = 0, + JOB_SHUTDOWN = 1 +}; + +#include + +static __inline__ unsigned int wq_empty (wq_job_head_t *wq) +{ + return wq->len == 0; +} + +void wq_add_job (wq_job_head_t *, struct job_struct *); +void wq_del_job (wq_job_head_t *, struct job_struct *); + +static __inline__ void wq_job_head_init (wq_job_head_t *wq) +{ + wq->len = 0; + wq->lock = RW_LOCK_UNLOCKED; + wq->job = NULL; + INIT_LIST_HEAD (&wq->list); +} + +static __inline__ void wq_job_init (wq_job_t *wq) +{ + wq->lock = RW_LOCK_UNLOCKED; + wq->job = NULL; + INIT_LIST_HEAD (&wq->list); +} + +void job_wake_up_common (wq_job_head_t *, unsigned int, unsigned long); + +#define job_wake_up(wq) job_wake_up_common (wq, 0, 0) +#define job_wake_up_cond(wq,cond) job_wake_up_common (wq, 1, cond) +#define job_wake_up_excl(wq,excl) job_wake_up_common (wq, 2, excl) + +#endif /* #ifndef _JOB_H_ */ diff --exclude=CVS -NBbwur linux-2.4.20/include/linux/kernel_stat.h linux-2.4.20-aem-12r14/include/linux/kernel_stat.h --- linux-2.4.20/include/linux/kernel_stat.h Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/include/linux/kernel_stat.h Tue Aug 12 15:17:29 2003 @@ -32,6 +32,7 @@ unsigned int irqs[NR_CPUS][NR_IRQS]; #endif unsigned int context_swtch; + unsigned int event_rt; }; extern struct kernel_stat kstat; diff --exclude=CVS -NBbwur linux-2.4.20/include/linux/net.h linux-2.4.20-aem-12r14/include/linux/net.h --- linux-2.4.20/include/linux/net.h Thu Nov 22 14:46:19 2001 +++ linux-2.4.20-aem-12r14/include/linux/net.h Tue Aug 12 15:17:29 2003 @@ -61,6 +61,9 @@ #define SOCK_ASYNC_NOSPACE 0 #define SOCK_ASYNC_WAITDATA 1 #define SOCK_NOSPACE 2 +#define SOCK_SOCKASYNC 3 + +#include struct socket { @@ -73,7 +76,8 @@ struct file *file; /* File back pointer for gc */ struct sock *sk; wait_queue_head_t wait; - + wq_job_head_t jwq_read; /* job wait queue for read operations */ + wq_job_head_t jwq_close; /* job wait queue for close operations */ short type; unsigned char passcred; }; diff --exclude=CVS -NBbwur linux-2.4.20/include/linux/sched.h linux-2.4.20-aem-12r14/include/linux/sched.h --- linux-2.4.20/include/linux/sched.h Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/include/linux/sched.h Tue Aug 12 15:17:29 2003 @@ -27,6 +27,8 @@ #include #include +#include + struct exec_domain; /* @@ -43,6 +45,7 @@ #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */ #define CLONE_THREAD 0x00010000 /* Same thread group? */ #define CLONE_NEWNS 0x00020000 /* New namespace group? */ +#define CLONE_EVENTS 0x10000000 #define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD) @@ -418,6 +421,19 @@ /* journalling filesystem info */ void *journal_info; + +/* events handler */ + struct list_head active; /* active list of event */ + struct list_head events; /* event list */ + struct event_struct *cloner; /* event that created us */ + spinlock_t evlock; + unsigned long srt_priority; /* soft realtime priority */ + atomic_t execlvl; + int keep_alive; + unsigned long ka_relax; + +/* memory management per process */ + struct table_struct vmtable; }; /* @@ -466,6 +482,15 @@ extern struct exec_domain default_exec_domain; /* + * Define symbol names to use in the assembler code. + */ +#define task_entry(__entry) (unsigned long)(&((struct task_struct *)0)->__entry) +#define ASM_SYMBOL(__sym, __asm) unsigned long asm_##__sym asm(__asm) = task_entry(__sym) +#define __SYMBOL_STR(x) #x +#define SYMBOL_STR(x) __SYMBOL_STR(x) +#define decl_asm_symbol(sym) ASM_SYMBOL(sym,SYMBOL_STR(sym)) + +/* * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB) */ @@ -510,6 +535,15 @@ blocked: {{0}}, \ alloc_lock: SPIN_LOCK_UNLOCKED, \ journal_info: NULL, \ + events: LIST_HEAD_INIT(tsk.events), \ + active: LIST_HEAD_INIT(tsk.active), \ + cloner: NULL, \ + evlock: SPIN_LOCK_UNLOCKED, \ + srt_priority: 0, \ + execlvl: ATOMIC_INIT(0), \ + keep_alive: 0, \ + ka_relax: 0, \ + vmtable: INIT_TABLE, \ } @@ -792,6 +826,7 @@ extern void exit_mm(struct task_struct *); extern void exit_files(struct task_struct *); extern void exit_sighand(struct task_struct *); +extern void exit_events (struct task_struct *, int); extern void reparent_to_init(void); extern void daemonize(void); diff --exclude=CVS -NBbwur linux-2.4.20/include/linux/sys.h linux-2.4.20-aem-12r14/include/linux/sys.h --- linux-2.4.20/include/linux/sys.h Sun Dec 10 23:56:37 1995 +++ linux-2.4.20-aem-12r14/include/linux/sys.h Tue Aug 12 15:13:28 2003 @@ -4,7 +4,7 @@ /* * system call entry points ... but not all are defined */ -#define NR_syscalls 256 +#define NR_syscalls 258 /* * These are system calls that will be removed at some time diff --exclude=CVS -NBbwur linux-2.4.20/include/linux/vmtables.h linux-2.4.20-aem-12r14/include/linux/vmtables.h --- linux-2.4.20/include/linux/vmtables.h Wed Dec 31 19:00:00 1969 +++ linux-2.4.20-aem-12r14/include/linux/vmtables.h Tue Aug 12 15:13:28 2003 @@ -0,0 +1,133 @@ +/* ------------------------------------------------------------------------ + * + * file: include/linux/vmtables.h + * + * Short description: + * + * ------------------------------------------------------------------------ + * + * Copyright (C) 2001, 2002, 2003 by + * Ericsson Research Canada + * 8400 Decarie Blvd + * Town of Mount Royal + * Quebec H4P 2N2 + * Tel: +1 514 345 7900 + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ------------------------------------------------------------------------ + * + * Created 2002/06/18 01:34:22 by lmcfros (Frederic.Rossi@Ericsson.CA) + * + * ------------------------------------------------------------------------ + * + * $Id: linux-2.4.20-aem-12r14.patch,v 1.1 2003/08/12 20:27:29 fjrossi Exp $ + * + * Revision history: + * ---------------- + * + * * 2002/06/18 - 2002/09/11 Frederic.Rossi@Ericsson.CA + * Initial Revision + * + * + * ------------------------------------------------------------------------ +*/ + +#ifndef _VMTABLES_H_ +#define _VMTABLES_H_ + +#define TBL_UZONE 0 +#define TBL_VZONE 1 + +#define MMTABLE_SZ 15 + +#define INIT_TABLE {\ + vm_init: ATOMIC_INIT(0),\ + vm_base: 0,\ + vm_size: ((1< #include +#include /* The AF_UNIX specific socket options */ struct unix_opt { @@ -410,6 +411,7 @@ /* FIFO of established children */ struct open_request *accept_queue; struct open_request *accept_queue_tail; + wq_job_head_t jwq_accept; int write_pending; /* A write to socket waits to start. */ @@ -513,6 +515,10 @@ int rcvbuf; /* Size of receive buffer in bytes */ wait_queue_head_t *sleep; /* Sock wait queue */ + + wq_job_head_t *wrq; /* jobs waiting on this socket receive queue */ + wq_job_head_t *wclose; /* jobs waiting on this socket state for closing */ + struct dst_entry *dst_cache; /* Destination cache */ rwlock_t dst_lock; atomic_t rmem_alloc; /* Receive queue bytes committed */ @@ -1005,6 +1011,8 @@ sk->dead = 1; sk->socket = NULL; sk->sleep = NULL; + sk->wrq = NULL; + sk->wclose = NULL; write_unlock_bh(&sk->callback_lock); } @@ -1012,6 +1020,8 @@ { write_lock_bh(&sk->callback_lock); sk->sleep = &parent->wait; + sk->wrq = &parent->jwq_read; + sk->wclose = &parent->jwq_close; parent->sk = sk; sk->socket = parent; write_unlock_bh(&sk->callback_lock); diff --exclude=CVS -NBbwur linux-2.4.20/include/net/tcp.h linux-2.4.20-aem-12r14/include/net/tcp.h --- linux-2.4.20/include/net/tcp.h Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/include/net/tcp.h Tue Aug 12 15:26:18 2003 @@ -30,6 +30,7 @@ #include #include #include +#include /* This is for all connections with a full identity, no wildcards. * New scheme, half the table is for TIME_WAIT, the other half is @@ -1579,6 +1580,7 @@ req->sk = child; tcp_acceptq_added(sk); + job_wake_up (&tp->jwq_accept); if (!tp->accept_queue_tail) { tp->accept_queue = req; diff --exclude=CVS -NBbwur linux-2.4.20/kernel/Makefile linux-2.4.20-aem-12r14/kernel/Makefile --- linux-2.4.20/kernel/Makefile Mon Sep 17 00:22:40 2001 +++ linux-2.4.20-aem-12r14/kernel/Makefile Tue Aug 12 15:13:29 2003 @@ -9,12 +9,12 @@ O_TARGET := kernel.o -export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o +export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o events.o exit.o fork.o itimer.o user.o job.o obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \ module.o exit.o itimer.o info.o time.o softirq.o resource.o \ sysctl.o acct.o capability.o ptrace.o timer.o user.o \ - signal.o sys.o kmod.o context.o + signal.o sys.o kmod.o context.o events.o job.o obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += ksyms.o diff --exclude=CVS -NBbwur linux-2.4.20/kernel/events.c linux-2.4.20-aem-12r14/kernel/events.c --- linux-2.4.20/kernel/events.c Wed Dec 31 19:00:00 1969 +++ linux-2.4.20-aem-12r14/kernel/events.c Tue Aug 12 15:13:29 2003 @@ -0,0 +1,342 @@ +/* + * file: kernel/events.c + * + * Short description: + * + * ------------------------------------------------------------------------ + * + * Copyright (C) 2001, 2002, 2003 by + * Ericsson Research Canada + * 8400 Decarie Blvd + * Town of Mount Royal + * Quebec H4P 2N2 + * Tel: +1 514 345 7900 + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ------------------------------------------------------------------------ + * + * Created 2001/9/10 10:10:34 by lmcfros (Frederic.Rossi@Ericsson.CA) + * + * ------------------------------------------------------------------------ + * + * $Id: linux-2.4.20-aem-12r14.patch,v 1.1 2003/08/12 20:27:29 fjrossi Exp $ + * + * Revision history: + * ---------------- + * + * * 2001/9/10 - 2002/09/23 Frederic.Rossi@Ericsson.CA + * Initial revision + * + * * 2003/02/05 Frederic.Rossi@Ericsson.CA + * + Fixed do_event. Do not restart a job if the event is shutting down. + * (used to provoked many occurances of the same event in the case of event processes). + * + Now we test before starting the event if the job has been marked has shutting down. + * + Fixed forget_child. For some reason the (new) parent wont start. + * + Minor fixes. + * + * * 2003/02/25 Frederic.Rossi@Ericsson.CA + * + EVJOBSTART/EVJOBSTOP: start/stop jobs from user space + * + EVJOBSHTDN: shutdn one or more jobs from user space + * + * ------------------------------------------------------------------------ +*/ + +#define __KERNEL_SYSCALLS__ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _EXIT_SIGS_ (sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGKILL) | sigmask(SIGTERM)) + +struct task_struct *capm = &init_task; + +#define logm(format,args...) +//#define logm printk + +/* + * AEM generic system call convention + * ebx = event call number + * ecx = event call arguments + */ +static __inline__ int aem_noentry (int sys_nr, void *args) +{ + return -ENOSYS; +} +int (*aem_entry_pfn)(int, void *) = aem_noentry; + +static __inline__ int aem_nosys1 (void *args) +{ + return -ENOSYS; +} + +static __inline__ int aem_nosys2 (void *args, void *args2) +{ + return -ENOSYS; +} + +static __inline__ int aem_nosys3 (void *args, void *args2, void *arg3) +{ + return -ENOSYS; +} + +static int aem_copy_events_default (int flags, struct task_struct *task, long eax) +{ + INIT_LIST_HEAD (&task->events); + INIT_LIST_HEAD (&task->active); + + task->evlock = SPIN_LOCK_UNLOCKED; + task->keep_alive = 0; + task->ka_relax = 0; + + atomic_set (&task->execlvl, 0); + + task->cloner = NULL; + task->srt_priority = 0; + + return 0; +} + +static int aem_copy_vmt_default (int clone_flags, struct task_struct *task) +{ + atomic_set (&task->vmtable.vm_init, 0); + task->vmtable.vm_base = 0; + task->vmtable.vm_size = 0; + + return 0; +} + +/* + * Default settings + */ +int (*aem_handle_event_pfn)(void *) = aem_nosys1; +int (*aem_copy_events_pfn)(int, struct task_struct *, long) = aem_copy_events_default; +int (*aem_copy_vmt_pfn)(int, struct task_struct *) = aem_copy_vmt_default; +int (*aem_vmtable_shutdn_pfn)(void *) = aem_nosys1; +int (*aem_vmtable_start_pfn)(void *, void *) = aem_nosys2; +int (*aem_do_event_pfn)(void *) = aem_nosys1; +int (*aem_evctl_pfn)(void *, void *, void *) = aem_nosys3; +int (*aem_exit_events_pfn)(void *, void *) = aem_nosys2; +int (*aem_cleanup_events_pfn)(void *) = aem_nosys1; + +asmlinkage int sys_aem_evshutdn (unsigned long __unused) +{ + do_exit (0); +} + +asmlinkage int sys_aem_entry (struct pt_regs regs) +{ + return aem_entry_pfn ((int )regs.ebx, (void *)regs.ecx); +} + +asmlinkage void do_event (struct pt_regs regs) +{ + aem_do_event_pfn (®s); +} + +asmlinkage unsigned long sys_aem_evctl (jid_t jid, unsigned int opt, unsigned long args) +{ + return (unsigned long)aem_evctl_pfn ((void *)jid, (void *)opt, (void *)args); +} + +void exit_events (struct task_struct *task, int exit_code) +{ + aem_exit_events_pfn ((void *)task, (void *)exit_code); +} + +void aem_entry_reset (void) +{ + aem_entry_pfn = aem_noentry; + + aem_handle_event_pfn = aem_nosys1; + aem_copy_events_pfn = aem_copy_events_default; + aem_copy_vmt_pfn = aem_copy_vmt_default; + aem_vmtable_shutdn_pfn = aem_nosys1; + aem_vmtable_start_pfn = aem_nosys2; + aem_do_event_pfn = aem_nosys1; + aem_cleanup_events_pfn = aem_nosys1; + aem_exit_events_pfn = aem_nosys2; + aem_evctl_pfn = aem_nosys3; +} + +#define KA_EIP 7 +#define KA_RELAX (5*HZ) + +static __inline__ int __enter_keepalive (struct pt_regs *regs) +{ + current->keep_alive = 0; + + if (current->sigpending) + return 0; + + regs->eip -= KA_EIP; + + current->keep_alive = 1; + if ((jiffies - current->ka_relax) > KA_RELAX) { + + current->state = TASK_INTERRUPTIBLE; + schedule_timeout (1); + current->state = TASK_RUNNING; + current->keep_alive = 0; + } + + return 0; +} + +asmlinkage int sys_aem_evkeepalive (struct pt_regs regs) +{ + return __enter_keepalive (®s); +} + +static int restore_context (struct pt_regs *regs, struct frame_struct *frame, int *peax, struct event_struct **ev) +{ + unsigned int err = 0; + unsigned int eflags; + struct context_struct *ctxt = &frame->ctxt; + struct _fpstate *fp; + + COPY_REGS (&ctxt->regs, regs); + + if (ev) err |= __get_user (*ev, &ctxt->ev); + + err |= __get_user (current->thread.trap_no, &ctxt->trapno); + err |= __get_user (current->thread.error_code, &ctxt->err); + err |= __get_user (current->thread.cr2, &ctxt->cr2); + + err |= __get_user (fp, &ctxt->fpstate); + if (fp) err |= restore_i387 (fp); + + err |= __get_user (eflags, &ctxt->eflags); + regs->eflags &= ~0x40DD5; + regs->eflags |= eflags & 0x40DD5; + + err |= __get_user (*peax, &ctxt->regs.eax); + regs->orig_eax = *peax; + + return err; +} + +asmlinkage int sys_aem_evreturn (unsigned long __unused) +{ + struct pt_regs *regs = (struct pt_regs *) &__unused; + struct frame_struct *frame; + struct event_struct *ev; + unsigned long *bfp; + int eax; + + bfp = (unsigned long *)(regs->esp - 8); + frame = (struct frame_struct *)(*bfp - sizeof (struct frame_struct) + 8); + + if (!access_ok (VERIFY_READ, frame, sizeof (*frame))) + goto error; + + if (restore_context (regs, frame, &eax, &ev)) + goto error; + + aem_cleanup_events_pfn (ev); + + return eax; + +error: + printk ("sys_eventreturn: segmentation violation calling eip=%p for process '%s' (pid=%d)\n", + (ulong *)regs->eip, current->comm, current->pid); + force_sig (SIGSEGV, current); + return 0; +} + +/* + * Scheduler entry for AEM + */ + +static __inline__ long aem_schedadv_noentry (struct task_struct *task) +{ + return 0; +} +long (*aem_schedadv_entry_pfn)(struct task_struct *) = aem_schedadv_noentry; + +long aem_schedadv_entry (struct task_struct *task) +{ + return aem_schedadv_entry_pfn (task); +} + +void aem_schedadv_entry_reset (void) +{ + spin_lock_irq (&runqueue_lock); + aem_schedadv_entry_pfn = aem_schedadv_noentry; + spin_unlock_irq (&runqueue_lock); +} + +/**/ + +static __inline__ long aem_schedcnt_noentry (struct task_struct *task) +{ + return 0; +} +long (*aem_schedcnt_entry_pfn)(struct task_struct *) = aem_schedcnt_noentry; + +long aem_schedcnt_entry (struct task_struct *task) +{ + return aem_schedcnt_entry_pfn (task); +} + +void aem_schedcnt_entry_reset (void) +{ + spin_lock_irq (&runqueue_lock); + aem_schedcnt_entry_pfn = aem_schedcnt_noentry; + spin_unlock_irq (&runqueue_lock); +} + +EXPORT_SYMBOL(aem_entry_reset); +EXPORT_SYMBOL(aem_entry_pfn); + +EXPORT_SYMBOL(aem_handle_event_pfn); +EXPORT_SYMBOL(aem_copy_events_pfn); +EXPORT_SYMBOL(aem_copy_vmt_pfn); +EXPORT_SYMBOL(aem_vmtable_start_pfn); +EXPORT_SYMBOL(aem_vmtable_shutdn_pfn); +EXPORT_SYMBOL(aem_do_event_pfn); +EXPORT_SYMBOL(aem_exit_events_pfn); +EXPORT_SYMBOL(aem_evctl_pfn); +EXPORT_SYMBOL(aem_cleanup_events_pfn); + +EXPORT_SYMBOL(aem_schedadv_entry_reset); +EXPORT_SYMBOL(aem_schedadv_entry_pfn); +EXPORT_SYMBOL(aem_schedcnt_entry_reset); +EXPORT_SYMBOL(aem_schedcnt_entry_pfn); +EXPORT_SYMBOL(runqueue_lock); +EXPORT_SYMBOL(errno); + +EXPORT_SYMBOL(capm); diff --exclude=CVS -NBbwur linux-2.4.20/kernel/exec_domain.c linux-2.4.20-aem-12r14/kernel/exec_domain.c --- linux-2.4.20/kernel/exec_domain.c Mon Feb 25 14:38:13 2002 +++ linux-2.4.20-aem-12r14/kernel/exec_domain.c Tue Aug 12 15:13:29 2003 @@ -290,3 +290,5 @@ EXPORT_SYMBOL(abi_defhandler_libcso); EXPORT_SYMBOL(abi_traceflg); EXPORT_SYMBOL(abi_fake_utsname); + +EXPORT_SYMBOL(default_exec_domain); diff --exclude=CVS -NBbwur linux-2.4.20/kernel/exit.c linux-2.4.20-aem-12r14/kernel/exit.c --- linux-2.4.20/kernel/exit.c Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/kernel/exit.c Tue Aug 12 15:13:29 2003 @@ -435,6 +435,8 @@ tsk->flags |= PF_EXITING; del_timer_sync(&tsk->real_timer); + exit_events (tsk, code); + fake_volatile: #ifdef CONFIG_BSD_PROCESS_ACCT acct_process(code); @@ -599,3 +601,5 @@ } #endif + +EXPORT_SYMBOL(do_exit); diff --exclude=CVS -NBbwur linux-2.4.20/kernel/fork.c linux-2.4.20-aem-12r14/kernel/fork.c --- linux-2.4.20/kernel/fork.c Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/kernel/fork.c Tue Aug 12 15:13:29 2003 @@ -28,6 +28,8 @@ #include #include +#include + /* The idle threads do not count.. */ int nr_threads; int nr_running; @@ -83,7 +85,7 @@ /* Protects next_safe and last_pid. */ spinlock_t lastpid_lock = SPIN_LOCK_UNLOCKED; -static int get_pid(unsigned long flags) +int get_pid(unsigned long flags) { static int next_safe = PID_MAX; struct task_struct *p; @@ -311,7 +313,7 @@ } } -static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) +int copy_mm(unsigned long clone_flags, struct task_struct * tsk) { struct mm_struct * mm, *oldmm; int retval; @@ -565,6 +567,9 @@ p->flags = new_flags; } +extern int (*aem_copy_events_pfn)(int, struct task_struct *, long); +extern int (*aem_copy_vmt_pfn)(int, struct task_struct *); + /* * Ok, this is the main fork-routine. It copies the system process * information (task[nr]) and sets up the necessary registers. It also @@ -602,6 +607,9 @@ *p = *current; + p->srt_priority = 0; + aem_copy_events_pfn (clone_flags, p, regs->eax); + retval = -EAGAIN; /* * Check if we are over our maximum process limit, but be sure to @@ -695,6 +703,9 @@ goto bad_fork_cleanup_namespace; p->semundo = NULL; + if (aem_copy_vmt_pfn (clone_flags, p)) + goto bad_fork_cleanup_mm; + /* Our parent execution domain becomes current domain These must match for thread signalling to apply */ @@ -751,7 +762,9 @@ if (p->ptrace & PT_PTRACED) send_sig(SIGSTOP, p, 1); + if (!(clone_flags & CLONE_EVENTS)) wake_up_process(p); /* do this last */ + ++total_forks; if (clone_flags & CLONE_VFORK) wait_for_completion(&vfork); @@ -828,3 +841,12 @@ if(!mm_cachep) panic("vma_init: Cannot alloc mm_struct SLAB cache"); } + +EXPORT_SYMBOL(do_fork); +EXPORT_SYMBOL(get_pid); +EXPORT_SYMBOL(total_forks); +EXPORT_SYMBOL(nr_threads); +EXPORT_SYMBOL(vm_area_cachep); +EXPORT_SYMBOL(files_cachep); +EXPORT_SYMBOL(sigact_cachep); +EXPORT_SYMBOL(copy_mm); diff --exclude=CVS -NBbwur linux-2.4.20/kernel/itimer.c linux-2.4.20-aem-12r14/kernel/itimer.c --- linux-2.4.20/kernel/itimer.c Thu Jun 29 13:07:36 2000 +++ linux-2.4.20-aem-12r14/kernel/itimer.c Tue Aug 12 15:13:29 2003 @@ -168,3 +168,6 @@ return -EFAULT; return 0; } + +#include +EXPORT_SYMBOL(it_real_fn); diff --exclude=CVS -NBbwur linux-2.4.20/kernel/job.c linux-2.4.20-aem-12r14/kernel/job.c --- linux-2.4.20/kernel/job.c Wed Dec 31 19:00:00 1969 +++ linux-2.4.20-aem-12r14/kernel/job.c Tue Aug 12 15:57:20 2003 @@ -0,0 +1,168 @@ +/* + * file: kernel/job.c + * + * Short description: + * + * ------------------------------------------------------------------------ + * + * Copyright (C) 2001, 2002, 2003 by + * Ericsson Research Canada + * 8400 Decarie Blvd + * Town of Mount Royal + * Quebec H4P 2N2 + * Tel: +1 514 345 7900 + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ------------------------------------------------------------------------ + * + * Created 2001/8/10 17:22:08 by lmcfros (Frederic.Rossi@Ericsson.CA) + * + * ------------------------------------------------------------------------ + * + * $Id: linux-2.4.20-aem-12r14.patch,v 1.1 2003/08/12 20:27:29 fjrossi Exp $ + * + * Revision history: + * ---------------- + * + * * 2001/08/10 - 2002/09/19 Frederic.Rossi@Ericsson.CA + * Initial revision + * + * + * ------------------------------------------------------------------------ +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define logm(format,args...) +//#define logm printk + +/* + * wq_add_job and wq_del_job are called with the job lock held! + */ +void wq_add_job (wq_job_head_t *wq, struct job_struct *job) +{ + struct job_args *jargs; + struct event_struct *ev; + unsigned long f; + + if (!job) + return; + + jargs = (struct job_args *)job->job.data; + ev = jargs->ev; + + if (!wq) + return; + + /* it's already awaken */ + if (!list_empty (&job->wq)) + goto out; + + /* it's already active */ + if (!list_empty (&ev->active)) + goto out; + + write_lock_irqsave (&wq->lock, f); + simple_wlock_job (job); + list_add_tail (&job->wq, &wq->list); + simple_wunlock_job (job); + wq->len++; + write_unlock_irqrestore (&wq->lock, f); + +out: + return; +} + +void wq_del_job (wq_job_head_t *wq, struct job_struct *job) +{ + unsigned long f; + + if (!wq) + return; + + if (!job) + return; + + write_lock_irqsave (&wq->lock, f); + if (wq->len>0) { + simple_wlock_job (job); + list_del_init (&job->wq); + simple_wunlock_job (job); + wq->len--; + } + write_unlock_irqrestore (&wq->lock, f); +} + +void job_wake_up_common (wq_job_head_t *wq, unsigned int __type, unsigned long __cond) +{ + struct list_head *curr; + unsigned long f; + + if (!wq) return; + + write_lock_irqsave (&wq->lock, f); + + if (!wq_empty (wq)) { + + list_for_each (curr, &wq->list) { + + struct job_struct *st_job = list_entry (curr, struct job_struct, wq); + if (!st_job) + continue; + + simple_wlock_job (st_job); + + switch (__type) { + case 0: + /* no condition */ + __job_activate (st_job); + break; + case 1: + /* strict condition */ + if (st_job->wstate == __cond) + __job_activate (st_job); + break; + case 2: + /* exclusive condition */ + if (st_job->wstate & __cond) + __job_activate (st_job); + break; + default: + logm ("job_wake_up_common: error __type=%u not valid\n", __type); + } + + simple_wunlock_job (st_job); + } + } + + write_unlock_irqrestore (&wq->lock, f); +} + +EXPORT_SYMBOL(wq_add_job); +EXPORT_SYMBOL(wq_del_job); +EXPORT_SYMBOL(job_wake_up_common); diff --exclude=CVS -NBbwur linux-2.4.20/kernel/sched.c linux-2.4.20-aem-12r14/kernel/sched.c --- linux-2.4.20/kernel/sched.c Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/kernel/sched.c Tue Aug 12 15:13:29 2003 @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -33,6 +34,8 @@ #include #include +#include + extern void timer_bh(void); extern void tqueue_bh(void); extern void immediate_bh(void); @@ -45,6 +48,13 @@ extern void mem_use(void); +/**/ + +extern long (*aem_schedadv_entry_pfn)(struct task_struct *); +extern long (*aem_schedcnt_entry_pfn)(struct task_struct *); +#define srt_advantage aem_schedadv_entry_pfn +#define srt_counter aem_schedcnt_entry_pfn + /* * Scheduling quanta. * @@ -180,7 +190,7 @@ if (p->mm == this_mm || !p->mm) weight += 1; weight += 20 - p->nice; - goto out; + goto cont; } /* @@ -189,6 +199,14 @@ * into account). */ weight = 1000 + p->rt_priority; + +cont: + /* + * Soft realtime responsiveness advantage given to processes + * with active events pending. + */ + weight += (int )srt_advantage (p); + out: return weight; } @@ -618,8 +636,13 @@ spin_unlock_irq(&runqueue_lock); read_lock(&tasklist_lock); - for_each_task(p) + for_each_task(p) { + if (p->srt_priority) { + p->counter = srt_counter (p); + } + else p->counter = (p->counter >> 1) + NICE_TO_TICKS(p->nice); + } read_unlock(&tasklist_lock); spin_lock_irq(&runqueue_lock); goto repeat_schedule; diff --exclude=CVS -NBbwur linux-2.4.20/kernel/signal.c linux-2.4.20-aem-12r14/kernel/signal.c --- linux-2.4.20/kernel/signal.c Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/kernel/signal.c Tue Aug 12 15:13:29 2003 @@ -1298,3 +1298,6 @@ return ret ? ret : (unsigned long)old_sa.sa.sa_handler; } #endif /* !alpha && !__ia64__ && !defined(__mips__) */ + + +EXPORT_SYMBOL(flush_signal_handlers); diff --exclude=CVS -NBbwur linux-2.4.20/kernel/user.c linux-2.4.20-aem-12r14/kernel/user.c --- linux-2.4.20/kernel/user.c Wed Nov 29 01:43:39 2000 +++ linux-2.4.20-aem-12r14/kernel/user.c Tue Aug 12 15:13:29 2003 @@ -135,3 +135,9 @@ } module_init(uid_cache_init); + + +#include +EXPORT_SYMBOL(alloc_uid); +EXPORT_SYMBOL(free_uid); +EXPORT_SYMBOL(root_user); diff --exclude=CVS -NBbwur linux-2.4.20/mm/Makefile linux-2.4.20-aem-12r14/mm/Makefile --- linux-2.4.20/mm/Makefile Fri Aug 2 20:39:46 2002 +++ linux-2.4.20-aem-12r14/mm/Makefile Tue Aug 12 15:13:29 2003 @@ -9,7 +9,7 @@ O_TARGET := mm.o -export-objs := shmem.o filemap.o memory.o page_alloc.o +export-objs := shmem.o filemap.o memory.o page_alloc.o mmap.o obj-y := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \ vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \ diff --exclude=CVS -NBbwur linux-2.4.20/mm/memory.c linux-2.4.20-aem-12r14/mm/memory.c --- linux-2.4.20/mm/memory.c Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/mm/memory.c Tue Aug 12 15:13:29 2003 @@ -1494,3 +1494,5 @@ } return page; } + +EXPORT_SYMBOL(zap_page_range); diff --exclude=CVS -NBbwur linux-2.4.20/mm/mmap.c linux-2.4.20-aem-12r14/mm/mmap.c --- linux-2.4.20/mm/mmap.c Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/mm/mmap.c Tue Aug 12 15:13:29 2003 @@ -243,7 +243,7 @@ #define validate_mm(mm) do { } while (0) #endif -static struct vm_area_struct * find_vma_prepare(struct mm_struct * mm, unsigned long addr, +struct vm_area_struct * find_vma_prepare(struct mm_struct * mm, unsigned long addr, struct vm_area_struct ** pprev, rb_node_t *** rb_link, rb_node_t ** rb_parent) { @@ -334,7 +334,7 @@ __vma_link_file(vma); } -static inline void vma_link(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev, +void vma_link(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev, rb_node_t ** rb_link, rb_node_t * rb_parent) { lock_vma_mappings(vma); @@ -867,7 +867,7 @@ * "prev", if it exists, points to a vma before the one * we just free'd - but there's no telling how much before. */ -static void free_pgtables(struct mm_struct * mm, struct vm_area_struct *prev, +void free_pgtables(struct mm_struct * mm, struct vm_area_struct *prev, unsigned long start, unsigned long end) { unsigned long first = start & PGDIR_MASK; @@ -1191,3 +1191,11 @@ vma_link(mm, vma, prev, rb_link, rb_parent); validate_mm(mm); } + +#include +EXPORT_SYMBOL(__insert_vm_struct); +EXPORT_SYMBOL(find_vma_prepare); +EXPORT_SYMBOL(find_vma_prev); +EXPORT_SYMBOL(vma_link); +EXPORT_SYMBOL(protection_map); +EXPORT_SYMBOL(free_pgtables); diff --exclude=CVS -NBbwur linux-2.4.20/net/Makefile linux-2.4.20-aem-12r14/net/Makefile --- linux-2.4.20/net/Makefile Fri Aug 2 20:39:46 2002 +++ linux-2.4.20-aem-12r14/net/Makefile Tue Aug 12 15:13:29 2003 @@ -8,7 +8,7 @@ O_TARGET := network.o mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched core -export-objs := netsyms.o +export-objs := netsyms.o socket.o subdir-y := core ethernet subdir-m := ipv4 # hum? diff --exclude=CVS -NBbwur linux-2.4.20/net/ax25/af_ax25.c linux-2.4.20-aem-12r14/net/ax25/af_ax25.c --- linux-2.4.20/net/ax25/af_ax25.c Fri Aug 2 20:39:46 2002 +++ linux-2.4.20-aem-12r14/net/ax25/af_ax25.c Tue Aug 12 15:13:29 2003 @@ -941,6 +941,8 @@ sk->debug = osk->debug; sk->state = TCP_ESTABLISHED; sk->sleep = osk->sleep; + sk->wrq = NULL; + sk->wclose = NULL; sk->zapped = osk->zapped; ax25->modulus = osk->protinfo.ax25->modulus; @@ -1316,6 +1318,9 @@ newsk->socket = newsock; newsk->sleep = &newsock->wait; + newsk->wrq = NULL; + newsk->wclose = NULL; + /* Now attach up the new socket */ kfree_skb(skb); sk->ack_backlog--; diff --exclude=CVS -NBbwur linux-2.4.20/net/core/sock.c linux-2.4.20-aem-12r14/net/core/sock.c --- linux-2.4.20/net/core/sock.c Fri Aug 2 20:39:46 2002 +++ linux-2.4.20-aem-12r14/net/core/sock.c Tue Aug 12 15:13:29 2003 @@ -580,6 +580,9 @@ * usage. */ +#include +#include + struct sock *sk_alloc(int family, int priority, int zero_it) { struct sock *sk = kmem_cache_alloc(sk_cachep, priority); @@ -1137,6 +1140,7 @@ if (sk->sleep && waitqueue_active(sk->sleep)) wake_up_interruptible(sk->sleep); sk_wake_async(sk,1,POLL_IN); + job_wake_up (sk->wrq); read_unlock(&sk->callback_lock); } @@ -1185,8 +1189,13 @@ sk->type = sock->type; sk->sleep = &sock->wait; sock->sk = sk; - } else + sk->wrq = &sock->jwq_read; + sk->wclose = &sock->jwq_close; + } else { sk->sleep = NULL; + sk->wrq = NULL; + sk->wclose = NULL; + } sk->dst_lock = RW_LOCK_UNLOCKED; sk->callback_lock = RW_LOCK_UNLOCKED; diff --exclude=CVS -NBbwur linux-2.4.20/net/ipv4/tcp.c linux-2.4.20-aem-12r14/net/ipv4/tcp.c --- linux-2.4.20/net/ipv4/tcp.c Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/net/ipv4/tcp.c Tue Aug 12 15:13:29 2003 @@ -531,6 +531,7 @@ sk->max_ack_backlog = 0; sk->ack_backlog = 0; tp->accept_queue = tp->accept_queue_tail = NULL; + wq_job_head_init (&tp->jwq_accept); tp->syn_wait_lock = RW_LOCK_UNLOCKED; tcp_delack_init(tp); @@ -590,6 +591,7 @@ tp->listen_opt =NULL; write_unlock_bh(&tp->syn_wait_lock); tp->accept_queue = tp->accept_queue_tail = NULL; + wq_job_head_init (&tp->jwq_accept); if (lopt->qlen) { for (i=0; isocket->flags)) + goto sockasync; + /* We need to make sure that this socket is listening, * and that it has something pending. */ - error = -EINVAL; if (sk->state != TCP_LISTEN) goto out; @@ -2219,6 +2225,8 @@ goto out; } +sockasync: + req = tp->accept_queue; if ((tp->accept_queue = req->dl_next) == NULL) tp->accept_queue_tail = NULL; diff --exclude=CVS -NBbwur linux-2.4.20/net/ipv4/tcp_input.c linux-2.4.20-aem-12r14/net/ipv4/tcp_input.c --- linux-2.4.20/net/ipv4/tcp_input.c Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/net/ipv4/tcp_input.c Tue Aug 12 15:13:29 2003 @@ -2235,6 +2235,8 @@ sk->shutdown |= RCV_SHUTDOWN; sk->done = 1; + job_wake_up (sk->wclose); + switch(sk->state) { case TCP_SYN_RECV: case TCP_ESTABLISHED: @@ -3613,6 +3615,7 @@ * Particularly, it can be connect to self. */ tcp_set_state(sk, TCP_SYN_RECV); + job_wake_up (&tp->jwq_accept); if (tp->saw_tstamp) { tp->tstamp_ok = 1; @@ -3780,6 +3783,7 @@ mb(); tcp_set_state(sk, TCP_ESTABLISHED); sk->state_change(sk); + job_wake_up (&tp->jwq_accept); /* Note, that this wakeup is only for marginal * crossed SYN case. Passively open sockets @@ -3817,6 +3821,7 @@ if (tp->snd_una == tp->write_seq) { tcp_set_state(sk, TCP_FIN_WAIT2); sk->shutdown |= SEND_SHUTDOWN; + job_wake_up (sk->wclose); dst_confirm(sk->dst_cache); if (!sk->dead) { @@ -3897,6 +3902,7 @@ /* Fall through */ case TCP_ESTABLISHED: tcp_data_queue(sk, skb); + job_wake_up (sk->wrq); queued = 1; break; } diff --exclude=CVS -NBbwur linux-2.4.20/net/ipv4/tcp_minisocks.c linux-2.4.20-aem-12r14/net/ipv4/tcp_minisocks.c --- linux-2.4.20/net/ipv4/tcp_minisocks.c Thu Nov 28 18:53:15 2002 +++ linux-2.4.20-aem-12r14/net/ipv4/tcp_minisocks.c Tue Aug 12 15:13:29 2003 @@ -734,6 +734,7 @@ newtp->urg_data = 0; newtp->listen_opt = NULL; newtp->accept_queue = newtp->accept_queue_tail = NULL; + wq_job_head_init (&newtp->jwq_accept); /* Deinitialize syn_wait_lock to trap illegal accesses. */ memset(&newtp->syn_wait_lock, 0, sizeof(newtp->syn_wait_lock)); @@ -750,6 +751,8 @@ tcp_reset_keepalive_timer(newsk, keepalive_time_when(newtp)); newsk->socket = NULL; newsk->sleep = NULL; + newsk->wrq = NULL; + newsk->wclose = NULL; newtp->tstamp_ok = req->tstamp_ok; if((newtp->sack_ok = req->sack_ok) != 0) { diff --exclude=CVS -NBbwur linux-2.4.20/net/netrom/af_netrom.c linux-2.4.20-aem-12r14/net/netrom/af_netrom.c --- linux-2.4.20/net/netrom/af_netrom.c Fri Aug 2 20:39:46 2002 +++ linux-2.4.20-aem-12r14/net/netrom/af_netrom.c Tue Aug 12 15:13:29 2003 @@ -526,6 +526,8 @@ sk->debug = osk->debug; sk->state = TCP_ESTABLISHED; sk->sleep = osk->sleep; + sk->wrq = NULL; + sk->wclose = NULL; sk->zapped = osk->zapped; skb_queue_head_init(&nr->ack_queue); @@ -789,6 +791,8 @@ newsk->pair = NULL; newsk->socket = newsock; newsk->sleep = &newsock->wait; + newsk->wrq = NULL; + newsk->wclose = NULL; sti(); /* Now attach up the new socket */ diff --exclude=CVS -NBbwur linux-2.4.20/net/rose/af_rose.c linux-2.4.20-aem-12r14/net/rose/af_rose.c --- linux-2.4.20/net/rose/af_rose.c Fri Aug 2 20:39:46 2002 +++ linux-2.4.20-aem-12r14/net/rose/af_rose.c Tue Aug 12 15:13:29 2003 @@ -607,6 +607,8 @@ sk->debug = osk->debug; sk->state = TCP_ESTABLISHED; sk->sleep = osk->sleep; + sk->wrq = NULL; + sk->wclose = NULL; sk->zapped = osk->zapped; init_timer(&rose->timer); @@ -886,6 +888,8 @@ newsk->pair = NULL; newsk->socket = newsock; newsk->sleep = &newsock->wait; + newsk->wrq = NULL; + newsk->wclose = NULL; sti(); /* Now attach up the new socket */ diff --exclude=CVS -NBbwur linux-2.4.20/net/socket.c linux-2.4.20-aem-12r14/net/socket.c --- linux-2.4.20/net/socket.c Thu Nov 28 18:53:16 2002 +++ linux-2.4.20-aem-12r14/net/socket.c Tue Aug 12 15:13:29 2003 @@ -391,13 +391,35 @@ * On a success the socket object pointer is returned. */ -struct socket *sockfd_lookup(int fd, int *err) +static inline struct file *fcheck_task (struct files_struct *files, unsigned int fd) +{ + struct file * file = NULL; + + if (fd < files->max_fds) + file = files->fd[fd]; + return file; +} + +struct file *fget_task (struct task_struct *task, unsigned int fd) +{ + struct file *file; + struct files_struct *files = task->files; + + read_lock (&files->file_lock); + file = fcheck_task (files, fd); + if (file) + get_file (file); + read_unlock (&files->file_lock); + return file; +} + +struct socket *do_sockfd_lookup(struct task_struct *task, int fd, int *err) { struct file *file; struct inode *inode; struct socket *sock; - if (!(file = fget(fd))) + if (!(file = fget_task (task, fd))) { *err = -EBADF; return NULL; @@ -418,6 +440,11 @@ return sock; } +struct socket *sockfd_lookup (int fd, int *err) +{ + return do_sockfd_lookup (current, fd, err); +} + extern __inline__ void sockfd_put(struct socket *sock) { fput(sock->file); @@ -450,6 +477,10 @@ sock->inode = inode; init_waitqueue_head(&sock->wait); + + wq_job_head_init(&sock->jwq_read); + wq_job_head_init(&sock->jwq_close); + sock->fasync_list = NULL; sock->state = SS_UNCONNECTED; sock->flags = 0; @@ -1043,7 +1074,124 @@ * clean when we restucture accept also. */ -asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen) +static int dup_fd (struct task_struct *task, int fd) +{ + int err = -EBADF; + int newfd; + + struct file *fi = fget (fd); + if (fi) { + struct files_struct *files = task->files; + + write_lock (&files->file_lock); + + newfd = find_next_zero_bit (files->open_fds->fds_bits, + files->max_fdset, fd); + + err = -EMFILE; + if (newfd >= task->rlim[RLIMIT_NOFILE].rlim_cur) + goto error; + + if (newfd >= files->max_fdset && !expand_fdset (files, newfd)) + goto error; + + if (newfd >= files->max_fds && !expand_fd_array (files, newfd)) + goto error; + + FD_SET (newfd, files->open_fds); + FD_CLR (newfd, files->close_on_exec); + files->next_fd = newfd + 1; + + err = newfd; + + error: + write_unlock (&files->file_lock); + fput (fi); + } + + return err; +} + +/* + * This is the socket mapping function used when want to create a + * mapping outside of the current process context. + */ +extern void fd_install_task (struct task_struct *, unsigned int, struct file *); + +int sock_map_fd_task (struct task_struct *task, struct socket *sock, int fd) +{ + int err; + struct file *file; + struct qstr iname; + char str[32]; + + err = -ENOMEM; + + /* + * we'll grab fsgid and fsuid from the current task + */ + file = get_empty_filp (); + if (!file) { + put_unused_fd (fd); + err = -ENFILE; + goto error; + } + + /* init for d_alloc */ + sprintf(str, "[%lu]", sock->inode->i_ino); + iname.name = str; + iname.len = strlen(str); + iname.hash = sock->inode->i_ino; + + /* allocate a dentry */ + file->f_dentry = d_alloc (sock_mnt->mnt_sb->s_root, &iname); + if (!file->f_dentry) { + put_filp (file); + goto error; + } + + file->f_dentry->d_op = &sockfs_dentry_operations; + d_add (file->f_dentry, sock->inode); + file->f_vfsmnt = mntget (sock_mnt); + + sock->file = file; + file->f_op = sock->inode->i_fop = &socket_file_ops; + file->f_mode = 3; + file->f_flags = O_RDWR; + file->f_pos = 0; + + fd_install_task (task, fd, file); + + return 0; + +error: + return err; +} + +static int map_fd (struct task_struct *task, struct socket *sock, int fd) +{ + int err; + int newfd; + + if (task == current) { + /* don't break the current implementation */ + return sock_map_fd (sock); + } + + err = dup_fd (task, fd); + if (err < 0) + return err; + + newfd = err; + + err = sock_map_fd_task (task, sock, newfd); + if (err < 0) + put_unused_fd_task (task, newfd); + + return err; +} + +long do_accept(struct task_struct *task, int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen) { struct socket *sock, *newsock; int err, len; @@ -1076,7 +1224,7 @@ /* File flags are not inherited via accept() unlike another OSes. */ - if ((err = sock_map_fd(newsock)) < 0) + if ((err = map_fd (current, newsock, 0)) < 0) goto out_release; out_put: @@ -1089,6 +1237,10 @@ goto out_put; } +asmlinkage long sys_accept (int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen) +{ + return do_accept (current, fd, upeer_sockaddr, upeer_addrlen); +} /* * Attempt to connect to a socket with the server address. The address @@ -1754,3 +1906,9 @@ len = 0; return len; } + +EXPORT_SYMBOL(sockfd_lookup); +EXPORT_SYMBOL(do_sockfd_lookup); +EXPORT_SYMBOL(do_accept); + + diff --exclude=CVS -NBbwur linux-2.4.20/net/unix/af_unix.c linux-2.4.20-aem-12r14/net/unix/af_unix.c --- linux-2.4.20/net/unix/af_unix.c Thu Nov 28 18:53:16 2002 +++ linux-2.4.20-aem-12r14/net/unix/af_unix.c Tue Aug 12 15:13:29 2003 @@ -974,6 +974,8 @@ newsk->peercred.uid = current->euid; newsk->peercred.gid = current->egid; newsk->sleep = &newsk->protinfo.af_unix.peer_wait; + newsk->wrq = NULL; + newsk->wclose = NULL; /* copy address information from listening to new sock*/ if (other->protinfo.af_unix.addr) diff --exclude=CVS -NBbwur linux-2.4.20/net/wanrouter/af_wanpipe.c linux-2.4.20-aem-12r14/net/wanrouter/af_wanpipe.c --- linux-2.4.20/net/wanrouter/af_wanpipe.c Fri Aug 2 20:39:46 2002 +++ linux-2.4.20-aem-12r14/net/wanrouter/af_wanpipe.c Tue Aug 12 15:13:29 2003 @@ -475,6 +475,8 @@ sk->debug = osk->debug; sk->state = WANSOCK_CONNECTING; sk->sleep = osk->sleep; + sk->wrq = NULL; + sk->wclose = NULL; return sk; } @@ -2576,6 +2578,8 @@ newsk->pair = NULL; newsk->socket = newsock; newsk->sleep = &newsock->wait; + newsk->wrq = NULL; + newsk->wclose = NULL; /* Now attach up the new socket */ sk->ack_backlog--;