From owner-p4-projects@FreeBSD.ORG Fri Mar 30 20:12:28 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 86CE016A406; Fri, 30 Mar 2007 20:12:28 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 1D76D16A400 for ; Fri, 30 Mar 2007 20:12:28 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 0CF7213C4C4 for ; Fri, 30 Mar 2007 20:12:28 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l2UKCRJD083117 for ; Fri, 30 Mar 2007 20:12:27 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l2UKCR5R083107 for perforce@freebsd.org; Fri, 30 Mar 2007 20:12:27 GMT (envelope-from jhb@freebsd.org) Date: Fri, 30 Mar 2007 20:12:27 GMT Message-Id: <200703302012.l2UKCR5R083107@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Cc: Subject: PERFORCE change 116967 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Mar 2007 20:12:28 -0000 http://perforce.freebsd.org/chv.cgi?CH=116967 Change 116967 by jhb@jhb_mutex on 2007/03/30 20:11:26 IFC @116957. Affected files ... .. //depot/projects/smpng/sys/amd64/amd64/support.S#18 integrate .. //depot/projects/smpng/sys/amd64/linux32/linux32_machdep.c#22 integrate .. //depot/projects/smpng/sys/compat/linprocfs/linprocfs.c#56 integrate .. //depot/projects/smpng/sys/compat/linux/linux_futex.c#4 integrate .. //depot/projects/smpng/sys/dev/firewire/firewire.c#40 integrate .. //depot/projects/smpng/sys/geom/geom_ctl.c#26 integrate .. //depot/projects/smpng/sys/i386/i386/support.s#23 integrate .. //depot/projects/smpng/sys/kern/kern_lock.c#62 integrate .. //depot/projects/smpng/sys/kern/kern_rwlock.c#15 integrate .. //depot/projects/smpng/sys/netgraph/ng_base.c#48 integrate .. //depot/projects/smpng/sys/sys/lockmgr.h#20 integrate .. //depot/projects/smpng/sys/sys/mutex.h#72 integrate Differences ... ==== //depot/projects/smpng/sys/amd64/amd64/support.S#18 (text+ko) ==== @@ -27,7 +27,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/amd64/amd64/support.S,v 1.121 2006/10/17 02:24:45 davidxu Exp $ + * $FreeBSD: src/sys/amd64/amd64/support.S,v 1.124 2007/03/30 19:33:52 jkim Exp $ */ #include "opt_ddb.h" @@ -242,7 +242,7 @@ cmpq %rcx,%rax ja copyout_fault - xchgq %rdi, %rsi + xchgq %rdi,%rsi /* bcopy(%rsi, %rdi, %rdx) */ movq %rdx,%rcx @@ -288,8 +288,8 @@ cmpq %rcx,%rax ja copyin_fault - xchgq %rdi, %rsi - movq %rdx, %rcx + xchgq %rdi,%rsi + movq %rdx,%rcx movb %cl,%al shrq $3,%rcx /* copy longword-wise */ cld @@ -353,11 +353,11 @@ cmpq %rax,%rdi /* verify address is valid */ ja fusufault - movq %rsi, %rax /* old */ + movq %rsi,%rax /* old */ #ifdef SMP lock #endif - cmpxchgq %rdx, (%rdi) /* new = %rdx */ + cmpxchgq %rdx,(%rdi) /* new = %rdx */ /* * The old value is in %eax. If the store succeeded it will be the @@ -501,7 +501,7 @@ cmpq %rax,%rdi /* verify address validity */ ja fusufault - movl %esi, %eax + movl %esi,%eax movb %al,(%rdi) xorl %eax,%eax movq PCPU(CURPCB),%rcx /* restore trashed register */ @@ -518,9 +518,9 @@ * return the actual length in *lencopied. */ ENTRY(copyinstr) - movq %rdx, %r8 /* %r8 = maxlen */ - movq %rcx, %r9 /* %r9 = *len */ - xchgq %rdi, %rsi /* %rdi = from, %rsi = to */ + movq %rdx,%r8 /* %r8 = maxlen */ + movq %rcx,%r9 /* %r9 = *len */ + xchgq %rdi,%rsi /* %rdi = from, %rsi = to */ movq PCPU(CURPCB),%rcx movq $cpystrflt,PCB_ONFAULT(%rcx) @@ -582,9 +582,9 @@ * %rdi, %rsi, %rdx, %rcx */ ENTRY(copystr) - movq %rdx, %r8 /* %r8 = maxlen */ + movq %rdx,%r8 /* %r8 = maxlen */ - xchgq %rdi, %rsi + xchgq %rdi,%rsi incq %rdx cld 1: @@ -605,11 +605,11 @@ 6: - testq %rcx, %rcx + testq %rcx,%rcx jz 7f /* set *lencopied and return %rax */ - subq %rdx, %r8 - movq %r8, (%rcx) + subq %rdx,%r8 + movq %r8,(%rcx) 7: ret @@ -626,7 +626,7 @@ jmp 1f nop 1: - movl $KDSEL, %eax + movl $KDSEL,%eax movl %eax,%ds movl %eax,%es movl %eax,%fs /* Beware, use wrmsr to set 64 bit base */ @@ -689,3 +689,47 @@ movq %rax,32(%rdi) movq %rdi,bbhead NON_GPROF_RET + + .text + +futex_fault: + movq PCPU(CURPCB),%rdx + movq $0,PCB_ONFAULT(%rdx) + movq $-EFAULT,%rax + ret + +/* int futex_xchgl(int oparg, caddr_t uaddr, int *oldval); */ +ENTRY(futex_xchgl) + movq PCPU(CURPCB),%r11 + movq $futex_fault,PCB_ONFAULT(%r11) + + movq $VM_MAXUSER_ADDRESS-4,%rax + cmpq %rax,%rsi + ja futex_fault + +#ifdef SMP + lock +#endif + xchgl %edi,(%rsi) + movl %edi,(%rdx) + xorl %eax,%eax + movq %rax,PCB_ONFAULT(%r11) + ret + +/* int futex_addl(int oparg, caddr_t uaddr, int *oldval); */ +ENTRY(futex_addl) + movq PCPU(CURPCB),%r11 + movq $futex_fault,PCB_ONFAULT(%r11) + + movq $VM_MAXUSER_ADDRESS-4,%rax + cmpq %rax,%rsi + ja futex_fault + +#ifdef SMP + lock +#endif + xaddl %edi,(%rsi) + movl %edi,(%rdx) + xorl %eax,%eax + movq %rax,PCB_ONFAULT(%r11) + ret ==== //depot/projects/smpng/sys/amd64/linux32/linux32_machdep.c#22 (text+ko) ==== @@ -29,7 +29,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_machdep.c,v 1.37 2007/03/30 00:06:21 jkim Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_machdep.c,v 1.39 2007/03/30 17:27:13 jkim Exp $"); #include #include @@ -124,7 +124,7 @@ * Allocate temporary demand zeroed space for argument and * environment strings */ - args->buf = (char *) kmem_alloc_wait(exec_map, + args->buf = (char *)kmem_alloc_wait(exec_map, PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); if (args->buf == NULL) return (ENOMEM); @@ -158,14 +158,14 @@ if (error) { if (error == ENAMETOOLONG) error = E2BIG; - + goto err_exit; } args->stringspace -= length; args->endp += length; args->argc++; } - + args->begin_envv = args->endp; /* @@ -222,13 +222,13 @@ if (error == 0) error = kern_execve(td, &eargs, NULL); if (error == 0) - /* linux process can exec fbsd one, dont attempt + /* Linux process can execute FreeBSD one, do not attempt * to create emuldata for such process using * linux_proc_init, this leads to a panic on KASSERT - * because such process has p->p_emuldata == NULL + * because such process has p->p_emuldata == NULL. */ if (td->td_proc->p_sysent == &elf_linux_sysvec) - error = linux_proc_init(td, 0, 0); + error = linux_proc_init(td, 0, 0); return (error); } @@ -469,7 +469,7 @@ if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2)) != 0) return (error); - + if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -483,7 +483,9 @@ td2 = FIRST_THREAD_IN_PROC(p2); - /* make it run */ + /* + * Make this runnable after we are finished with it. + */ mtx_lock_spin(&sched_lock); TD_SET_CAN_RUN(td2); sched_add(td2, SRQ_BORING); @@ -504,7 +506,7 @@ printf(ARGS(vfork, "")); #endif - /* exclude RFPPWAIT */ + /* Exclude RFPPWAIT */ if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFSTOPPED, 0, &p2)) != 0) return (error); if (error == 0) { @@ -523,7 +525,7 @@ PROC_UNLOCK(p2); td2 = FIRST_THREAD_IN_PROC(p2); - + /* make it run */ mtx_lock_spin(&sched_lock); TD_SET_CAN_RUN(td2); @@ -535,7 +537,7 @@ while (p2->p_flag & P_PPWAIT) msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0); PROC_UNLOCK(p2); - + return (0); } @@ -550,10 +552,9 @@ #ifdef DEBUG if (ldebug(clone)) { - printf(ARGS(clone, "flags %x, stack %x, parent tid: %x, child tid: %x"), - (unsigned int)args->flags, (unsigned int)(uintptr_t)args->stack, - (unsigned int)(uintptr_t)args->parent_tidptr, - (unsigned int)(uintptr_t)args->child_tidptr); + printf(ARGS(clone, "flags %x, stack %p, parent tid: %p, " + "child tid: %p"), (unsigned)args->flags, + args->stack, args->parent_tidptr, args->child_tidptr); } #endif @@ -568,11 +569,11 @@ ff |= RFMEM; if (args->flags & LINUX_CLONE_SIGHAND) ff |= RFSIGSHARE; - /* - * XXX: in linux sharing of fs info (chroot/cwd/umask) - * and open files is independant. in fbsd its in one - * structure but in reality it doesn't cause any problems - * because both of these flags are usually set together. + /* + * XXX: In Linux, sharing of fs info (chroot/cwd/umask) + * and open files is independant. In FreeBSD, its in one + * structure but in reality it does not make any problems + * because both of these flags are set at once usually. */ if (!(args->flags & (LINUX_CLONE_FILES | LINUX_CLONE_FS))) ff |= RFFDG; @@ -593,6 +594,10 @@ if ((args->flags & 0xffffff00) == LINUX_THREADING_FLAGS) ff |= RFTHREAD; + if (args->flags & LINUX_CLONE_PARENT_SETTID) + if (args->parent_tidptr == NULL) + return (EINVAL); + error = fork1(td, ff, 0, &p2); if (error) return (error); @@ -604,35 +609,21 @@ PROC_UNLOCK(p2); sx_xunlock(&proctree_lock); } - + /* create the emuldata */ error = linux_proc_init(td, p2->p_pid, args->flags); /* reference it - no need to check this */ em = em_find(p2, EMUL_DOLOCK); KASSERT(em != NULL, ("clone: emuldata not found.\n")); /* and adjust it */ - if (args->flags & LINUX_CLONE_PARENT_SETTID) { - if (args->parent_tidptr == NULL) { - EMUL_UNLOCK(&emul_lock); - return (EINVAL); - } - error = copyout(&p2->p_pid, args->parent_tidptr, sizeof(p2->p_pid)); - if (error) { - EMUL_UNLOCK(&emul_lock); - return (error); - } - } if (args->flags & LINUX_CLONE_THREAD) { - /* XXX: linux mangles pgrp and pptr somehow - * I think it might be this but I am not sure. - */ #ifdef notyet PROC_LOCK(p2); p2->p_pgrp = td->td_proc->p_pgrp; PROC_UNLOCK(p2); #endif - exit_signal = 0; + exit_signal = 0; } if (args->flags & LINUX_CLONE_CHILD_SETTID) @@ -647,16 +638,24 @@ EMUL_UNLOCK(&emul_lock); + if (args->flags & LINUX_CLONE_PARENT_SETTID) { + error = copyout(&p2->p_pid, args->parent_tidptr, + sizeof(p2->p_pid)); + if (error) + printf(LMSG("copyout failed!")); + } + PROC_LOCK(p2); p2->p_sigparent = exit_signal; PROC_UNLOCK(p2); td2 = FIRST_THREAD_IN_PROC(p2); - /* - * in a case of stack = NULL we are supposed to COW calling process stack - * this is what normal fork() does so we just keep the tf_rsp arg intact + /* + * In a case of stack = NULL, we are supposed to COW calling process + * stack. This is what normal fork() does, so we just keep tf_rsp arg + * intact. */ if (args->stack) - td2->td_frame->tf_rsp = PTROUT(args->stack); + td2->td_frame->tf_rsp = PTROUT(args->stack); if (args->flags & LINUX_CLONE_SETTLS) { struct user_segment_descriptor sd; @@ -700,8 +699,9 @@ #ifdef DEBUG if (ldebug(clone)) - printf(LMSG("clone: successful rfork to %ld, stack %p sig = %d"), - (long)p2->p_pid, args->stack, exit_signal); + printf(LMSG("clone: successful rfork to %d, " + "stack %p sig = %d"), (int)p2->p_pid, args->stack, + exit_signal); #endif if (args->flags & LINUX_CLONE_VFORK) { PROC_LOCK(p2); @@ -719,12 +719,12 @@ td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; - + if (args->flags & LINUX_CLONE_VFORK) { - /* wait for the children to exit, ie. emulate vfork */ - PROC_LOCK(p2); + /* wait for the children to exit, ie. emulate vfork */ + PROC_LOCK(p2); while (p2->p_flag & P_PPWAIT) - msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0); + msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0); PROC_UNLOCK(p2); } @@ -743,8 +743,8 @@ #ifdef DEBUG if (ldebug(mmap2)) - printf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"), - (void *)(intptr_t)args->addr, args->len, args->prot, + printf(ARGS(mmap2, "0x%08x, %d, %d, 0x%08x, %d, %d"), + args->addr, args->len, args->prot, args->flags, args->fd, args->pgoff); #endif @@ -770,10 +770,9 @@ #ifdef DEBUG if (ldebug(mmap)) - printf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"), - (void *)(intptr_t)linux_args.addr, linux_args.len, - linux_args.prot, linux_args.flags, linux_args.fd, - linux_args.pgoff); + printf(ARGS(mmap, "0x%08x, %d, %d, 0x%08x, %d, %d"), + linux_args.addr, linux_args.len, linux_args.prot, + linux_args.flags, linux_args.fd, linux_args.pgoff); #endif if ((linux_args.pgoff % PAGE_SIZE) != 0) return (EINVAL); @@ -859,14 +858,14 @@ } if (linux_args->flags & LINUX_MAP_GROWSDOWN) { - /* - * The linux MAP_GROWSDOWN option does not limit auto + /* + * The Linux MAP_GROWSDOWN option does not limit auto * growth of the region. Linux mmap with this option * takes as addr the inital BOS, and as len, the initial * region size. It can then grow down from addr without - * limit. However, linux threads has an implicit internal + * limit. However, Linux threads has an implicit internal * limit to stack size of STACK_SIZE. Its just not - * enforced explicitly in linux. But, here we impose + * enforced explicitly in Linux. But, here we impose * a limit of (STACK_SIZE - GUARD_SIZE) on the stack * region, since we can do this with our mmap. * @@ -883,8 +882,8 @@ if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len > p->p_vmspace->vm_maxsaddr) { - /* - * Some linux apps will attempt to mmap + /* + * Some Linux apps will attempt to mmap * thread stacks near the top of their * address space. If their TOS is greater * than vm_maxsaddr, vm_map_growstack() @@ -911,7 +910,7 @@ else bsd_args.len = STACK_SIZE - GUARD_SIZE; - /* + /* * This gives us a new BOS. If we're using VM_STACK, then * mmap will just map the top SGROWSIZ bytes, and let * the stack grow down to the limit at BOS. If we're @@ -1044,7 +1043,7 @@ } /* - * Linux has two extra args, restart and oldmask. We dont use these, + * Linux has two extra args, restart and oldmask. We don't use these, * but it seems that "restart" is actually a context pointer that * enables the signal to happen with a different register set. */ ==== //depot/projects/smpng/sys/compat/linprocfs/linprocfs.c#56 (text+ko) ==== @@ -40,7 +40,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/compat/linprocfs/linprocfs.c,v 1.107 2007/03/12 12:16:52 des Exp $"); +__FBSDID("$FreeBSD: src/sys/compat/linprocfs/linprocfs.c,v 1.108 2007/03/30 17:56:44 jkim Exp $"); #include #include @@ -54,11 +54,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -1031,14 +1033,8 @@ static int linprocfs_domsgmni(PFS_FILL_ARGS) { - int msgmni; - size_t size; - size = sizeof(msgmni); - if (kernel_sysctlbyname(td, "kern.ipc.msgmni", &msgmni, &size, - 0, 0, 0, 0) != 0) - msgmni = 0; - sbuf_printf(sb, "%i\n", msgmni); + sbuf_printf(sb, "%d\n", msginfo.msgmni); return (0); } @@ -1061,34 +1057,9 @@ static int linprocfs_dosem(PFS_FILL_ARGS) { - int semmsl, semmns, semopm, semmni; - size_t size; - /* Field 1: SEMMSL */ - size = sizeof(semmsl); - if (kernel_sysctlbyname(td, "kern.ipc.semmsl", &semmsl, &size, - 0, 0, 0, 0) != 0) - semmsl = 0; - - /* Field 2: SEMMNS */ - size = sizeof(semmns); - if (kernel_sysctlbyname(td, "kern.ipc.semmns", &semmns, &size, - 0, 0, 0, 0) != 0) - semmns = 0; - - /* Field 3: SEMOPM */ - size = sizeof(semopm); - if (kernel_sysctlbyname(td, "kern.ipc.semopm", &semopm, &size, - 0, 0, 0, 0) != 0) - semopm = 0; - - /* Field 4: SEMMNI */ - size = sizeof(semmni); - if (kernel_sysctlbyname(td, "kern.ipc.semmni", &semmni, &size, - 0, 0, 0, 0) != 0) - semmni = 0; - - sbuf_printf(sb, "%i %i %i %i\n", semmsl, semmns, semopm, semmni); + sbuf_printf(sb, "%d %d %d %d\n", seminfo.semmsl, seminfo.semmns, + seminfo.semopm, seminfo.semmni); return (0); } ==== //depot/projects/smpng/sys/compat/linux/linux_futex.c#4 (text+ko) ==== @@ -32,7 +32,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/compat/linux/linux_futex.c,v 1.8 2007/02/25 12:43:07 netchild Exp $"); +__FBSDID("$FreeBSD: src/sys/compat/linux/linux_futex.c,v 1.9 2007/03/30 01:07:28 jkim Exp $"); #if 0 __KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.7 2006/07/24 19:01:49 manu Exp $"); #endif @@ -88,17 +88,15 @@ static struct futex *futex_get(void *, int); static void futex_put(struct futex *); static int futex_sleep(struct futex *, struct thread *, unsigned long); -static int futex_wake(struct futex *, int, struct futex *); -#ifdef __i386__ +static int futex_wake(struct futex *, int, struct futex *, int); static int futex_atomic_op(struct thread *td, int encoded_op, caddr_t uaddr); -#endif +static int futex_orl(int oparg, caddr_t uaddr, int *oldval); +static int futex_andl(int oparg, caddr_t uaddr, int *oldval); +static int futex_xorl(int oparg, caddr_t uaddr, int *oldval); /* support.s */ int futex_xchgl(int oparg, caddr_t uaddr, int *oldval); int futex_addl(int oparg, caddr_t uaddr, int *oldval); -int futex_orl(int oparg, caddr_t uaddr, int *oldval); -int futex_andnl(int oparg, caddr_t uaddr, int *oldval); -int futex_xorl(int oparg, caddr_t uaddr, int *oldval); int linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) @@ -111,10 +109,8 @@ struct futex *newf; int timeout_hz; struct timeval tv = {0, 0}; -#ifdef __i386__ struct futex *f2; int op_ret; -#endif #ifdef DEBUG if (ldebug(sys_futex)) @@ -192,7 +188,8 @@ case 0: /* FUTEX_WAKE received */ #ifdef DEBUG if (ldebug(sys_futex)) - printf("FUTEX_WAIT %d: uaddr = %p, got FUTEX_WAKE\n", + printf("FUTEX_WAIT %d: uaddr = %p, " + "got FUTEX_WAKE\n", td->td_proc->p_pid, args->uaddr); #endif return 0; @@ -200,7 +197,8 @@ default: #ifdef DEBUG if (ldebug(sys_futex)) - printf("FUTEX_WAIT: unexpected ret = %d\n", ret); + printf("FUTEX_WAIT: unexpected ret = %d\n", + ret); #endif break; } @@ -212,9 +210,9 @@ FUTEX_SYSTEM_LOCK; /* - * XXX: Linux is able cope with different addresses + * XXX: Linux is able to cope with different addresses * corresponding to the same mapped memory in the sleeping - * and the waker process. + * and waker process(es). */ #ifdef DEBUG if (ldebug(sys_futex)) @@ -222,7 +220,7 @@ td->td_proc->p_pid, args->uaddr, args->val); #endif f = futex_get(args->uaddr, FUTEX_UNLOCKED); - td->td_retval[0] = futex_wake(f, args->val, NULL); + td->td_retval[0] = futex_wake(f, args->val, NULL, 0); futex_put(f); FUTEX_SYSTEM_UNLOCK; @@ -244,7 +242,8 @@ f = futex_get(args->uaddr, FUTEX_UNLOCKED); newf = futex_get(args->uaddr2, FUTEX_UNLOCKED); - td->td_retval[0] = futex_wake(f, args->val, newf); + td->td_retval[0] = futex_wake(f, args->val, newf, + (int)(unsigned long)args->timeout); futex_put(f); futex_put(newf); @@ -253,29 +252,31 @@ case LINUX_FUTEX_REQUEUE: FUTEX_SYSTEM_LOCK; - + f = futex_get(args->uaddr, FUTEX_UNLOCKED); newf = futex_get(args->uaddr2, FUTEX_UNLOCKED); - td->td_retval[0] = futex_wake(f, args->val, newf); + td->td_retval[0] = futex_wake(f, args->val, newf, + (int)(unsigned long)args->timeout); futex_put(f); futex_put(newf); - + FUTEX_SYSTEM_UNLOCK; break; case LINUX_FUTEX_FD: - printf("linux_sys_futex: unimplemented op %d\n", + /* XXX: Linux plans to remove this operation */ + printf("linux_sys_futex: unimplemented op %d\n", args->op); break; case LINUX_FUTEX_WAKE_OP: -#ifdef __i386__ FUTEX_SYSTEM_LOCK; #ifdef DEBUG if (ldebug(sys_futex)) - printf("FUTEX_WAKE_OP: %d: uaddr = %p, op = %d, val = %d, uaddr2 = %p, val3 = %d\n", - td->td_proc->p_pid, args->uaddr, args->op, args->val, - args->uaddr2, args->val3); + printf("FUTEX_WAKE_OP: %d: uaddr = %p, op = %d, " + "val = %d, uaddr2 = %p, val3 = %d\n", + td->td_proc->p_pid, args->uaddr, args->op, + args->val, args->uaddr2, args->val3); #endif f = futex_get(args->uaddr, FUTEX_UNLOCKED); f2 = futex_get(args->uaddr2, FUTEX_UNLOCKED); @@ -287,7 +288,7 @@ op_ret = futex_atomic_op(td, args->val3, args->uaddr2); if (op_ret < 0) { - /* XXX: we dont handle the EFAULT yet */ + /* XXX: We don't handle the EFAULT yet. */ if (op_ret != -EFAULT) { futex_put(f); futex_put(f2); @@ -303,29 +304,26 @@ } - ret = futex_wake(f, args->val, NULL); + ret = futex_wake(f, args->val, NULL, 0); futex_put(f); if (op_ret > 0) { - op_ret = 0; - /* - * Linux uses the address of the timespec parameter - * as the number of retries, so any large number will - * be ok. + op_ret = 0; + /* + * Linux abuses the address of the timespec parameter + * as the number of retries. */ - op_ret += futex_wake(f2, 0x7fffffff, NULL); + op_ret += futex_wake(f2, + (int)(unsigned long)args->timeout, NULL, 0); ret += op_ret; } futex_put(f2); td->td_retval[0] = ret; FUTEX_SYSTEM_UNLOCK; -#else - printf("linux_sys_futex: wake_op not implemented"); -#endif - break; + break; default: - printf("linux_sys_futex: unknown op %d\n", + printf("linux_sys_futex: unknown op %d\n", args->op); break; } @@ -389,8 +387,8 @@ #ifdef DEBUG if (ldebug(sys_futex)) - printf("FUTEX --> %d tlseep timeout = %ld\n", td->td_proc->p_pid, - timeout); + printf("FUTEX --> %d tlseep timeout = %ld\n", + td->td_proc->p_pid, timeout); #endif ret = tsleep(wp, PCATCH | PZERO, "linuxfutex", timeout); #ifdef DEBUG @@ -414,10 +412,17 @@ } static int -futex_wake(struct futex *f, int n, struct futex *newf) +futex_wake(struct futex *f, int n, struct futex *newf, int n2) { struct waiting_proc *wp; - int count = 0; + int count; + + /* + * Linux is very strange it wakes up N threads for + * all operations BUT requeue ones where its N+1 + * mimic this. + */ + count = newf ? 0 : 1; FUTEX_LOCK; TAILQ_FOREACH(wp, &f->f_waiting_proc, wp_list) { @@ -427,8 +432,11 @@ } else { if (newf != NULL) { /* futex_put called after tsleep */ - wp->wp_new_futex = futex_get(newf->f_uaddr, FUTEX_LOCKED); + wp->wp_new_futex = futex_get(newf->f_uaddr, + FUTEX_LOCKED); wakeup_one(wp); + if (count - n >= n2) + break; } } } @@ -437,72 +445,106 @@ return count; } -#ifdef __i386__ static int futex_atomic_op(struct thread *td, int encoded_op, caddr_t uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; - int oldval = 0, ret; + int op = (encoded_op >> 28) & 7; + int cmp = (encoded_op >> 24) & 15; + int oparg = (encoded_op << 8) >> 20; + int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret; if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; + oparg = 1 << oparg; -#ifdef DEBUG - printf("futex_atomic_op: op = %d, cmp = %d, oparg = %d, cmparg = %d, uaddr = %p\n", - op, cmp, oparg, cmparg, uaddr); +#ifdef DEBUG + printf("futex_atomic_op: op = %d, cmp = %d, oparg = %d, cmparg = %d, " + "uaddr = %p\n", op, cmp, oparg, cmparg, uaddr); #endif /* XXX: linux verifies access here and returns EFAULT */ - critical_enter(); + switch (op) { + case FUTEX_OP_SET: + ret = futex_xchgl(oparg, uaddr, &oldval); + break; + case FUTEX_OP_ADD: + ret = futex_addl(oparg, uaddr, &oldval); + break; + case FUTEX_OP_OR: + ret = futex_orl(oparg, uaddr, &oldval); + break; + case FUTEX_OP_ANDN: + ret = futex_andl(~oparg, uaddr, &oldval); + break; + case FUTEX_OP_XOR: + ret = futex_xorl(oparg, uaddr, &oldval); + break; + default: + ret = -ENOSYS; + } - switch (op) { - case FUTEX_OP_SET: - ret = futex_xchgl(oparg, uaddr, &oldval); + if (!ret) + switch (cmp) { + case FUTEX_OP_CMP_EQ: + ret = (oldval == cmparg); + break; + case FUTEX_OP_CMP_NE: + ret = (oldval != cmparg); break; - case FUTEX_OP_ADD: - ret = futex_addl(oparg, uaddr, &oldval); + case FUTEX_OP_CMP_LT: + ret = (oldval < cmparg); break; - case FUTEX_OP_OR: - ret = futex_orl(oparg, uaddr, &oldval); + case FUTEX_OP_CMP_GE: + ret = (oldval >= cmparg); break; - case FUTEX_OP_ANDN: - ret = futex_andnl(oparg, uaddr, &oldval); + case FUTEX_OP_CMP_LE: + ret = (oldval <= cmparg); break; - case FUTEX_OP_XOR: - ret = futex_xorl(oparg, uaddr, &oldval); + case FUTEX_OP_CMP_GT: + ret = (oldval > cmparg); break; default: ret = -ENOSYS; + } + + return (ret); +} + +static int +futex_orl(int oparg, caddr_t uaddr, int *oldval) +{ + uint32_t ua, ua_old; + + for (;;) { + ua = ua_old = fuword32(uaddr); + ua |= oparg; + if (casuword32((void *)uaddr, ua_old, ua) == ua_old) + return ua_old; } +} - critical_exit(); +static int +futex_andl(int oparg, caddr_t uaddr, int *oldval) +{ + uint32_t ua, ua_old; + + for (;;) { + ua = ua_old = fuword32(uaddr); + ua &= oparg; + if (casuword32((void *)uaddr, ua_old, ua) == ua_old) + return ua_old; + } +} - if (!ret) - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: ret = -ENOSYS; - } +static int +futex_xorl(int oparg, caddr_t uaddr, int *oldval) +{ + uint32_t ua, ua_old; - return (ret); + for (;;) { + ua = ua_old = fuword32(uaddr); + ua ^= oparg; + if (casuword32((void *)uaddr, ua_old, ua) == ua_old) + return ua_old; + } } -#endif ==== //depot/projects/smpng/sys/dev/firewire/firewire.c#40 (text+ko) ==== @@ -31,7 +31,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/firewire/firewire.c,v 1.84 2007/03/16 05:39:33 simokawa Exp $ + * $FreeBSD: src/sys/dev/firewire/firewire.c,v 1.86 2007/03/30 15:43:56 simokawa Exp $ * */ @@ -355,7 +355,6 @@ "split transaction timeout dst=0x%x tl=0x%x state=%d\n", xfer->send.hdr.mode.hdr.dst, i, xfer->state); xfer->resp = ETIMEDOUT; - STAILQ_REMOVE_HEAD(&fc->tlabels[i], link); fw_xfer_done(xfer); } } @@ -420,7 +419,6 @@ bus_generic_attach(dev); /* bus_reset */ - fw_busreset(fc); fc->ibr(fc); return 0; @@ -1013,6 +1011,7 @@ if (xfer->fc == NULL) panic("fw_xfer_done: why xfer->fc is NULL?"); + fw_tl_free(xfer->fc, xfer); xfer->hand(xfer); } @@ -1039,7 +1038,6 @@ */ printf("fw_xfer_free FWXF_START\n"); #endif - fw_tl_free(xfer->fc, xfer); } xfer->state = FWXF_INIT; xfer->resp = 0; ==== //depot/projects/smpng/sys/geom/geom_ctl.c#26 (text+ko) ==== @@ -34,7 +34,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/geom/geom_ctl.c,v 1.38 2006/04/07 16:19:48 marcel Exp $"); +__FBSDID("$FreeBSD: src/sys/geom/geom_ctl.c,v 1.39 2007/03/30 16:32:08 delphij Exp $"); >>> TRUNCATED FOR MAIL (1000 lines) <<<