diff options
author | dim <dim@FreeBSD.org> | 2010-11-16 10:33:41 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2010-11-16 10:33:41 +0000 |
commit | b0df1c137c1d7cc6c086e8c3de63b91a97e180c7 (patch) | |
tree | 56f0dadc92981a1efbf66b53a434baa21a8c2c82 /sys | |
parent | b355314642d1e24edf4e05d08b793f8b9ea76458 (diff) | |
download | FreeBSD-src-b0df1c137c1d7cc6c086e8c3de63b91a97e180c7.zip FreeBSD-src-b0df1c137c1d7cc6c086e8c3de63b91a97e180c7.tar.gz |
Sync: merge r215319 through r215395 from ^/head, so ports can actually
build! :)
Diffstat (limited to 'sys')
39 files changed, 343 insertions, 204 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index a1a3ebc..e5184a6 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -416,8 +416,7 @@ trap(struct trapframe *frame) * without the ABI-tag ELF note. */ if (SV_CURPROC_ABI() == SV_ABI_FREEBSD - && p->p_osrel >= - __FreeBSD_version_SIGSEGV) { + && p->p_osrel >= P_OSREL_SIGSEGV) { i = SIGSEGV; ucode = SEGV_ACCERR; } else { diff --git a/sys/arm/xscale/ixp425/avila_gpio.c b/sys/arm/xscale/ixp425/avila_gpio.c index 82103a1..cb73001 100644 --- a/sys/arm/xscale/ixp425/avila_gpio.c +++ b/sys/arm/xscale/ixp425/avila_gpio.c @@ -58,13 +58,8 @@ __FBSDID("$FreeBSD$"); #define GPIO_CLEAR_BITS(sc, reg, bits) \ GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, (reg)) & ~(bits)) -#define GPIO_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) -#define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) -#define GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) - struct avila_gpio_softc { device_t sc_dev; - struct mtx sc_mtx; bus_space_tag_t sc_iot; bus_space_handle_t sc_gpio_ioh; uint32_t sc_valid; @@ -148,12 +143,12 @@ avila_gpio_pin_configure(struct avila_gpio_softc *sc, struct gpio_pin *pin, uint32_t mask; mask = 1 << pin->gp_pin; - GPIO_LOCK(sc); /* * Manage input/output */ if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { + IXP4XX_GPIO_LOCK(sc); pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); if (flags & GPIO_PIN_OUTPUT) { pin->gp_flags |= GPIO_PIN_OUTPUT; @@ -163,9 +158,8 @@ avila_gpio_pin_configure(struct avila_gpio_softc *sc, struct gpio_pin *pin, pin->gp_flags |= GPIO_PIN_INPUT; GPIO_SET_BITS(sc, IXP425_GPIO_GPOER, mask); } + IXP4XX_GPIO_UNLOCK(sc); } - - GPIO_UNLOCK(sc); } static int @@ -184,10 +178,7 @@ avila_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin))) return (EINVAL); - GPIO_LOCK(sc); *caps = sc->sc_pins[pin].gp_caps; - GPIO_UNLOCK(sc); - return (0); } @@ -199,11 +190,11 @@ avila_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin))) return (EINVAL); - GPIO_LOCK(sc); + IXP4XX_GPIO_LOCK(sc); /* refresh since we do not own all the pins */ sc->sc_pins[pin].gp_flags = avila_gpio_pin_flags(sc, pin); *flags = sc->sc_pins[pin].gp_flags; - GPIO_UNLOCK(sc); + IXP4XX_GPIO_UNLOCK(sc); return (0); } @@ -216,10 +207,7 @@ avila_gpio_pin_getname(device_t dev, uint32_t pin, char *name) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin))) return (EINVAL); - GPIO_LOCK(sc); memcpy(name, sc->sc_pins[pin].gp_name, GPIOMAXNAME); - GPIO_UNLOCK(sc); - return (0); } @@ -254,12 +242,12 @@ avila_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & mask)) return (EINVAL); - GPIO_LOCK(sc); + IXP4XX_GPIO_LOCK(sc); if (value) GPIO_SET_BITS(sc, IXP425_GPIO_GPOUTR, mask); else GPIO_CLEAR_BITS(sc, IXP425_GPIO_GPOUTR, mask); - GPIO_UNLOCK(sc); + IXP4XX_GPIO_UNLOCK(sc); return (0); } @@ -272,9 +260,9 @@ avila_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin))) return (EINVAL); - GPIO_LOCK(sc); + IXP4XX_GPIO_LOCK(sc); *val = (GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & (1 << pin)) ? 1 : 0; - GPIO_UNLOCK(sc); + IXP4XX_GPIO_UNLOCK(sc); return (0); } @@ -289,13 +277,13 @@ avila_gpio_pin_toggle(device_t dev, uint32_t pin) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & mask)) return (EINVAL); - GPIO_LOCK(sc); - res = (GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & mask) ? 1 : 0; + IXP4XX_GPIO_LOCK(sc); + res = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & mask; if (res) GPIO_CLEAR_BITS(sc, IXP425_GPIO_GPOUTR, mask); else GPIO_SET_BITS(sc, IXP425_GPIO_GPOUTR, mask); - GPIO_UNLOCK(sc); + IXP4XX_GPIO_UNLOCK(sc); return (0); } @@ -320,9 +308,6 @@ avila_gpio_attach(device_t dev) sc->sc_iot = sa->sc_iot; sc->sc_gpio_ioh = sa->sc_gpio_ioh; - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF); - for (i = 0; i < N(avila_gpio_pins); i++) { struct avila_gpio_pin *p = &avila_gpio_pins[i]; @@ -342,14 +327,9 @@ avila_gpio_attach(device_t dev) static int avila_gpio_detach(device_t dev) { - struct avila_gpio_softc *sc = device_get_softc(dev); - - KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized")); bus_generic_detach(dev); - mtx_destroy(&sc->sc_mtx); - return(0); } diff --git a/sys/arm/xscale/ixp425/avila_led.c b/sys/arm/xscale/ixp425/avila_led.c index 1d1553b..ed41782 100644 --- a/sys/arm/xscale/ixp425/avila_led.c +++ b/sys/arm/xscale/ixp425/avila_led.c @@ -52,12 +52,14 @@ led_func(void *arg, int onoff) struct led_avila_softc *sc = arg; uint32_t reg; + IXP4XX_GPIO_LOCK(); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR); if (onoff) reg &= ~GPIO_LED_STATUS_BIT; else reg |= GPIO_LED_STATUS_BIT; GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg); + IXP4XX_GPIO_UNLOCK(); } static int diff --git a/sys/arm/xscale/ixp425/cambria_gpio.c b/sys/arm/xscale/ixp425/cambria_gpio.c index 89b07d8..509cdc3 100644 --- a/sys/arm/xscale/ixp425/cambria_gpio.c +++ b/sys/arm/xscale/ixp425/cambria_gpio.c @@ -133,11 +133,11 @@ i2c_getsda(struct cambria_gpio_softc *sc) { uint32_t reg; - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); return (reg & GPIO_I2C_SDA_BIT); } @@ -145,13 +145,13 @@ static void i2c_setsda(struct cambria_gpio_softc *sc, int val) { - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT); if (val) GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); else GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); DELAY(I2C_DELAY); } @@ -159,13 +159,13 @@ static void i2c_setscl(struct cambria_gpio_softc *sc, int val) { - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT); if (val) GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); else GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); DELAY(I2C_DELAY); } diff --git a/sys/arm/xscale/ixp425/ixp425.c b/sys/arm/xscale/ixp425/ixp425.c index 9b11b43..78d2042 100644 --- a/sys/arm/xscale/ixp425/ixp425.c +++ b/sys/arm/xscale/ixp425/ixp425.c @@ -66,6 +66,8 @@ uint32_t intr_steer2 = 0; struct ixp425_softc *ixp425_softc = NULL; +struct mtx ixp425_gpio_mtx; + static int ixp425_probe(device_t); static void ixp425_identify(driver_t *, device_t); static int ixp425_attach(device_t); @@ -164,6 +166,7 @@ ixp425_set_gpio(struct ixp425_softc *sc, int pin, int type) { uint32_t gpiotr = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(pin)); + IXP4XX_GPIO_LOCK(); /* clear interrupt type */ GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(pin), gpiotr &~ GPIO_TYPE(pin, GPIO_TYPE_MASK)); @@ -176,6 +179,7 @@ ixp425_set_gpio(struct ixp425_softc *sc, int pin, int type) /* configure gpio line as an input */ GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER, GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER) | (1<<pin)); + IXP4XX_GPIO_UNLOCK(); } static __inline void @@ -313,6 +317,7 @@ ixp425_attach(device_t dev) } arm_post_filter = ixp425_post_filter; + mtx_init(&ixp425_gpio_mtx, "gpio", NULL, MTX_DEF); if (bus_space_map(sc->sc_iot, IXP425_GPIO_HWBASE, IXP425_GPIO_SIZE, 0, &sc->sc_gpio_ioh)) panic("%s: unable to map GPIO registers", __func__); diff --git a/sys/arm/xscale/ixp425/ixp425_iic.c b/sys/arm/xscale/ixp425/ixp425_iic.c index bb7d47f..342a6a5 100644 --- a/sys/arm/xscale/ixp425/ixp425_iic.c +++ b/sys/arm/xscale/ixp425/ixp425_iic.c @@ -106,11 +106,11 @@ ixpiic_getscl(device_t dev) struct ixpiic_softc *sc = ixpiic_sc; uint32_t reg; - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); return (reg & GPIO_I2C_SCL_BIT); } @@ -120,11 +120,11 @@ ixpiic_getsda(device_t dev) struct ixpiic_softc *sc = ixpiic_sc; uint32_t reg; - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); return (reg & GPIO_I2C_SDA_BIT); } @@ -133,13 +133,13 @@ ixpiic_setsda(device_t dev, int val) { struct ixpiic_softc *sc = ixpiic_sc; - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT); if (val) GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); else GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); DELAY(I2C_DELAY); } @@ -148,13 +148,13 @@ ixpiic_setscl(device_t dev, int val) { struct ixpiic_softc *sc = ixpiic_sc; - mtx_lock(&Giant); + IXP4XX_GPIO_LOCK(); GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT); if (val) GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); else GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT); - mtx_unlock(&Giant); + IXP4XX_GPIO_UNLOCK(); DELAY(I2C_DELAY); } diff --git a/sys/arm/xscale/ixp425/ixp425var.h b/sys/arm/xscale/ixp425/ixp425var.h index 0f22b91..5d90e10 100644 --- a/sys/arm/xscale/ixp425/ixp425var.h +++ b/sys/arm/xscale/ixp425/ixp425var.h @@ -93,6 +93,9 @@ struct ixppcib_softc { bus_space_write_4(sc->sc_iot, sc->sc_gpio_ioh, reg, data) #define GPIO_CONF_READ_4(sc, reg) \ bus_space_read_4(sc->sc_iot, sc->sc_gpio_ioh, reg) +#define IXP4XX_GPIO_LOCK() mtx_lock(&ixp425_gpio_mtx) +#define IXP4XX_GPIO_UNLOCK() mtx_unlock(&ixp425_gpio_mtx) +extern struct mtx ixp425_gpio_mtx; extern struct bus_space ixp425_bs_tag; extern struct bus_space ixp425_a4x_bs_tag; diff --git a/sys/boot/arm/uboot/ldscript.arm b/sys/boot/arm/uboot/ldscript.arm index 4b8ab54..db8dc0c 100644 --- a/sys/boot/arm/uboot/ldscript.arm +++ b/sys/boot/arm/uboot/ldscript.arm @@ -1,6 +1,5 @@ /* $FreeBSD$ */ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS diff --git a/sys/boot/forth/beastie.4th b/sys/boot/forth/beastie.4th index 79b818d..65d5fc0 100644 --- a/sys/boot/forth/beastie.4th +++ b/sys/boot/forth/beastie.4th @@ -140,12 +140,16 @@ at-xy ." `--{__________) [0m" fbsdbw-logo ; -: acpienabled? ( -- flag ) +: acpipresent? ( -- flag ) s" hint.acpi.0.rsdp" getenv dup -1 = if drop false exit then 2drop + true +; + +: acpienabled? ( -- flag ) s" hint.acpi.0.disabled" getenv dup -1 <> if s" 0" compare 0<> if @@ -180,11 +184,18 @@ at-xy ." `--{__________) [0m" printmenuitem ." Boot FreeBSD [default]" bootkey ! s" arch-i386" environment? if drop - printmenuitem ." Boot FreeBSD with ACPI " bootacpikey ! - acpienabled? if - ." disabled" + acpipresent? if + printmenuitem ." Boot FreeBSD with ACPI " bootacpikey ! + acpienabled? if + ." disabled" + else + ." enabled" + then else - ." enabled" + menuidx @ + 1+ dup + menuidx ! + -2 bootacpikey ! then else -2 bootacpikey ! diff --git a/sys/compat/linsysfs/linsysfs.c b/sys/compat/linsysfs/linsysfs.c index 2247d29..a64b247 100644 --- a/sys/compat/linsysfs/linsysfs.c +++ b/sys/compat/linsysfs/linsysfs.c @@ -182,8 +182,8 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, char sprintf(host, "host%d", host_number++); strcat(new_path, "/"); strcat(new_path, host); - sub_dir = pfs_create_dir(dir, - host, NULL, NULL, NULL, 0); + pfs_create_dir(dir, host, + NULL, NULL, NULL, 0); scsi_host = malloc(sizeof( struct scsi_host_queue), M_DEVBUF, M_NOWAIT); diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c index 01af020..dc7e669 100644 --- a/sys/compat/linux/linux_futex.c +++ b/sys/compat/linux/linux_futex.c @@ -416,7 +416,7 @@ futex_atomic_op(struct thread *td, int encoded_op, uint32_t *uaddr) int linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) { - int op_ret, val, ret, nrwake; + int clockrt, nrwake, op_ret, ret, val; struct linux_emuldata *em; struct waiting_proc *wp; struct futex *f, *f2 = NULL; @@ -429,7 +429,19 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) * in most cases (ie. when futexes are not shared on file descriptor * or between different processes.). */ - args->op = (args->op & ~LINUX_FUTEX_PRIVATE_FLAG); + args->op = args->op & ~LINUX_FUTEX_PRIVATE_FLAG; + + /* + * Currently support for switching between CLOCK_MONOTONIC and + * CLOCK_REALTIME is not present. However Linux forbids the use of + * FUTEX_CLOCK_REALTIME with any op except FUTEX_WAIT_BITSET and + * FUTEX_WAIT_REQUEUE_PI. + */ + clockrt = args->op & LINUX_FUTEX_CLOCK_REALTIME; + args->op = args->op & ~LINUX_FUTEX_CLOCK_REALTIME; + if (clockrt && args->op != LINUX_FUTEX_WAIT_BITSET && + args->op != LINUX_FUTEX_WAIT_REQUEUE_PI) + return (ENOSYS); switch (args->op) { case LINUX_FUTEX_WAIT: @@ -612,14 +624,23 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) case LINUX_FUTEX_LOCK_PI: /* not yet implemented */ + linux_msg(td, + "linux_sys_futex: " + "op LINUX_FUTEX_LOCK_PI not implemented.\n"); return (ENOSYS); case LINUX_FUTEX_UNLOCK_PI: /* not yet implemented */ + linux_msg(td, + "linux_sys_futex: " + "op LINUX_FUTEX_UNLOCK_PI not implemented.\n"); return (ENOSYS); case LINUX_FUTEX_TRYLOCK_PI: /* not yet implemented */ + linux_msg(td, + "linux_sys_futex: " + "op LINUX_FUTEX_TRYLOCK_PI not implemented.\n"); return (ENOSYS); case LINUX_FUTEX_REQUEUE: @@ -632,15 +653,30 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) */ em = em_find(td->td_proc, EMUL_DONTLOCK); if (em->used_requeue == 0) { - printf("linux(%s (%d)) sys_futex: " - "unsupported futex_requeue op\n", - td->td_proc->p_comm, td->td_proc->p_pid); - em->used_requeue = 1; + linux_msg(td, + "linux_sys_futex: " + "unsupported futex_requeue op\n"); + em->used_requeue = 1; } return (EINVAL); + case LINUX_FUTEX_WAIT_BITSET: + /* not yet implemented */ + linux_msg(td, + "linux_sys_futex: " + "op FUTEX_WAIT_BITSET not implemented.\n"); + return (ENOSYS); + + case LINUX_FUTEX_WAIT_REQUEUE_PI: + /* not yet implemented */ + linux_msg(td, + "linux_sys_futex: " + "op FUTEX_WAIT_REQUEUE_PI not implemented.\n"); + return (ENOSYS); + default: - printf("linux_sys_futex: unknown op %d\n", args->op); + linux_msg(td, + "linux_sys_futex: unknown op %d\n", args->op); return (ENOSYS); } @@ -665,7 +701,7 @@ linux_set_robust_list(struct thread *td, struct linux_set_robust_list_args *args em->robust_futexes = args->head; EMUL_UNLOCK(&emul_lock); - return (0); + return (0); } int @@ -683,7 +719,7 @@ linux_get_robust_list(struct thread *td, struct linux_get_robust_list_args *args if (!args->pid) { em = em_find(td->td_proc, EMUL_DONTLOCK); - head = em->robust_futexes; + head = em->robust_futexes; } else { struct proc *p; @@ -693,14 +729,14 @@ linux_get_robust_list(struct thread *td, struct linux_get_robust_list_args *args em = em_find(p, EMUL_DONTLOCK); /* XXX: ptrace? */ - if (priv_check(td, PRIV_CRED_SETUID) || + if (priv_check(td, PRIV_CRED_SETUID) || priv_check(td, PRIV_CRED_SETEUID) || p_candebug(td, p)) { PROC_UNLOCK(p); return (EPERM); } head = em->robust_futexes; - + PROC_UNLOCK(p); } diff --git a/sys/compat/linux/linux_futex.h b/sys/compat/linux/linux_futex.h index 1d462a7..4ccd46c 100644 --- a/sys/compat/linux/linux_futex.h +++ b/sys/compat/linux/linux_futex.h @@ -39,17 +39,20 @@ extern LIST_HEAD(futex_list, futex) futex_list; extern struct mtx futex_mtx; -#define LINUX_FUTEX_WAIT 0 -#define LINUX_FUTEX_WAKE 1 -#define LINUX_FUTEX_FD 2 /* unused */ -#define LINUX_FUTEX_REQUEUE 3 -#define LINUX_FUTEX_CMP_REQUEUE 4 -#define LINUX_FUTEX_WAKE_OP 5 -#define LINUX_FUTEX_LOCK_PI 6 -#define LINUX_FUTEX_UNLOCK_PI 7 -#define LINUX_FUTEX_TRYLOCK_PI 8 +#define LINUX_FUTEX_WAIT 0 +#define LINUX_FUTEX_WAKE 1 +#define LINUX_FUTEX_FD 2 /* unused */ +#define LINUX_FUTEX_REQUEUE 3 +#define LINUX_FUTEX_CMP_REQUEUE 4 +#define LINUX_FUTEX_WAKE_OP 5 +#define LINUX_FUTEX_LOCK_PI 6 +#define LINUX_FUTEX_UNLOCK_PI 7 +#define LINUX_FUTEX_TRYLOCK_PI 8 +#define LINUX_FUTEX_WAIT_BITSET 9 +#define LINUX_FUTEX_WAIT_REQUEUE_PI 11 #define LINUX_FUTEX_PRIVATE_FLAG 128 +#define LINUX_FUTEX_CLOCK_REALTIME 256 #define FUTEX_OP_SET 0 /* *(int *)UADDR2 = OPARG; */ #define FUTEX_OP_ADD 1 /* *(int *)UADDR2 += OPARG; */ diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h index af50893..3b121e7 100644 --- a/sys/dev/drm/drmP.h +++ b/sys/dev/drm/drmP.h @@ -80,7 +80,9 @@ struct drm_file; #include <machine/pmap.h> #include <machine/bus.h> #include <machine/resource.h> +#if defined(__i386__) || defined(__amd64__) #include <machine/specialreg.h> +#endif #include <machine/sysarch.h> #include <sys/endian.h> #include <sys/mman.h> @@ -246,20 +248,20 @@ typedef u_int8_t u8; *(volatile u_int8_t *)(((vm_offset_t)(map)->virtual) + \ (vm_offset_t)(offset)) #define DRM_READ16(map, offset) \ - *(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) + le16toh(*(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \ + (vm_offset_t)(offset))) #define DRM_READ32(map, offset) \ - *(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) + le32toh(*(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \ + (vm_offset_t)(offset))) #define DRM_WRITE8(map, offset, val) \ *(volatile u_int8_t *)(((vm_offset_t)(map)->virtual) + \ (vm_offset_t)(offset)) = val #define DRM_WRITE16(map, offset, val) \ *(volatile u_int16_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) = val + (vm_offset_t)(offset)) = htole16(val) #define DRM_WRITE32(map, offset, val) \ *(volatile u_int32_t *)(((vm_offset_t)(map)->virtual) + \ - (vm_offset_t)(offset)) = val + (vm_offset_t)(offset)) = htole32(val) #define DRM_VERIFYAREA_READ( uaddr, size ) \ (!useracc(__DECONST(caddr_t, uaddr), size, VM_PROT_READ)) diff --git a/sys/dev/drm/drm_agpsupport.c b/sys/dev/drm/drm_agpsupport.c index 7019fe7..cb98ec1 100644 --- a/sys/dev/drm/drm_agpsupport.c +++ b/sys/dev/drm/drm_agpsupport.c @@ -318,7 +318,7 @@ int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request) if (!dev->agp || !dev->agp->acquired) return EINVAL; - DRM_DEBUG("agp_bind, page_size=%x\n", PAGE_SIZE); + DRM_DEBUG("agp_bind, page_size=%x\n", (int)PAGE_SIZE); entry = drm_agp_lookup_entry(dev, (void *)request->handle); if (entry == NULL || entry->bound) diff --git a/sys/dev/drm/drm_drv.c b/sys/dev/drm/drm_drv.c index 8d9bc69..75902a7 100644 --- a/sys/dev/drm/drm_drv.c +++ b/sys/dev/drm/drm_drv.c @@ -478,7 +478,7 @@ static int drm_load(struct drm_device *dev) retcode = ENOMEM; goto error; } - if (dev->agp != NULL) { + if (dev->agp != NULL && dev->agp->info.ai_aperture_base != 0) { if (drm_mtrr_add(dev->agp->info.ai_aperture_base, dev->agp->info.ai_aperture_size, DRM_MTRR_WC) == 0) dev->agp->mtrr = 1; diff --git a/sys/dev/drm/drm_memory.c b/sys/dev/drm/drm_memory.c index 415b774..409ea7d 100644 --- a/sys/dev/drm/drm_memory.c +++ b/sys/dev/drm/drm_memory.c @@ -73,7 +73,7 @@ void drm_mem_uninit(void) void *drm_ioremap_wc(struct drm_device *dev, drm_local_map_t *map) { - return pmap_mapdev_attr(map->offset, map->size, PAT_WRITE_COMBINING); + return pmap_mapdev_attr(map->offset, map->size, VM_MEMATTR_WRITE_COMBINING); } void *drm_ioremap(struct drm_device *dev, drm_local_map_t *map) diff --git a/sys/dev/drm/drm_sysctl.c b/sys/dev/drm/drm_sysctl.c index 4d9b0e8..1366b07 100644 --- a/sys/dev/drm/drm_sysctl.c +++ b/sys/dev/drm/drm_sysctl.c @@ -259,7 +259,7 @@ static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS *(1 << dma->bufs[i].page_order), (dma->bufs[i].seg_count * (1 << dma->bufs[i].page_order)) - * PAGE_SIZE / 1024); + * (int)PAGE_SIZE / 1024); } DRM_SYSCTL_PRINT("\n"); for (i = 0; i < dma->buf_count; i++) { diff --git a/sys/dev/drm/radeon_cs.c b/sys/dev/drm/radeon_cs.c index 14fe2fc..6dd82a2 100644 --- a/sys/dev/drm/radeon_cs.c +++ b/sys/dev/drm/radeon_cs.c @@ -765,7 +765,7 @@ static int r600_cs_parse(struct drm_radeon_cs_parser *parser) memcpy(parser->ib, ib_chunk->kdata, ib_chunk->length_dw * sizeof(uint32_t)); /* read back last byte to flush WC buffers */ - rb = readl(((vm_offset_t)parser->ib + (ib_chunk->length_dw-1) * sizeof(uint32_t))); + rb = *(volatile u_int32_t *) (((vm_offset_t)parser->ib + (ib_chunk->length_dw-1) * sizeof(uint32_t))); return 0; } diff --git a/sys/dev/firewire/00README b/sys/dev/firewire/00README index a6536ae..1abaa33 100644 --- a/sys/dev/firewire/00README +++ b/sys/dev/firewire/00README @@ -44,10 +44,6 @@ IEEE 1394 support for FreeBSD-5.X and 4.X. - make install - make load - For FreeBSD-4 user: - - - ./MAKEDEV - 3. SBP-II support (sbp) - You need CAM(SCSI) support in your kernel. diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c index 96947d4..58adc53 100644 --- a/sys/dev/mii/brgphy.c +++ b/sys/dev/mii/brgphy.c @@ -154,15 +154,19 @@ static int detect_hs21(struct bce_softc *bce_sc) { char *sysenv; - - if (bce_sc->bce_chipid != HS21_BCM_CHIPID) - return (0); - sysenv = getenv("smbios.system.product"); - if (sysenv == NULL) - return (0); - if (strncmp(sysenv, HS21_PRODUCT_ID, strlen(HS21_PRODUCT_ID)) != 0) - return (0); - return (1); + int found; + + found = 0; + if (bce_sc->bce_chipid == HS21_BCM_CHIPID) { + sysenv = getenv("smbios.system.product"); + if (sysenv != NULL) { + if (strncmp(sysenv, HS21_PRODUCT_ID, + strlen(HS21_PRODUCT_ID)) == 0) + found = 1; + freeenv(sysenv); + } + } + return (found); } /* Search for our PHY in the list of known PHYs */ diff --git a/sys/dev/mii/mii.c b/sys/dev/mii/mii.c index 79378f5..3df5dfa 100644 --- a/sys/dev/mii/mii.c +++ b/sys/dev/mii/mii.c @@ -438,6 +438,9 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp, rv = bus_generic_attach(dev); if (rv != 0) goto fail; + + /* Attaching of the PHY drivers is done in miibus_attach(). */ + return (0); } rv = bus_generic_attach(*miibus); if (rv != 0) diff --git a/sys/dev/mpt/mpt.h b/sys/dev/mpt/mpt.h index f095bbf..cf72194 100644 --- a/sys/dev/mpt/mpt.h +++ b/sys/dev/mpt/mpt.h @@ -1112,10 +1112,10 @@ do { \ mpt_prt(mpt, __VA_ARGS__); \ } while (0) -#define mpt_lprtc(mpt, level, ...) \ -do { \ - if (level <= (mpt)->debug_level) \ - mpt_prtc(mpt, __VA_ARGS__); \ +#define mpt_lprtc(mpt, level, ...) \ +do { \ + if (level <= (mpt)->verbose) \ + mpt_prtc(mpt, __VA_ARGS__); \ } while (0) #else void mpt_lprt(struct mpt_softc *, int, const char *, ...) diff --git a/sys/dev/nfe/if_nfe.c b/sys/dev/nfe/if_nfe.c index fcc11c2..c77a4da 100644 --- a/sys/dev/nfe/if_nfe.c +++ b/sys/dev/nfe/if_nfe.c @@ -77,6 +77,7 @@ static int nfe_detach(device_t); static int nfe_suspend(device_t); static int nfe_resume(device_t); static int nfe_shutdown(device_t); +static int nfe_can_use_msix(struct nfe_softc *); static void nfe_power(struct nfe_softc *); static int nfe_miibus_readreg(device_t, int, int); static int nfe_miibus_writereg(device_t, int, int, int); @@ -383,6 +384,13 @@ nfe_attach(device_t dev) "max. width of link(x%d)\n", width, v); } + if (nfe_can_use_msix(sc) == 0) { + device_printf(sc->nfe_dev, + "MSI/MSI-X capability black-listed, will use INTx\n"); + msix_disable = 1; + msi_disable = 1; + } + /* Allocate interrupt */ if (msix_disable == 0 || msi_disable == 0) { if (msix_disable == 0 && @@ -784,6 +792,48 @@ nfe_resume(device_t dev) } +static int +nfe_can_use_msix(struct nfe_softc *sc) +{ + static struct msix_blacklist { + char *maker; + char *product; + } msix_blacklists[] = { + { "ASUSTeK Computer INC.", "P5N32-SLI PREMIUM" } + }; + + struct msix_blacklist *mblp; + char *maker, *product; + int count, n, use_msix; + + /* + * Search base board manufacturer and product name table + * to see this system has a known MSI/MSI-X issue. + */ + maker = getenv("smbios.planar.maker"); + product = getenv("smbios.planar.product"); + use_msix = 1; + if (maker != NULL && product != NULL) { + count = sizeof(msix_blacklists) / sizeof(msix_blacklists[0]); + mblp = msix_blacklists; + for (n = 0; n < count; n++) { + if (strcmp(maker, mblp->maker) == 0 && + strcmp(product, mblp->product) == 0) { + use_msix = 0; + break; + } + mblp++; + } + } + if (maker != NULL) + freeenv(maker); + if (product != NULL) + freeenv(product); + + return (use_msix); +} + + /* Take PHY/NIC out of powerdown, from Linux */ static void nfe_power(struct nfe_softc *sc) diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index 35326cb..4df624b 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -1449,7 +1449,7 @@ re_attach(device_t dev) if (sc->rl_type == RL_8169) phy = 1; error = mii_attach(dev, &sc->rl_miibus, ifp, re_ifmedia_upd, - re_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); + re_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; diff --git a/sys/dev/tdfx/tdfx_pci.c b/sys/dev/tdfx/tdfx_pci.c index 7ed00ac..770c672 100644 --- a/sys/dev/tdfx/tdfx_pci.c +++ b/sys/dev/tdfx/tdfx_pci.c @@ -250,7 +250,7 @@ tdfx_attach(device_t dev) { /* * make_dev registers the cdev to access the 3dfx card from /dev * use hex here for the dev num, simply to provide better support if > 10 - * voodoo cards, for the mad. The user must set the link, or use MAKEDEV. + * voodoo cards, for the mad. The user must set the link. * Why would we want that many voodoo cards anyhow? */ tdfx_info->devt = make_dev(&tdfx_cdev, device_get_unit(dev), diff --git a/sys/dev/usb/net/if_ruereg.h b/sys/dev/usb/net/if_ruereg.h index a4a4aec..c90a969 100644 --- a/sys/dev/usb/net/if_ruereg.h +++ b/sys/dev/usb/net/if_ruereg.h @@ -157,11 +157,6 @@ struct rue_intrpkt { uint8_t rue_col_cnt; } __packed; -struct rue_type { - uint16_t rue_vid; - uint16_t rue_did; -}; - enum { RUE_BULK_DT_WR, RUE_BULK_DT_RD, diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index 0777cdd..646063a 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -288,6 +288,7 @@ static const struct usb_device_id u3g_devs[] = { U3G_DEV(HUAWEI, MOBILE, U3GINIT_HUAWEI), U3G_DEV(HUAWEI, E1752, U3GINIT_HUAWEISCSI), U3G_DEV(HUAWEI, K3765, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, K3765_INIT, U3GINIT_HUAWEISCSI), U3G_DEV(KYOCERA2, CDMA_MSM_K, 0), U3G_DEV(KYOCERA2, KPC680, 0), U3G_DEV(LONGCHEER, WM66, U3GINIT_HUAWEI), @@ -457,6 +458,7 @@ static const struct usb_device_id u3g_devs[] = { U3G_DEV(SIERRA, MC5727, 0), U3G_DEV(SIERRA, MC5727_2, 0), U3G_DEV(SIERRA, MC5728, 0), + U3G_DEV(SIERRA, MC8700, 0), U3G_DEV(SIERRA, MC8755, 0), U3G_DEV(SIERRA, MC8755_2, 0), U3G_DEV(SIERRA, MC8755_3, 0), diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 87350a7..91fe9f4 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1857,6 +1857,7 @@ product HUAWEI E143F 0x143f 3G modem product HUAWEI E1752 0x1446 3G modem product HUAWEI K3765 0x1465 3G modem product HUAWEI E14AC 0x14ac 3G modem +product HUAWEI K3765_INIT 0x1520 HUAWEI Mobile K3765 Initial /* HUAWEI 3com products */ product HUAWEI3COM WUB320G 0x0009 Aolynk WUB320g @@ -2919,6 +2920,7 @@ product SIERRA C888 0x6890 C888 product SIERRA C22 0x6891 C22 product SIERRA E6892 0x6892 E6892 product SIERRA E6893 0x6893 E6893 +product SIERRA MC8700 0x68A3 MC8700 product SIERRA AIRCARD875 0x6820 Aircard 875 HSDPA product SIERRA TRUINSTALL 0x0fff Aircard Tru Installer diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index d99109f..ad54d79 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -555,6 +555,7 @@ xl_miibus_statchg(device_t dev) { struct xl_softc *sc; struct mii_data *mii; + uint8_t macctl; sc = device_get_softc(dev); mii = device_get_softc(sc->xl_miibus); @@ -563,11 +564,22 @@ xl_miibus_statchg(device_t dev) /* Set ASIC's duplex mode to match the PHY. */ XL_SEL_WIN(3); - if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) - CSR_WRITE_1(sc, XL_W3_MAC_CTRL, XL_MACCTRL_DUPLEX); - else - CSR_WRITE_1(sc, XL_W3_MAC_CTRL, - (CSR_READ_1(sc, XL_W3_MAC_CTRL) & ~XL_MACCTRL_DUPLEX)); + macctl = CSR_READ_1(sc, XL_W3_MAC_CTRL); + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { + macctl |= XL_MACCTRL_DUPLEX; + if (sc->xl_type == XL_TYPE_905B) { + if ((IFM_OPTIONS(mii->mii_media_active) & + IFM_ETH_RXPAUSE) != 0) + macctl |= XL_MACCTRL_FLOW_CONTROL_ENB; + else + macctl &= ~XL_MACCTRL_FLOW_CONTROL_ENB; + } + } else { + macctl &= ~XL_MACCTRL_DUPLEX; + if (sc->xl_type == XL_TYPE_905B) + macctl &= ~XL_MACCTRL_FLOW_CONTROL_ENB; + } + CSR_WRITE_1(sc, XL_W3_MAC_CTRL, macctl); } /* @@ -1464,7 +1476,8 @@ xl_attach(device_t dev) if ((sc->xl_flags & XL_FLAG_PHYOK) == 0) phy = 24; error = mii_attach(dev, &sc->xl_miibus, ifp, xl_ifmedia_upd, - xl_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); + xl_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, + sc->xl_type == XL_TYPE_905B ? MIIF_DOPAUSE : 0); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index b6f843a..026ba9d 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -462,8 +462,7 @@ trap(struct trapframe *frame) * without the ABI-tag ELF note. */ if (SV_CURPROC_ABI() == SV_ABI_FREEBSD - && p->p_osrel >= - __FreeBSD_version_SIGSEGV) { + && p->p_osrel >= P_OSREL_SIGSEGV) { i = SIGSEGV; ucode = SEGV_ACCERR; } else { diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index cf8c534..951fef6 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -1592,11 +1592,11 @@ umtxq_sleep_pi(struct umtx_q *uq, struct umtx_pi *pi, /* XXX Only look up thread in current process. */ td1 = tdfind(owner, curproc->p_pid); mtx_lock_spin(&umtx_lock); - if (td1 != NULL && pi->pi_owner == NULL) { - uq1 = td1->td_umtxq; - umtx_pi_setowner(pi, td1); + if (td1 != NULL) { + if (pi->pi_owner == NULL) + umtx_pi_setowner(pi, td1); + PROC_UNLOCK(td1->td_proc); } - PROC_UNLOCK(td1->td_proc); } TAILQ_FOREACH(uq1, &pi->pi_blocked, uq_lockq) { diff --git a/sys/netinet/cc.h b/sys/netinet/cc.h index 6f24f11..aaa1d67 100644 --- a/sys/netinet/cc.h +++ b/sys/netinet/cc.h @@ -58,11 +58,14 @@ extern STAILQ_HEAD(cc_head, cc_algo) cc_list; extern const int tcprexmtthresh; extern struct cc_algo newreno_cc_algo; +/* Per-netstack bits. */ +VNET_DECLARE(struct cc_algo *, default_cc_ptr); +#define V_default_cc_ptr VNET(default_cc_ptr) + /* Define the new net.inet.tcp.cc sysctl tree. */ SYSCTL_DECL(_net_inet_tcp_cc); /* CC housekeeping functions. */ -void cc_init(void); int cc_register_algo(struct cc_algo *add_cc); int cc_deregister_algo(struct cc_algo *remove_cc); @@ -147,7 +150,7 @@ struct cc_algo { #define CC_DATA(tp) ((tp)->ccv->cc_data) /* Macro to obtain the system default CC algo's struct ptr. */ -#define CC_DEFAULT() STAILQ_FIRST(&cc_list) +#define CC_DEFAULT() V_default_cc_ptr extern struct rwlock cc_list_lock; #define CC_LIST_LOCK_INIT() rw_init(&cc_list_lock, "cc_list") @@ -156,6 +159,6 @@ extern struct rwlock cc_list_lock; #define CC_LIST_RUNLOCK() rw_runlock(&cc_list_lock) #define CC_LIST_WLOCK() rw_wlock(&cc_list_lock) #define CC_LIST_WUNLOCK() rw_wunlock(&cc_list_lock) -#define CC_LIST_WLOCK_ASSERT() rw_assert(&cc_list_lock, RA_WLOCKED) +#define CC_LIST_LOCK_ASSERT() rw_assert(&cc_list_lock, RA_LOCKED) #endif /* _NETINET_CC_H_ */ diff --git a/sys/netinet/cc/cc.c b/sys/netinet/cc/cc.c index 4643ca4..f075327 100644 --- a/sys/netinet/cc/cc.c +++ b/sys/netinet/cc/cc.c @@ -81,24 +81,7 @@ struct cc_head cc_list = STAILQ_HEAD_INITIALIZER(cc_list); /* Protects the cc_list TAILQ. */ struct rwlock cc_list_lock; -/* - * Set the default CC algorithm to new_default. The default is identified - * by being the first element in the cc_list TAILQ. - */ -static void -cc_set_default(struct cc_algo *new_default) -{ - CC_LIST_WLOCK_ASSERT(); - - /* - * Make the requested system default CC algorithm the first element in - * the list if it isn't already. - */ - if (new_default != CC_DEFAULT()) { - STAILQ_REMOVE(&cc_list, new_default, cc_algo, entries); - STAILQ_INSERT_HEAD(&cc_list, new_default, entries); - } -} +VNET_DEFINE(struct cc_algo *, default_cc_ptr) = &newreno_cc_algo; /* * Sysctl handler to show and change the default CC algorithm. @@ -106,14 +89,13 @@ cc_set_default(struct cc_algo *new_default) static int cc_default_algo(SYSCTL_HANDLER_ARGS) { + char default_cc[TCP_CA_NAME_MAX]; struct cc_algo *funcs; int err, found; err = found = 0; if (req->newptr == NULL) { - char default_cc[TCP_CA_NAME_MAX]; - /* Just print the current default. */ CC_LIST_RLOCK(); strlcpy(default_cc, CC_DEFAULT()->name, TCP_CA_NAME_MAX); @@ -121,15 +103,15 @@ cc_default_algo(SYSCTL_HANDLER_ARGS) err = sysctl_handle_string(oidp, default_cc, 1, req); } else { /* Find algo with specified name and set it to default. */ - CC_LIST_WLOCK(); + CC_LIST_RLOCK(); STAILQ_FOREACH(funcs, &cc_list, entries) { if (strncmp((char *)req->newptr, funcs->name, TCP_CA_NAME_MAX) == 0) { found = 1; - cc_set_default(funcs); + V_default_cc_ptr = funcs; } } - CC_LIST_WUNLOCK(); + CC_LIST_RUNLOCK(); if (!found) err = ESRCH; @@ -174,10 +156,32 @@ cc_list_available(SYSCTL_HANDLER_ARGS) } /* + * Reset the default CC algo to NewReno for any netstack which is using the algo + * that is about to go away as its default. + */ +static void +cc_checkreset_default(struct cc_algo *remove_cc) +{ + VNET_ITERATOR_DECL(vnet_iter); + + CC_LIST_LOCK_ASSERT(); + + VNET_LIST_RLOCK_NOSLEEP(); + VNET_FOREACH(vnet_iter) { + CURVNET_SET(vnet_iter); + if (strncmp(CC_DEFAULT()->name, remove_cc->name, + TCP_CA_NAME_MAX) == 0) + V_default_cc_ptr = &newreno_cc_algo; + CURVNET_RESTORE(); + } + VNET_LIST_RUNLOCK_NOSLEEP(); +} + +/* * Initialise CC subsystem on system boot. */ -void -cc_init() +static void +cc_init(void) { CC_LIST_LOCK_INIT(); STAILQ_INIT(&cc_list); @@ -190,8 +194,6 @@ int cc_deregister_algo(struct cc_algo *remove_cc) { struct cc_algo *funcs, *tmpfuncs; - struct tcpcb *tp; - struct inpcb *inp; int err; err = ENOENT; @@ -204,58 +206,22 @@ cc_deregister_algo(struct cc_algo *remove_cc) CC_LIST_WLOCK(); STAILQ_FOREACH_SAFE(funcs, &cc_list, entries, tmpfuncs) { if (funcs == remove_cc) { - /* - * If we're removing the current system default, - * reset the default to newreno. - */ - if (strncmp(CC_DEFAULT()->name, remove_cc->name, - TCP_CA_NAME_MAX) == 0) - cc_set_default(&newreno_cc_algo); - + cc_checkreset_default(remove_cc); STAILQ_REMOVE(&cc_list, funcs, cc_algo, entries); err = 0; break; } } CC_LIST_WUNLOCK(); - - if (!err) { + + if (!err) /* - * Check all active control blocks and change any that are - * using this algorithm back to newreno. If the algorithm that - * was in use requires cleanup code to be run, call it. - * - * New connections already part way through being initialised - * with the CC algo we're removing will not race with this code - * because the INP_INFO_WLOCK is held during initialisation. - * We therefore don't enter the loop below until the connection - * list has stabilised. + * XXXLAS: + * - We may need to handle non-zero return values in future. + * - If we add CC framework support for protocols other than + * TCP, we may want a more generic way to handle this step. */ - INP_INFO_RLOCK(&V_tcbinfo); - LIST_FOREACH(inp, &V_tcb, inp_list) { - INP_WLOCK(inp); - /* Important to skip tcptw structs. */ - if (!(inp->inp_flags & INP_TIMEWAIT) && - (tp = intotcpcb(inp)) != NULL) { - /* - * By holding INP_WLOCK here, we are - * assured that the connection is not - * currently executing inside the CC - * module's functions i.e. it is safe to - * make the switch back to newreno. - */ - if (CC_ALGO(tp) == remove_cc) { - tmpfuncs = CC_ALGO(tp); - /* Newreno does not require any init. */ - CC_ALGO(tp) = &newreno_cc_algo; - if (tmpfuncs->cb_destroy != NULL) - tmpfuncs->cb_destroy(tp->ccv); - } - } - INP_WUNLOCK(inp); - } - INP_INFO_RUNLOCK(&V_tcbinfo); - } + tcp_ccalgounload(remove_cc); return (err); } @@ -328,11 +294,13 @@ cc_modevent(module_t mod, int event_type, void *data) return (err); } +SYSINIT(cc, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST, cc_init, NULL); + /* Declare sysctl tree and populate it. */ SYSCTL_NODE(_net_inet_tcp, OID_AUTO, cc, CTLFLAG_RW, NULL, "congestion control related settings"); -SYSCTL_PROC(_net_inet_tcp_cc, OID_AUTO, algorithm, CTLTYPE_STRING|CTLFLAG_RW, +SYSCTL_VNET_PROC(_net_inet_tcp_cc, OID_AUTO, algorithm, CTLTYPE_STRING|CTLFLAG_RW, NULL, 0, cc_default_algo, "A", "default congestion control algorithm"); SYSCTL_PROC(_net_inet_tcp_cc, OID_AUTO, available, CTLTYPE_STRING|CTLFLAG_RD, diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index e6e7ca4..eebc023 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -278,8 +278,6 @@ tcp_init(void) { int hashsize; - cc_init(); - hashsize = TCBHASHSIZE; TUNABLE_INT_FETCH("net.inet.tcp.tcbhashsize", &hashsize); if (!powerof2(hashsize)) { @@ -710,6 +708,69 @@ tcp_newtcpcb(struct inpcb *inp) } /* + * Switch the congestion control algorithm back to NewReno for any active + * control blocks using an algorithm which is about to go away. + * This ensures the CC framework can allow the unload to proceed without leaving + * any dangling pointers which would trigger a panic. + * Returning non-zero would inform the CC framework that something went wrong + * and it would be unsafe to allow the unload to proceed. However, there is no + * way for this to occur with this implementation so we always return zero. + */ +int +tcp_ccalgounload(struct cc_algo *unload_algo) +{ + struct cc_algo *tmpalgo; + struct inpcb *inp; + struct tcpcb *tp; + VNET_ITERATOR_DECL(vnet_iter); + + /* + * Check all active control blocks across all network stacks and change + * any that are using "unload_algo" back to NewReno. If "unload_algo" + * requires cleanup code to be run, call it. + */ + VNET_LIST_RLOCK(); + VNET_FOREACH(vnet_iter) { + CURVNET_SET(vnet_iter); + INP_INFO_RLOCK(&V_tcbinfo); + /* + * New connections already part way through being initialised + * with the CC algo we're removing will not race with this code + * because the INP_INFO_WLOCK is held during initialisation. We + * therefore don't enter the loop below until the connection + * list has stabilised. + */ + LIST_FOREACH(inp, &V_tcb, inp_list) { + INP_WLOCK(inp); + /* Important to skip tcptw structs. */ + if (!(inp->inp_flags & INP_TIMEWAIT) && + (tp = intotcpcb(inp)) != NULL) { + /* + * By holding INP_WLOCK here, we are assured + * that the connection is not currently + * executing inside the CC module's functions + * i.e. it is safe to make the switch back to + * NewReno. + */ + if (CC_ALGO(tp) == unload_algo) { + tmpalgo = CC_ALGO(tp); + /* NewReno does not require any init. */ + CC_ALGO(tp) = &newreno_cc_algo; + if (tmpalgo->cb_destroy != NULL) + tmpalgo->cb_destroy(tp->ccv); + } + } + INP_WUNLOCK(inp); + } + INP_INFO_RUNLOCK(&V_tcbinfo); + CURVNET_RESTORE(); + } + VNET_LIST_RUNLOCK(); + + return (0); +} + +/* * Drop a TCP connection, reporting * the specified error. If connection is synchronized, * then send a RST to peer. diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 442c736..7b38667 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -605,6 +605,7 @@ VNET_DECLARE(int, tcp_ecn_maxretries); #define V_tcp_ecn_maxretries VNET(tcp_ecn_maxretries) int tcp_addoptions(struct tcpopt *, u_char *); +int tcp_ccalgounload(struct cc_algo *unload_algo); struct tcpcb * tcp_close(struct tcpcb *); void tcp_discardcb(struct tcpcb *); diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index 7f6fdc26..f916be0 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -159,7 +159,8 @@ static devclass_t psycho_devclass; DEFINE_CLASS_0(pcib, psycho_driver, psycho_methods, sizeof(struct psycho_softc)); -DRIVER_MODULE(psycho, nexus, psycho_driver, psycho_devclass, 0, 0); +EARLY_DRIVER_MODULE(psycho, nexus, psycho_driver, psycho_devclass, 0, 0, + BUS_PASS_BUS); static SLIST_HEAD(, psycho_softc) psycho_softcs = SLIST_HEAD_INITIALIZER(psycho_softcs); diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c index f346667..d2e22bc 100644 --- a/sys/sparc64/pci/schizo.c +++ b/sys/sparc64/pci/schizo.c @@ -158,7 +158,8 @@ static devclass_t schizo_devclass; DEFINE_CLASS_0(pcib, schizo_driver, schizo_methods, sizeof(struct schizo_softc)); -DRIVER_MODULE(schizo, nexus, schizo_driver, schizo_devclass, 0, 0); +EARLY_DRIVER_MODULE(schizo, nexus, schizo_driver, schizo_devclass, 0, 0, + BUS_PASS_BUS); static SLIST_HEAD(, schizo_softc) schizo_softcs = SLIST_HEAD_INITIALIZER(schizo_softcs); diff --git a/sys/sys/param.h b/sys/sys/param.h index 3e4cdf6..ea90308 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -61,8 +61,8 @@ #define __FreeBSD_version 900025 /* Master, propagated to newvers */ #ifdef _KERNEL -#define __FreeBSD_version_SIGSEGV 700004 -#define __FreeBSD_version_MAP_ANON 800104 +#define P_OSREL_SIGSEGV 700004 +#define P_OSREL_MAP_ANON 800104 #endif #ifndef LOCORE diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 5c6f173..f2dba2c 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -232,7 +232,7 @@ mmap(td, uap) /* Make sure mapping fits into numeric range, etc. */ if ((uap->len == 0 && !SV_CURPROC_FLAG(SV_AOUT) && - curproc->p_osrel >= __FreeBSD_version_MAP_ANON) || + curproc->p_osrel >= P_OSREL_MAP_ANON) || ((flags & MAP_ANON) && (uap->fd != -1 || pos != 0))) return (EINVAL); |