Date: Mon, 23 Jul 2007 15:55:16 GMT From: Roman Divacky <rdivacky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 123973 for review Message-ID: <200707231555.l6NFtGjo080281@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=123973 Change 123973 by rdivacky@rdivacky_witten on 2007/07/23 15:55:13 IFC Affected files ... .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/isa/clock.c#4 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/ndis/subr_ntoskrnl.c#3 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/conf/files#9 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/dev/acpica/acpi_hpet.c#4 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/dev/usb/usb_quirks.c#6 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/dev/usb/usbdevs#7 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/fs/msdosfs/msdosfs_vfsops.c#4 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/fs/tmpfs/tmpfs_vfsops.c#5 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/isa/clock.c#4 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/ia64/ia64/clock.c#2 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/kern_kse.c#3 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/kern_thread.c#4 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/subr_clock.c#2 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/netinet6/udp6_output.c#6 delete .. //depot/projects/soc2007/rdivacky/linux_at/sys/netinet6/udp6_usrreq.c#6 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/netinet6/udp6_var.h#3 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/pc98/cbus/clock.c#3 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/security/mac_mls/mac_mls.c#3 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/sparc64/sparc64/eeprom.c#3 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/sparc64/sparc64/rtc.c#3 integrate .. //depot/projects/soc2007/rdivacky/linux_at/sys/sys/proc.h#4 integrate Differences ... ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/isa/clock.c#4 (text+ko) ==== @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/isa/clock.c,v 1.232 2007/06/15 22:58:14 peter Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/isa/clock.c,v 1.233 2007/07/23 09:42:30 dwmalone Exp $"); /* * Routines to handle clock hardware. @@ -686,8 +686,7 @@ return; wrong_time: - printf("Invalid time in real time clock.\n"); - printf("Check and reset the date immediately!\n"); + printf("Invalid time in clock: check and reset the date!\n"); } /* ==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/ndis/subr_ntoskrnl.c#3 (text+ko) ==== @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/compat/ndis/subr_ntoskrnl.c,v 1.89 2007/06/05 00:00:50 jeff Exp $"); +__FBSDID("$FreeBSD: src/sys/compat/ndis/subr_ntoskrnl.c,v 1.90 2007/07/22 20:53:28 thompsa Exp $"); #include <sys/ctype.h> #include <sys/unistd.h> @@ -2778,6 +2778,7 @@ KeAcquireSpinLock(&kq->kq_lock, &irql); if (kq->kq_exit) { + kq->kq_exit = 0; KeReleaseSpinLock(&kq->kq_lock, irql); break; } @@ -2814,7 +2815,8 @@ kq = wq_queues + i; kq->kq_exit = 1; KeSetEvent(&kq->kq_proc, IO_NO_INCREMENT, FALSE); - tsleep(kq->kq_td->td_proc, PWAIT, "waitiw", 0); + while (kq->kq_exit) + tsleep(kq->kq_td->td_proc, PWAIT, "waitiw", hz/10); } return; @@ -3842,6 +3844,7 @@ KeAcquireSpinLock(&kq->kq_lock, &irql); if (kq->kq_exit) { + kq->kq_exit = 0; KeReleaseSpinLock(&kq->kq_lock, irql); break; } @@ -3891,7 +3894,8 @@ KeInitializeDpc(&dpc, NULL, NULL); KeSetTargetProcessorDpc(&dpc, i); KeInsertQueueDpc(&dpc, NULL, NULL); - tsleep(kq->kq_td->td_proc, PWAIT, "dpcw", 0); + while (kq->kq_exit) + tsleep(kq->kq_td->td_proc, PWAIT, "dpcw", hz/10); } return; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/conf/files#9 (text+ko) ==== @@ -1,4 +1,4 @@ -# $FreeBSD: src/sys/conf/files,v 1.1239 2007/07/19 16:15:58 gallatin Exp $ +# $FreeBSD: src/sys/conf/files,v 1.1240 2007/07/23 07:58:58 rwatson Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -1912,7 +1912,6 @@ netinet6/route6.c optional inet6 netinet6/scope6.c optional inet6 netinet6/sctp6_usrreq.c optional inet6 sctp -netinet6/udp6_output.c optional inet6 netinet6/udp6_usrreq.c optional inet6 netipsec/ipsec.c optional ipsec netipsec/ipsec_input.c optional ipsec ==== //depot/projects/soc2007/rdivacky/linux_at/sys/dev/acpica/acpi_hpet.c#4 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_hpet.c,v 1.9 2007/06/15 18:02:34 njl Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_hpet.c,v 1.10 2007/07/22 20:45:27 njl Exp $"); #include "opt_acpi.h" #include <sys/param.h> @@ -140,7 +140,7 @@ { struct acpi_hpet_softc *sc; int rid; - uint32_t val; + uint32_t val, val2; uintmax_t freq; ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); @@ -163,6 +163,9 @@ return (ENXIO); } + /* Be sure timer is enabled. */ + bus_write_4(sc->mem_res, HPET_OFFSET_ENABLE, 1); + /* Read basic statistics about the timer. */ val = bus_read_4(sc->mem_res, HPET_OFFSET_PERIOD); freq = (1000000000000000LL + val / 2) / val; @@ -175,12 +178,23 @@ ((val >> 13) & 1) ? " count_size" : ""); } - /* Be sure it is enabled. */ - bus_write_4(sc->mem_res, HPET_OFFSET_ENABLE, 1); - if (testenv("debug.acpi.hpet_test")) acpi_hpet_test(sc); + /* + * Don't attach if the timer never increments. Since the spec + * requires it to be at least 10 MHz, it has to change in 1 us. + */ + val = bus_read_4(sc->mem_res, HPET_OFFSET_VALUE); + DELAY(1); + val2 = bus_read_4(sc->mem_res, HPET_OFFSET_VALUE); + if (val == val2) { + device_printf(dev, "HPET never increments, disabling\n"); + bus_write_4(sc->mem_res, HPET_OFFSET_ENABLE, 0); + bus_free_resource(dev, SYS_RES_MEMORY, sc->mem_res); + return (ENXIO); + } + hpet_timecounter.tc_frequency = freq; hpet_timecounter.tc_priv = sc; tc_init(&hpet_timecounter); ==== //depot/projects/soc2007/rdivacky/linux_at/sys/dev/usb/usb_quirks.c#6 (text+ko) ==== @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.62 2007/07/10 21:00:10 imp Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.63 2007/07/22 15:59:45 imp Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -108,7 +108,7 @@ /* Devices which should be ignored by both ukbd and uhid */ { USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_WISPY, ANY, { UQ_KBD_IGNORE }}, - { USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY, + { USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPYX, ANY, { UQ_KBD_IGNORE }}, { 0, 0, 0, { 0 } } }; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/dev/usb/usbdevs#7 (text+ko) ==== @@ -1,4 +1,4 @@ -$FreeBSD: src/sys/dev/usb/usbdevs,v 1.324 2007/07/22 03:45:35 imp Exp $ +$FreeBSD: src/sys/dev/usb/usbdevs,v 1.325 2007/07/22 18:29:18 imp Exp $ /* $NetBSD: usbdevs,v 1.392 2004/12/29 08:38:44 imp Exp $ */ /*- @@ -1562,7 +1562,7 @@ product MELCO G54HP 0x00d9 WLI-U2-G54HP /* MetaGeek products */ -product METAGEEK WISPYX 0x083e MetaGeek Wi-Spy +product METAGEEK WISPYX 0x083e MetaGeek Wi-Spy 2.4x /* Metricom products */ product METRICOM RICOCHET_GS 0x0001 Ricochet GS ==== //depot/projects/soc2007/rdivacky/linux_at/sys/fs/msdosfs/msdosfs_vfsops.c#4 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/fs/msdosfs/msdosfs_vfsops.c,v 1.166 2007/07/12 17:17:47 bde Exp $ */ +/* $FreeBSD: src/sys/fs/msdosfs/msdosfs_vfsops.c,v 1.167 2007/07/23 07:10:17 bde Exp $ */ /* $NetBSD: msdosfs_vfsops.c,v 1.51 1997/11/17 15:36:58 ws Exp $ */ /*- @@ -279,9 +279,12 @@ return (error); DROP_GIANT(); g_topology_lock(); - g_access(pmp->pm_cp, 0, -1, 0); + error = g_access(pmp->pm_cp, 0, -1, 0); g_topology_unlock(); PICKUP_GIANT(); + if (error) + return (error); + /* Now the volume is clean. Mark it. */ error = markvoldirty(pmp, 0); if (error && (flags & FORCECLOSE) == 0) @@ -402,11 +405,11 @@ struct g_consumer *cp; struct bufobj *bo; - ronly = !vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL); + ronly = (mp->mnt_flag & MNT_RDONLY) != 0; /* XXX: use VOP_ACCESS to check FS perms */ DROP_GIANT(); g_topology_lock(); - error = g_vfs_open(devvp, &cp, "msdos", ronly ? 0 : 1); + error = g_vfs_open(devvp, &cp, "msdosfs", ronly ? 0 : 1); g_topology_unlock(); PICKUP_GIANT(); VOP_UNLOCK(devvp, 0, td); @@ -446,6 +449,15 @@ pmp->pm_bo = bo; /* + * Initialize ownerships and permissions, since nothing else will + * initialize them iff we are mounting root. + */ + pmp->pm_uid = UID_ROOT; + pmp->pm_gid = GID_WHEEL; + pmp->pm_mask = pmp->pm_dirmask = S_IXUSR | S_IXGRP | S_IXOTH | + S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR; + + /* * Experimental support for large MS-DOS filesystems. * WARNING: This uses at least 32 bytes of kernel memory (which is not * reclaimed until the FS is unmounted) for each file on disk to map ==== //depot/projects/soc2007/rdivacky/linux_at/sys/fs/tmpfs/tmpfs_vfsops.c#5 (text+ko) ==== @@ -48,7 +48,7 @@ * allocate and release resources. */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/fs/tmpfs/tmpfs_vfsops.c,v 1.6 2007/07/11 14:26:27 delphij Exp $"); +__FBSDID("$FreeBSD: src/sys/fs/tmpfs/tmpfs_vfsops.c,v 1.7 2007/07/23 06:54:58 delphij Exp $"); #include <sys/param.h> #include <sys/limits.h> @@ -268,7 +268,7 @@ mtx_init(&tmp->allnode_lock, "tmpfs allnode lock", NULL, MTX_DEF); tmp->tm_nodes_max = nodes; tmp->tm_nodes_inuse = 0; - tmp->tm_maxfilesize = get_swpgtotal() * PAGE_SIZE; + tmp->tm_maxfilesize = (cnt.v_page_count + get_swpgtotal()) * PAGE_SIZE; LIST_INIT(&tmp->tm_nodes_used); tmp->tm_pages_max = pages; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/isa/clock.c#4 (text+ko) ==== @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/i386/isa/clock.c,v 1.237 2007/06/15 22:58:13 peter Exp $"); +__FBSDID("$FreeBSD: src/sys/i386/isa/clock.c,v 1.238 2007/07/23 09:42:31 dwmalone Exp $"); /* * Routines to handle clock hardware. @@ -679,8 +679,7 @@ /* Look if we have a RTC present and the time is valid */ if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) { - printf("Invalid time in real time clock.\n"); - printf("Check and reset the date immediately!\n"); + printf("Invalid time in clock: check and reset the date!\n"); return; } @@ -704,7 +703,11 @@ #else ct.year += 2000; #endif - clock_ct_to_ts(&ct, &ts); + /* Should we set dow = -1 because some clocks don't set it correctly? */ + if (clock_ct_to_ts(&ct, &ts)) { + printf("Invalid time in clock: check and reset the date!\n"); + return; + } ts.tv_sec += utc_offset(); tc_setclock(&ts); } ==== //depot/projects/soc2007/rdivacky/linux_at/sys/ia64/ia64/clock.c#2 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/ia64/ia64/clock.c,v 1.30 2006/10/19 00:53:35 marcel Exp $"); +__FBSDID("$FreeBSD: src/sys/ia64/ia64/clock.c,v 1.31 2007/07/23 09:42:31 dwmalone Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -142,7 +142,8 @@ ct.mon = tm.tm_mon; ct.year = tm.tm_year; ct.dow = -1; - clock_ct_to_ts(&ct, &ts); + if (clock_ct_to_ts(&ct, &ts)) + printf("Invalid time in clock: check and reset the date!\n"); ts.tv_sec += utc_offset(); /* ==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/kern_kse.c#3 (text+ko) ==== @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/kern/kern_kse.c,v 1.231 2007/06/12 19:49:39 jeff Exp $"); +__FBSDID("$FreeBSD: src/sys/kern/kern_kse.c,v 1.232 2007/07/23 14:52:21 attilio Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -68,9 +68,6 @@ static struct thread *thread_schedule_upcall(struct thread *td, struct kse_upcall *ku); static struct kse_upcall *upcall_alloc(void); static void upcall_free(struct kse_upcall *ku); -static void upcall_link(struct kse_upcall *ku, struct proc *p); -static void upcall_unlink(struct kse_upcall *ku); -static void upcall_stash(struct kse_upcall *ke); struct mtx kse_lock; @@ -93,30 +90,11 @@ } void -upcall_link(struct kse_upcall *ku, struct proc *p) -{ - - PROC_SLOCK_ASSERT(p, MA_OWNED); - TAILQ_INSERT_TAIL(&p->p_upcalls, ku, ku_link); - ku->ku_proc = p; -} - -void -upcall_unlink(struct kse_upcall *ku) -{ - struct proc *p = ku->ku_proc; - - PROC_SLOCK_ASSERT(p, MA_OWNED); - KASSERT(ku->ku_owner == NULL, ("%s: have owner", __func__)); - TAILQ_REMOVE(&p->p_upcalls, ku, ku_link); - upcall_stash(ku); -} - -void upcall_remove(struct thread *td) { PROC_SLOCK_ASSERT(td->td_proc, MA_OWNED); + THREAD_LOCK_ASSERT(td, MA_OWNED); if (td->td_upcall != NULL) { /* * If we are not a bound thread then decrement the count of @@ -124,8 +102,12 @@ */ if (td->td_pflags & TDP_SA) td->td_proc->p_numupcalls--; + mtx_lock_spin(&kse_lock); td->td_upcall->ku_owner = NULL; - upcall_unlink(td->td_upcall); + TAILQ_REMOVE(&td->td_upcall->ku_proc->p_upcalls, td->td_upcall, + ku_link); + TAILQ_INSERT_HEAD(&zombie_upcalls, td->td_upcall, ku_link); + mtx_unlock_spin(&kse_lock); td->td_upcall = NULL; } } @@ -157,8 +139,12 @@ struct kse_upcall *ku; int error; - if ((ku = td->td_upcall) == NULL || TD_CAN_UNBIND(td)) + thread_lock(td); + if ((ku = td->td_upcall) == NULL || TD_CAN_UNBIND(td)) { + thread_unlock(td); return (EINVAL); + } + thread_unlock(td); error = (uap->tmbx == NULL) ? EINVAL : 0; if (!error) error = copyin(uap->tmbx, &tmbx, sizeof(tmbx)); @@ -181,11 +167,11 @@ else ptrace_clear_single_step(td); if (tmbx.tm_dflags & TMDF_SUSPEND) { - PROC_SLOCK(td->td_proc); + thread_lock(td); /* fuword can block, check again */ if (td->td_upcall) ku->ku_flags |= KUF_DOUPCALL; - PROC_SUNLOCK(td->td_proc); + thread_unlock(td); } _PRELE(td->td_proc); } @@ -219,8 +205,12 @@ p = td->td_proc; - if (!(p->p_flag & P_SA)) + PROC_LOCK(p); + if (!(p->p_flag & P_SA)) { + PROC_UNLOCK(p); return (EINVAL); + } + PROC_UNLOCK(p); switch (uap->cmd) { case KSE_INTR_SENDSIG: @@ -274,16 +264,18 @@ /* this sub-function is only for bound thread */ if (td->td_pflags & TDP_SA) return (EINVAL); + thread_lock(td); ku = td->td_upcall; + thread_unlock(td); tmbx = (void *)fuword((void *)&ku->ku_mailbox->km_curthread); if (tmbx == NULL || tmbx == (void *)-1) return (EINVAL); flags = 0; + PROC_LOCK(p); while ((p->p_flag & P_TRACED) && !(p->p_flag & P_SINGLE_EXIT)) { flags = fuword32(&tmbx->tm_dflags); if (!(flags & TMDF_SUSPEND)) break; - PROC_LOCK(p); PROC_SLOCK(p); thread_stopped(p); PROC_UNLOCK(p); @@ -292,7 +284,9 @@ PROC_SUNLOCK(p); mi_switch(SW_VOL, NULL); thread_unlock(td); + PROC_LOCK(p); } + PROC_UNLOCK(p); return (0); case KSE_INTR_EXECVE: @@ -338,9 +332,12 @@ /* * Ensure that this is only called from the UTS */ - if ((ku = td->td_upcall) == NULL || TD_CAN_UNBIND(td)) + thread_lock(td); + if ((ku = td->td_upcall) == NULL || TD_CAN_UNBIND(td)) { + thread_unlock(td); return (EINVAL); - + } + thread_unlock(td); /* * Calculate the existing non-exiting upcalls in this process. @@ -384,7 +381,9 @@ psignal(p, SIGSEGV); sigqueue_flush(&td->td_sigqueue); PROC_SLOCK(p); + thread_lock(td); upcall_remove(td); + thread_unlock(td); if (p->p_numthreads != 1) { thread_stopped(p); thread_exit(); @@ -435,10 +434,13 @@ int error; p = td->td_proc; + thread_lock(td); if ((ku = td->td_upcall) == NULL || TD_CAN_UNBIND(td)) { + thread_unlock(td); printf("kse_release: called outside of threading. exiting"); exit1(td, 0); } + thread_unlock(td); if (uap->timeout != NULL) { if ((error = copyin(uap->timeout, &timeout, sizeof(timeout)))) return (error); @@ -508,9 +510,11 @@ td2 = NULL; ku = NULL; /* KSE-enabled processes only, please. */ - if (!(p->p_flag & P_SA)) + PROC_LOCK(p); + if (!(p->p_flag & P_SA)) { + PROC_UNLOCK(p); return (EINVAL); - PROC_LOCK(p); + } PROC_SLOCK(p); if (uap->mbx) { FOREACH_UPCALL_IN_PROC(p, ku) { @@ -531,10 +535,14 @@ PROC_UNLOCK(p); return (ESRCH); } + mtx_lock_spin(&kse_lock); if ((td2 = ku->ku_owner) == NULL) { + mtx_unlock_spin(&kse_lock); PROC_SUNLOCK(p); + PROC_UNLOCK(p); panic("%s: no owner", __func__); } else if (td2->td_kflags & (TDK_KSEREL | TDK_KSERELSIG)) { + mtx_unlock_spin(&kse_lock); if (!(td2->td_kflags & TDK_WAKEUP)) { td2->td_kflags |= TDK_WAKEUP; if (td2->td_kflags & TDK_KSEREL) @@ -544,6 +552,7 @@ } } else { ku->ku_flags |= KUF_DOUPCALL; + mtx_unlock_spin(&kse_lock); } PROC_SUNLOCK(p); PROC_UNLOCK(p); @@ -582,6 +591,7 @@ * suddenly start calling this one * XXX maybe... */ + PROC_LOCK(p); if ((p->p_flag & (P_SA|P_HADTHREADS)) == P_HADTHREADS) { PROC_UNLOCK(p); return (EINVAL); @@ -590,6 +600,7 @@ first = 1; p->p_flag |= P_SA|P_HADTHREADS; } + PROC_UNLOCK(p); if ((err = copyin(uap->mbx, &mbx, sizeof(mbx)))) return (err); @@ -662,7 +673,8 @@ * Make the new upcall available to the process. * It may or may not use it, but it's available. */ - upcall_link(newku, p); + TAILQ_INSERT_TAIL(&p->p_upcalls, newku, ku_link); + newku->ku_proc = p; PROC_UNLOCK(p); if (mbx.km_quantum) /* XXX should this be in the thread? */ @@ -786,44 +798,6 @@ } /* - * Stash an embarasingly extra upcall into the zombie upcall queue. - */ - -void -upcall_stash(struct kse_upcall *ku) -{ - mtx_lock_spin(&kse_lock); - TAILQ_INSERT_HEAD(&zombie_upcalls, ku, ku_link); - mtx_unlock_spin(&kse_lock); -} - -/* - * Reap zombie kse resource. - */ -void -kse_GC(void) -{ - struct kse_upcall *ku_first, *ku_next; - - /* - * Don't even bother to lock if none at this instant, - * we really don't care about the next instant.. - */ - if (!TAILQ_EMPTY(&zombie_upcalls)) { - mtx_lock_spin(&kse_lock); - ku_first = TAILQ_FIRST(&zombie_upcalls); - if (ku_first) - TAILQ_INIT(&zombie_upcalls); - mtx_unlock_spin(&kse_lock); - while (ku_first) { - ku_next = TAILQ_NEXT(ku_first, ku_link); - upcall_free(ku_first); - ku_first = ku_next; - } - } -} - -/* * Store the thread context in the UTS's mailbox. * then add the mailbox at the head of a list we are building in user space. * The list is anchored in the proc structure. @@ -885,6 +859,7 @@ } PROC_LOCK(p); if (mbx == (uintptr_t)p->p_completed) { + thread_lock(td); p->p_completed = td->td_mailbox; /* * The thread context may be taken away by @@ -893,6 +868,7 @@ * use it again in any other places. */ td->td_mailbox = NULL; + thread_unlock(td); PROC_UNLOCK(p); break; } @@ -968,8 +944,12 @@ caddr_t addr; u_int uticks; - if (td->td_mailbox == NULL) + thread_lock(td); + if (td->td_mailbox == NULL) { + thread_unlock(td); return (-1); + } + thread_unlock(td); if ((uticks = td->td_uuticks) != 0) { td->td_uuticks = 0; @@ -1173,7 +1153,9 @@ * note where our mailbox is. */ + thread_lock(td); ku = td->td_upcall; + thread_unlock(td); KASSERT(ku != NULL, ("no upcall owned")); KASSERT(ku->ku_owner == td, ("wrong owner")); @@ -1200,16 +1182,18 @@ } else { td->td_mailbox = tmbx; td->td_pflags |= TDP_CAN_UNBIND; + PROC_LOCK(p); if (__predict_false(p->p_flag & P_TRACED)) { flags = fuword32(&tmbx->tm_dflags); if (flags & TMDF_SUSPEND) { - PROC_SLOCK(td->td_proc); + thread_lock(td); /* fuword can block, check again */ if (td->td_upcall) ku->ku_flags |= KUF_DOUPCALL; - PROC_SUNLOCK(td->td_proc); + thread_unlock(td); } } + PROC_UNLOCK(p); } } } @@ -1249,6 +1233,7 @@ } p = td->td_proc; + thread_lock(td); ku = td->td_upcall; /* @@ -1258,6 +1243,7 @@ * then it can return direct to userland. */ if (TD_CAN_UNBIND(td)) { + thread_unlock(td); td->td_pflags &= ~TDP_CAN_UNBIND; if ((td->td_flags & TDF_NEEDSIGCHK) == 0 && (p->p_completed == NULL) && @@ -1281,6 +1267,7 @@ */ td->td_pflags |= TDP_UPCALLING; } else if (td->td_mailbox && (ku == NULL)) { + thread_unlock(td); thread_export_context(td, 1); PROC_LOCK(p); if (p->p_upsleeps) @@ -1292,15 +1279,16 @@ thread_stopped(p); thread_exit(); /* NOTREACHED */ - } + } else + thread_unlock(td); KASSERT(ku != NULL, ("upcall is NULL")); KASSERT(TD_CAN_UNBIND(td) == 0, ("can unbind")); + PROC_LOCK(p); + PROC_SLOCK(p); if (p->p_numthreads > max_threads_per_proc) { max_threads_hits++; - PROC_LOCK(p); - PROC_SLOCK(p); while (p->p_numthreads > max_threads_per_proc) { if (p->p_numupcalls >= max_threads_per_proc) break; @@ -1309,13 +1297,12 @@ "maxthreads", hz/10) != EWOULDBLOCK) { PROC_SLOCK(p); break; - } else { + } else PROC_SLOCK(p); - } } - PROC_SUNLOCK(p); - PROC_UNLOCK(p); } + PROC_SUNLOCK(p); + PROC_UNLOCK(p); if (td->td_pflags & TDP_UPCALLING) { uts_crit = 0; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/kern_thread.c#4 (text+ko) ==== @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/kern/kern_thread.c,v 1.250 2007/06/12 19:49:39 jeff Exp $"); +__FBSDID("$FreeBSD: src/sys/kern/kern_thread.c,v 1.251 2007/07/23 14:52:21 attilio Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -550,7 +550,9 @@ KASSERT((p->p_numthreads == 1), ("Unthreading with >1 threads")); #ifdef KSE + thread_lock(td); upcall_remove(td); + thread_unlock(td); p->p_flag &= ~(P_SA|P_HADTHREADS); td->td_mailbox = NULL; td->td_pflags &= ~(TDP_SA | TDP_CAN_UNBIND); ==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/subr_clock.c#2 (text+ko) ==== @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/kern/subr_clock.c,v 1.11 2006/10/02 18:23:37 phk Exp $"); +__FBSDID("$FreeBSD: src/sys/kern/subr_clock.c,v 1.12 2007/07/23 09:42:31 dwmalone Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -151,7 +151,7 @@ days += days_in_month(year, i); days += (ct->day - 1); - /* Another sanity check. */ + /* XXX Dow sanity check. Dow is not used, so should we check it? */ if (ct->dow != -1 && ct->dow != day_of_week(days)) return (EINVAL); ==== //depot/projects/soc2007/rdivacky/linux_at/sys/netinet6/udp6_usrreq.c#6 (text+ko) ==== @@ -1,5 +1,6 @@ -/* $FreeBSD: src/sys/netinet6/udp6_usrreq.c,v 1.78 2007/07/19 22:34:25 rwatson Exp $ */ +/* $FreeBSD: src/sys/netinet6/udp6_usrreq.c,v 1.79 2007/07/23 07:58:58 rwatson Exp $ */ /* $KAME: udp6_usrreq.c,v 1.27 2001/05/21 05:45:10 jinmei Exp $ */ +/* $KAME: udp6_output.c,v 1.31 2001/05/21 16:39:15 jinmei Exp $ */ /*- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -468,6 +469,231 @@ SYSCTL_PROC(_net_inet6_udp6, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW, 0, 0, udp6_getcred, "S,xucred", "Get the xucred of a UDP6 connection"); +#define in6pcb inpcb +#define udp6stat udpstat +#define udp6s_opackets udps_opackets + +static int +udp6_output(struct in6pcb *in6p, struct mbuf *m, struct sockaddr *addr6, + struct mbuf *control, struct thread *td) +{ + u_int32_t ulen = m->m_pkthdr.len; + u_int32_t plen = sizeof(struct udphdr) + ulen; + struct ip6_hdr *ip6; + struct udphdr *udp6; + struct in6_addr *laddr, *faddr; + struct sockaddr_in6 *sin6 = NULL; + struct ifnet *oifp = NULL; + int scope_ambiguous = 0; + u_short fport; + int error = 0; + struct ip6_pktopts *optp, opt; + int priv; + int af = AF_INET6, hlen = sizeof(struct ip6_hdr); + int flags; + struct sockaddr_in6 tmp; + + INP_LOCK_ASSERT(in6p); + + priv = 0; + if (td && !suser(td)) + priv = 1; + + if (addr6) { + /* addr6 has been validated in udp6_send(). */ + sin6 = (struct sockaddr_in6 *)addr6; + + /* protect *sin6 from overwrites */ + tmp = *sin6; + sin6 = &tmp; + + /* + * Application should provide a proper zone ID or the use of + * default zone IDs should be enabled. Unfortunately, some + * applications do not behave as it should, so we need a + * workaround. Even if an appropriate ID is not determined, + * we'll see if we can determine the outgoing interface. If we + * can, determine the zone ID based on the interface below. + */ + if (sin6->sin6_scope_id == 0 && !ip6_use_defzone) + scope_ambiguous = 1; + if ((error = sa6_embedscope(sin6, ip6_use_defzone)) != 0) + return (error); + } + + if (control) { + if ((error = ip6_setpktopts(control, &opt, + in6p->in6p_outputopts, priv, IPPROTO_UDP)) != 0) + goto release; + optp = &opt; + } else + optp = in6p->in6p_outputopts; + + if (sin6) { + faddr = &sin6->sin6_addr; + + /* + * IPv4 version of udp_output calls in_pcbconnect in this case, + * which needs splnet and affects performance. + * Since we saw no essential reason for calling in_pcbconnect, + * we get rid of such kind of logic, and call in6_selectsrc + * and in6_pcbsetport in order to fill in the local address + * and the local port. + */ + if (sin6->sin6_port == 0) { + error = EADDRNOTAVAIL; + goto release; + } + + if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) { + /* how about ::ffff:0.0.0.0 case? */ + error = EISCONN; + goto release; + } + + fport = sin6->sin6_port; /* allow 0 port */ + + if (IN6_IS_ADDR_V4MAPPED(faddr)) { + if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY)) { + /* + * I believe we should explicitly discard the + * packet when mapped addresses are disabled, + * rather than send the packet as an IPv6 one. + * If we chose the latter approach, the packet + * might be sent out on the wire based on the + * default route, the situation which we'd + * probably want to avoid. + * (20010421 jinmei@kame.net) + */ + error = EINVAL; + goto release; + } + if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) && + !IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr)) { + /* + * when remote addr is an IPv4-mapped address, + * local addr should not be an IPv6 address, + * since you cannot determine how to map IPv6 + * source address to IPv4. + */ + error = EINVAL; + goto release; + } + + af = AF_INET; + } + + if (!IN6_IS_ADDR_V4MAPPED(faddr)) { + laddr = in6_selectsrc(sin6, optp, in6p->in6p_moptions, + NULL, &in6p->in6p_laddr, &oifp, &error); + if (oifp && scope_ambiguous && + (error = in6_setscope(&sin6->sin6_addr, + oifp, NULL))) { + goto release; + } + } else + laddr = &in6p->in6p_laddr; /* XXX */ + if (laddr == NULL) { + if (error == 0) + error = EADDRNOTAVAIL; + goto release; + } + if (in6p->in6p_lport == 0 && + (error = in6_pcbsetport(laddr, in6p, td->td_ucred)) != 0) + goto release; + } else { + if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) { + error = ENOTCONN; + goto release; + } + if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_faddr)) { + if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY)) { + /* + * XXX: this case would happen when the + * application sets the V6ONLY flag after + * connecting the foreign address. + * Such applications should be fixed, + * so we bark here. + */ + log(LOG_INFO, "udp6_output: IPV6_V6ONLY " + "option was set for a connected socket\n"); + error = EINVAL; + goto release; + } else + af = AF_INET; + } + laddr = &in6p->in6p_laddr; + faddr = &in6p->in6p_faddr; + fport = in6p->in6p_fport; + } + + if (af == AF_INET) + hlen = sizeof(struct ip); + + /* + * Calculate data length and get a mbuf + * for UDP and IP6 headers. + */ + M_PREPEND(m, hlen + sizeof(struct udphdr), M_DONTWAIT); + if (m == 0) { + error = ENOBUFS; + goto release; + } + + /* + * Stuff checksum and output datagram. + */ + udp6 = (struct udphdr *)(mtod(m, caddr_t) + hlen); + udp6->uh_sport = in6p->in6p_lport; /* lport is always set in the PCB */ + udp6->uh_dport = fport; + if (plen <= 0xffff) + udp6->uh_ulen = htons((u_short)plen); + else + udp6->uh_ulen = 0; + udp6->uh_sum = 0; + + switch (af) { + case AF_INET6: + ip6 = mtod(m, struct ip6_hdr *); + ip6->ip6_flow = in6p->in6p_flowinfo & IPV6_FLOWINFO_MASK; + ip6->ip6_vfc &= ~IPV6_VERSION_MASK; + ip6->ip6_vfc |= IPV6_VERSION; >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707231555.l6NFtGjo080281>