diff -Nur linux-2.4.15/Makefile linux/Makefile --- linux-2.4.15/Makefile Thu Nov 22 17:22:58 2001 +++ linux/Makefile Sat Nov 24 16:21:53 2001 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 -SUBLEVEL = 15 -EXTRAVERSION =-greased-turkey +SUBLEVEL = 16 +EXTRAVERSION = KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -Nur linux-2.4.15/arch/ppc/kernel/entry.S linux/arch/ppc/kernel/entry.S --- linux-2.4.15/arch/ppc/kernel/entry.S Tue Aug 28 10:58:33 2001 +++ linux/arch/ppc/kernel/entry.S Sat Nov 24 16:22:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.entry.S 1.22 08/15/01 22:43:06 paulus + * BK Id: SCCS/s.entry.S 1.24 11/23/01 16:38:29 paulus */ /* * PowerPC version @@ -216,6 +216,7 @@ SAVE_8GPRS(14, r1) SAVE_10GPRS(22, r1) mflr r20 /* Return to switch caller */ + stw r20,INT_FRAME_SIZE+4(r1) mfmsr r22 li r0,MSR_FP /* Disable floating-point */ #ifdef CONFIG_ALTIVEC @@ -223,10 +224,12 @@ oris r0,r0,MSR_VEC@h /* Disable altivec */ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ + and. r0,r0,r22 /* FP or altivec enabled? */ + beq+ 1f andc r22,r22,r0 mtmsr r22 isync - stw r20,_NIP(r1) +1: stw r20,_NIP(r1) stw r22,_MSR(r1) stw r20,_LINK(r1) mfcr r20 @@ -391,9 +394,9 @@ mfmsr r9 stw r9,8(r1) li r0,0 - ori r0,r0,MSR_EE|MSR_SE|MSR_BE + ori r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_FE0|MSR_FE1 andc r0,r9,r0 - li r10,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP + li r10,MSR_IR|MSR_DR|MSR_FP andc r9,r0,r10 SYNC /* disable interrupts so SRR0/1 */ mtmsr r0 /* don't get trashed */ diff -Nur linux-2.4.15/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S --- linux-2.4.15/arch/ppc/kernel/misc.S Fri Nov 2 23:43:54 2001 +++ linux/arch/ppc/kernel/misc.S Sat Nov 24 16:22:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.misc.S 1.32 10/18/01 17:29:53 trini + * BK Id: SCCS/s.misc.S 1.34 11/23/01 16:38:29 paulus */ /* * This file contains miscellaneous low-level functions. @@ -866,10 +866,8 @@ sc cmpi 0,r3,0 /* parent or child? */ bnelr /* return if parent */ - li r0,0 /* clear out p->thread.regs */ - stw r0,THREAD+PT_REGS(r2) /* since we don't have user ctx */ - addi r1,r2,TASK_UNION_SIZE-STACK_FRAME_OVERHEAD - stw r0,0(r1) + li r0,0 /* make top-level stack frame */ + stwu r0,-16(r1) mtlr r6 /* fn addr in lr */ mr r3,r4 /* load arg and call fn */ blrl diff -Nur linux-2.4.15/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c --- linux-2.4.15/arch/ppc/kernel/process.c Mon Oct 8 15:43:01 2001 +++ linux/arch/ppc/kernel/process.c Sat Nov 24 16:22:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.process.c 1.31 10/02/01 09:51:41 paulus + * BK Id: SCCS/s.process.c 1.34 11/23/01 16:38:29 paulus */ /* * linux/arch/ppc/kernel/process.c @@ -336,9 +336,10 @@ /* for kernel thread, set `current' and stackptr in new task */ childregs->gpr[1] = sp + sizeof(struct pt_regs); childregs->gpr[2] = (unsigned long) p; - } + p->thread.regs = NULL; /* no user register state */ + } else + p->thread.regs = childregs; childregs->gpr[3] = 0; /* Result from fork() */ - p->thread.regs = childregs; sp -= STACK_FRAME_OVERHEAD; childframe = sp; @@ -463,6 +464,27 @@ break; } printk("\n"); +} + +void show_trace_task(struct task_struct *tsk) +{ + unsigned long stack_top = (unsigned long) tsk + THREAD_SIZE; + unsigned long sp, prev_sp; + int count = 0; + + if (tsk == NULL) + return; + sp = (unsigned long) &tsk->thread.ksp; + do { + prev_sp = sp; + sp = *(unsigned long *)sp; + if (sp <= prev_sp || sp >= stack_top || (sp & 3) != 0) + break; + if (count > 0) + printk("[%08lx] ", *(unsigned long *)(sp + 4)); + } while (++count < 16); + if (count > 1) + printk("\n"); } #if 0 diff -Nur linux-2.4.15/arch/ppc/kernel/ptrace.c linux/arch/ppc/kernel/ptrace.c --- linux-2.4.15/arch/ppc/kernel/ptrace.c Tue Sep 18 20:56:19 2001 +++ linux/arch/ppc/kernel/ptrace.c Sat Nov 24 16:22:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ptrace.c 1.8 07/07/01 17:00:08 paulus + * BK Id: SCCS/s.ptrace.c 1.12 11/23/01 16:38:30 paulus */ /* * linux/arch/ppc/kernel/ptrace.c @@ -132,14 +132,9 @@ ret = ptrace_attach(child); goto out_tsk; } - ret = -ESRCH; - if (!(child->ptrace & PT_PTRACED)) - goto out_tsk; - if (child->state != TASK_STOPPED) { - if (request != PTRACE_KILL) - goto out_tsk; - } - if (child->p_pptr != current) + + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret < 0) goto out_tsk; switch (request) { diff -Nur linux-2.4.15/arch/ppc/kernel/signal.c linux/arch/ppc/kernel/signal.c --- linux-2.4.15/arch/ppc/kernel/signal.c Mon May 21 21:04:47 2001 +++ linux/arch/ppc/kernel/signal.c Sat Nov 24 16:22:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.signal.c 1.7 05/17/01 18:14:22 cort + * BK Id: SCCS/s.signal.c 1.10 11/23/01 16:38:30 paulus */ /* * linux/arch/ppc/kernel/signal.c @@ -180,7 +180,7 @@ siginitset(&new_ka.sa.sa_mask, mask); } - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL)); if (!ret && oact) { if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || @@ -254,6 +254,8 @@ current->blocked = set; recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); + if (regs->msr & MSR_FP) + giveup_fpu(current); rt_sf++; /* Look at next rt_sigframe */ if (rt_sf == (struct rt_sigframe *)(sigctx.regs)) { @@ -263,8 +265,6 @@ * see handle_signal() */ sr = (struct sigregs *) sigctx.regs; - if (regs->msr & MSR_FP ) - giveup_fpu(current); if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs))) goto badframe; @@ -298,6 +298,7 @@ if (get_user(prevsp, &sr->gp_regs[PT_R1]) || put_user(prevsp, (unsigned long *) regs->gpr[1])) goto badframe; + current->thread.fpscr = 0; } return ret; @@ -328,6 +329,7 @@ goto badframe; flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); + current->thread.fpscr = 0; /* turn off all fp exceptions */ /* Retrieve rt_sigframe from stack and set up registers for signal handler @@ -379,13 +381,13 @@ current->blocked = set; recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); + if (regs->msr & MSR_FP ) + giveup_fpu(current); sc++; /* Look at next sigcontext */ if (sc == (struct sigcontext_struct *)(sigctx.regs)) { /* Last stacked signal - restore registers */ sr = (struct sigregs *) sigctx.regs; - if (regs->msr & MSR_FP ) - giveup_fpu(current); if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs))) goto badframe; @@ -413,6 +415,7 @@ if (get_user(prevsp, &sr->gp_regs[PT_R1]) || put_user(prevsp, (unsigned long *) regs->gpr[1])) goto badframe; + current->thread.fpscr = 0; } return ret; @@ -431,8 +434,8 @@ if (verify_area(VERIFY_WRITE, frame, sizeof(*frame))) goto badframe; - if (regs->msr & MSR_FP) - giveup_fpu(current); + if (regs->msr & MSR_FP) + giveup_fpu(current); if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE) || __copy_to_user(&frame->fp_regs, current->thread.fpr, ELF_NFPREG * sizeof(double)) @@ -441,6 +444,7 @@ goto badframe; flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); + current->thread.fpscr = 0; /* turn off all fp exceptions */ newsp -= __SIGNAL_FRAMESIZE; if (put_user(regs->gpr[1], (unsigned long *)newsp) diff -Nur linux-2.4.15/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c --- linux-2.4.15/arch/ppc/kernel/smp.c Wed Nov 21 16:31:09 2001 +++ linux/arch/ppc/kernel/smp.c Sat Nov 24 16:22:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.smp.c 1.34 10/11/01 12:06:01 trini + * BK Id: SCCS/s.smp.c 1.37 11/23/01 16:38:30 paulus */ /* * Smp support for ppc. @@ -37,8 +37,6 @@ #include #include -#include "open_pic.h" - int smp_threads_ready; volatile int smp_commenced; int smp_num_cpus = 1; @@ -324,21 +322,8 @@ struct pt_regs regs; /* create a process for the processor */ - /* we don't care about the values in regs since we'll - never reschedule the forked task. */ - /* We DO care about one bit in the pt_regs we - pass to do_fork. That is the MSR_FP bit in - regs.msr. If that bit is on, then do_fork - (via copy_thread) will call giveup_fpu. - giveup_fpu will get a pointer to our (current's) - last register savearea via current->thread.regs - and using that pointer will turn off the MSR_FP, - MSR_FE0 and MSR_FE1 bits. At this point, this - pointer is pointing to some arbitrary point within - our stack. */ - + /* only regs.msr is actually used, and 0 is OK for it */ memset(®s, 0, sizeof(struct pt_regs)); - if (do_fork(CLONE_VM|CLONE_PID, 0, ®s, 0) < 0) panic("failed fork for CPU %d", i); p = init_task.prev_task; @@ -505,8 +490,6 @@ cpu_callin_map[cpu] = 1; smp_ops->setup_cpu(cpu); - - init_idle(); /* * This cpu is now "online". Only set them online diff -Nur linux-2.4.15/arch/ppc/mm/ppc_mmu.c linux/arch/ppc/mm/ppc_mmu.c --- linux-2.4.15/arch/ppc/mm/ppc_mmu.c Tue Aug 28 10:58:33 2001 +++ linux/arch/ppc/mm/ppc_mmu.c Sat Nov 24 16:22:16 2001 @@ -304,6 +304,9 @@ if (Hash == 0 || nopreload) return; + /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */ + if (!pte_young(pte)) + return; mm = (address < TASK_SIZE)? vma->vm_mm: &init_mm; pmd = pmd_offset(pgd_offset(mm, address), address); if (!pmd_none(*pmd)) { diff -Nur linux-2.4.15/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c --- linux-2.4.15/drivers/ide/ide-probe.c Thu Oct 11 13:14:32 2001 +++ linux/drivers/ide/ide-probe.c Sat Nov 24 16:22:06 2001 @@ -779,7 +779,7 @@ /* IDE can do up to 128K per request. */ *max_sect++ = 255; #endif - *max_ra++ = MAX_READAHEAD; + *max_ra++ = vm_max_readahead; } for (unit = 0; unit < units; ++unit) diff -Nur linux-2.4.15/drivers/md/md.c linux/drivers/md/md.c --- linux-2.4.15/drivers/md/md.c Thu Oct 25 18:58:34 2001 +++ linux/drivers/md/md.c Sat Nov 24 16:22:06 2001 @@ -3398,7 +3398,7 @@ /* * Tune reconstruction: */ - window = MAX_READAHEAD*(PAGE_SIZE/512); + window = vm_max_readahead*(PAGE_SIZE/512); printk(KERN_INFO "md: using %dk window, over a total of %d blocks.\n", window/2,max_sectors/2); diff -Nur linux-2.4.15/drivers/net/8139too.c linux/drivers/net/8139too.c --- linux-2.4.15/drivers/net/8139too.c Fri Nov 9 19:45:35 2001 +++ linux/drivers/net/8139too.c Sat Nov 24 17:46:36 2001 @@ -1270,6 +1270,7 @@ tp->full_duplex = tp->duplex_lock; tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000; tp->twistie = 1; + tp->time_to_die = 0; rtl8139_init_ring (dev); rtl8139_hw_start (dev); diff -Nur linux-2.4.15/fs/inode.c linux/fs/inode.c --- linux-2.4.15/fs/inode.c Thu Nov 22 16:38:31 2001 +++ linux/fs/inode.c Sat Nov 24 16:22:41 2001 @@ -1065,24 +1065,27 @@ if (inode->i_state != I_CLEAR) BUG(); } else { - if (!list_empty(&inode->i_hash) && sb && sb->s_root) { + if (!list_empty(&inode->i_hash)) { if (!(inode->i_state & (I_DIRTY|I_LOCK))) { list_del(&inode->i_list); list_add(&inode->i_list, &inode_unused); } inodes_stat.nr_unused++; spin_unlock(&inode_lock); - return; - } else { - list_del_init(&inode->i_list); + if (!sb || sb->s_flags & MS_ACTIVE) + return; + write_inode_now(inode, 1); + spin_lock(&inode_lock); + inodes_stat.nr_unused--; list_del_init(&inode->i_hash); - inode->i_state|=I_FREEING; - inodes_stat.nr_inodes--; - spin_unlock(&inode_lock); - if (inode->i_data.nrpages) - truncate_inode_pages(&inode->i_data, 0); - clear_inode(inode); } + list_del_init(&inode->i_list); + inode->i_state|=I_FREEING; + inodes_stat.nr_inodes--; + spin_unlock(&inode_lock); + if (inode->i_data.nrpages) + truncate_inode_pages(&inode->i_data, 0); + clear_inode(inode); } destroy_inode(inode); } diff -Nur linux-2.4.15/fs/super.c linux/fs/super.c --- linux-2.4.15/fs/super.c Wed Nov 21 20:05:29 2001 +++ linux/fs/super.c Sat Nov 24 16:22:41 2001 @@ -462,6 +462,7 @@ lock_super(s); if (!type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) goto out_fail; + s->s_flags |= MS_ACTIVE; unlock_super(s); /* tell bdcache that we are going to keep this one */ if (bdev) @@ -614,6 +615,7 @@ lock_super(s); if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) goto out_fail; + s->s_flags |= MS_ACTIVE; unlock_super(s); get_filesystem(fs_type); path_release(&nd); @@ -695,6 +697,7 @@ lock_super(s); if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) goto out_fail; + s->s_flags |= MS_ACTIVE; unlock_super(s); get_filesystem(fs_type); return s; @@ -739,6 +742,7 @@ dput(root); fsync_super(sb); lock_super(sb); + sb->s_flags &= ~MS_ACTIVE; invalidate_inodes(sb); /* bad name - it should be evict_inodes() */ if (sop) { if (sop->write_super && sb->s_dirt) diff -Nur linux-2.4.15/include/linux/blkdev.h linux/include/linux/blkdev.h --- linux-2.4.15/include/linux/blkdev.h Thu Nov 22 17:47:08 2001 +++ linux/include/linux/blkdev.h Sat Nov 24 16:51:59 2001 @@ -180,10 +180,6 @@ #define PageAlignSize(size) (((size) + PAGE_SIZE -1) & PAGE_MASK) -/* read-ahead in pages.. */ -#define MAX_READAHEAD 31 -#define MIN_READAHEAD 3 - #define blkdev_entry_to_request(entry) list_entry((entry), struct request, queue) #define blkdev_entry_next_request(entry) blkdev_entry_to_request((entry)->next) #define blkdev_entry_prev_request(entry) blkdev_entry_to_request((entry)->prev) diff -Nur linux-2.4.15/include/linux/fs.h linux/include/linux/fs.h --- linux-2.4.15/include/linux/fs.h Thu Nov 22 17:46:19 2001 +++ linux/include/linux/fs.h Sat Nov 24 16:51:47 2001 @@ -110,6 +110,7 @@ #define MS_BIND 4096 #define MS_REC 16384 #define MS_VERBOSE 32768 +#define MS_ACTIVE (1<<30) #define MS_NOUSER (1<<31) /* diff -Nur linux-2.4.15/include/linux/mm.h linux/include/linux/mm.h --- linux-2.4.15/include/linux/mm.h Thu Nov 22 17:46:20 2001 +++ linux/include/linux/mm.h Sat Nov 24 16:51:47 2001 @@ -111,6 +111,10 @@ #define VM_SequentialReadHint(v) ((v)->vm_flags & VM_SEQ_READ) #define VM_RandomReadHint(v) ((v)->vm_flags & VM_RAND_READ) +/* read ahead limits */ +extern int vm_min_readahead; +extern int vm_max_readahead; + /* * mapping from the currently active vm_flags protection bits (the * low four bits) to a page protection mask.. diff -Nur linux-2.4.15/include/linux/raid/md_k.h linux/include/linux/raid/md_k.h --- linux-2.4.15/include/linux/raid/md_k.h Mon Nov 12 15:51:56 2001 +++ linux/include/linux/raid/md_k.h Sat Nov 24 16:22:06 2001 @@ -91,7 +91,7 @@ /* * default readahead */ -#define MD_READAHEAD MAX_READAHEAD +#define MD_READAHEAD vm_max_readahead static inline int disk_faulty(mdp_disk_t * d) { diff -Nur linux-2.4.15/include/linux/sysctl.h linux/include/linux/sysctl.h --- linux-2.4.15/include/linux/sysctl.h Thu Nov 22 17:46:19 2001 +++ linux/include/linux/sysctl.h Sat Nov 24 16:51:47 2001 @@ -139,7 +139,9 @@ VM_PAGECACHE=7, /* struct: Set cache memory thresholds */ VM_PAGERDAEMON=8, /* struct: Control kswapd behaviour */ VM_PGT_CACHE=9, /* struct: Set page table cache parameters */ - VM_PAGE_CLUSTER=10 /* int: set number of pages to swap together */ + VM_PAGE_CLUSTER=10, /* int: set number of pages to swap together */ + VM_MIN_READAHEAD=12, /* Min file readahead */ + VM_MAX_READAHEAD=13 /* Max file readahead */ }; diff -Nur linux-2.4.15/kernel/sysctl.c linux/kernel/sysctl.c --- linux-2.4.15/kernel/sysctl.c Fri Oct 5 16:23:53 2001 +++ linux/kernel/sysctl.c Sat Nov 24 16:22:06 2001 @@ -270,6 +270,10 @@ &pgt_cache_water, 2*sizeof(int), 0644, NULL, &proc_dointvec}, {VM_PAGE_CLUSTER, "page-cluster", &page_cluster, sizeof(int), 0644, NULL, &proc_dointvec}, + {VM_MIN_READAHEAD, "min-readahead", + &vm_min_readahead,sizeof(int), 0644, NULL, &proc_dointvec}, + {VM_MAX_READAHEAD, "max-readahead", + &vm_max_readahead,sizeof(int), 0644, NULL, &proc_dointvec}, {0} }; diff -Nur linux-2.4.15/mm/filemap.c linux/mm/filemap.c --- linux-2.4.15/mm/filemap.c Wed Nov 21 20:07:25 2001 +++ linux/mm/filemap.c Sat Nov 24 16:22:06 2001 @@ -47,6 +47,12 @@ unsigned int page_hash_bits; struct page **page_hash_table; +int vm_max_readahead = 31; +int vm_min_readahead = 3; +EXPORT_SYMBOL(vm_max_readahead); +EXPORT_SYMBOL(vm_min_readahead); + + spinlock_t pagecache_lock ____cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; /* * NOTE: to avoid deadlocking you must never acquire the pagemap_lru_lock @@ -1134,7 +1140,7 @@ static inline int get_max_readahead(struct inode * inode) { if (!inode->i_dev || !max_readahead[MAJOR(inode->i_dev)]) - return MAX_READAHEAD; + return vm_max_readahead; return max_readahead[MAJOR(inode->i_dev)][MINOR(inode->i_dev)]; } @@ -1317,8 +1323,8 @@ if (filp->f_ramax < needed) filp->f_ramax = needed; - if (reada_ok && filp->f_ramax < MIN_READAHEAD) - filp->f_ramax = MIN_READAHEAD; + if (reada_ok && filp->f_ramax < vm_min_readahead) + filp->f_ramax = vm_min_readahead; if (filp->f_ramax > max_readahead) filp->f_ramax = max_readahead; }