PERFORCE change 116967 for review
John Baldwin
jhb at FreeBSD.org
Fri Mar 30 20:12:28 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=116967
Change 116967 by jhb at 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 <sys/cdefs.h>
-__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 <sys/param.h>
#include <sys/kernel.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
#include <sys/queue.h>
@@ -54,11 +54,13 @@
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mount.h>
+#include <sys/msg.h>
#include <sys/mutex.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/sbuf.h>
+#include <sys/sem.h>
#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/cdefs.h>
-__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) <<<
More information about the p4-projects
mailing list