svn commit: r222237 - in projects/largeSMP: contrib/top
sbin/hastctl sbin/hastd share/man/man4 share/mk sys/conf
sys/dev/acpica sys/dev/msk sys/fs/nfsclient sys/geom/gate
sys/kern sys/netinet sys/n...
Attilio Rao
attilio at FreeBSD.org
Mon May 23 23:58:03 UTC 2011
Author: attilio
Date: Mon May 23 23:58:02 2011
New Revision: 222237
URL: http://svn.freebsd.org/changeset/base/222237
Log:
MFC
Modified:
projects/largeSMP/sbin/hastctl/hastctl.c
projects/largeSMP/sbin/hastd/control.c
projects/largeSMP/sbin/hastd/hast.h
projects/largeSMP/sbin/hastd/primary.c
projects/largeSMP/sbin/hastd/secondary.c
projects/largeSMP/sbin/hastd/subr.c
projects/largeSMP/share/man/man4/msk.4
projects/largeSMP/sys/conf/kern.post.mk
projects/largeSMP/sys/conf/kmod.mk
projects/largeSMP/sys/conf/newvers.sh
projects/largeSMP/sys/dev/acpica/acpi_hpet.c
projects/largeSMP/sys/dev/acpica/acpi_timer.c
projects/largeSMP/sys/dev/msk/if_msk.c
projects/largeSMP/sys/dev/msk/if_mskreg.h
projects/largeSMP/sys/fs/nfsclient/nfs_clvfsops.c
projects/largeSMP/sys/geom/gate/g_gate.c
projects/largeSMP/sys/kern/kern_environment.c
projects/largeSMP/sys/kern/vfs_bio.c
projects/largeSMP/sys/netinet/in_pcb.c
projects/largeSMP/sys/netinet/in_pcb.h
projects/largeSMP/sys/netinet6/in6_pcb.c
projects/largeSMP/sys/netinet6/in6_src.c
projects/largeSMP/usr.bin/gzip/Makefile
projects/largeSMP/usr.bin/gzip/gzip.1
projects/largeSMP/usr.bin/gzip/gzip.c
projects/largeSMP/usr.bin/gzip/zdiff
projects/largeSMP/usr.bin/gzip/zdiff.1
projects/largeSMP/usr.bin/gzip/zuncompress.c
Directory Properties:
projects/largeSMP/ (props changed)
projects/largeSMP/cddl/contrib/opensolaris/ (props changed)
projects/largeSMP/contrib/bind9/ (props changed)
projects/largeSMP/contrib/binutils/ (props changed)
projects/largeSMP/contrib/bzip2/ (props changed)
projects/largeSMP/contrib/dialog/ (props changed)
projects/largeSMP/contrib/ee/ (props changed)
projects/largeSMP/contrib/expat/ (props changed)
projects/largeSMP/contrib/file/ (props changed)
projects/largeSMP/contrib/gcc/ (props changed)
projects/largeSMP/contrib/gdb/ (props changed)
projects/largeSMP/contrib/gdtoa/ (props changed)
projects/largeSMP/contrib/gnu-sort/ (props changed)
projects/largeSMP/contrib/groff/ (props changed)
projects/largeSMP/contrib/less/ (props changed)
projects/largeSMP/contrib/libpcap/ (props changed)
projects/largeSMP/contrib/libstdc++/ (props changed)
projects/largeSMP/contrib/llvm/ (props changed)
projects/largeSMP/contrib/llvm/tools/clang/ (props changed)
projects/largeSMP/contrib/ncurses/ (props changed)
projects/largeSMP/contrib/netcat/ (props changed)
projects/largeSMP/contrib/ntp/ (props changed)
projects/largeSMP/contrib/one-true-awk/ (props changed)
projects/largeSMP/contrib/openbsm/ (props changed)
projects/largeSMP/contrib/openpam/ (props changed)
projects/largeSMP/contrib/pf/ (props changed)
projects/largeSMP/contrib/sendmail/ (props changed)
projects/largeSMP/contrib/tcpdump/ (props changed)
projects/largeSMP/contrib/tcsh/ (props changed)
projects/largeSMP/contrib/top/ (props changed)
projects/largeSMP/contrib/top/install-sh (props changed)
projects/largeSMP/contrib/tzcode/stdtime/ (props changed)
projects/largeSMP/contrib/tzcode/zic/ (props changed)
projects/largeSMP/contrib/tzdata/ (props changed)
projects/largeSMP/contrib/wpa/ (props changed)
projects/largeSMP/contrib/xz/ (props changed)
projects/largeSMP/crypto/openssh/ (props changed)
projects/largeSMP/crypto/openssl/ (props changed)
projects/largeSMP/gnu/lib/ (props changed)
projects/largeSMP/gnu/usr.bin/binutils/ (props changed)
projects/largeSMP/gnu/usr.bin/cc/cc_tools/ (props changed)
projects/largeSMP/gnu/usr.bin/gdb/ (props changed)
projects/largeSMP/lib/libc/ (props changed)
projects/largeSMP/lib/libc/stdtime/ (props changed)
projects/largeSMP/lib/libutil/ (props changed)
projects/largeSMP/lib/libz/ (props changed)
projects/largeSMP/sbin/ (props changed)
projects/largeSMP/sbin/ipfw/ (props changed)
projects/largeSMP/share/mk/bsd.arch.inc.mk (props changed)
projects/largeSMP/share/zoneinfo/ (props changed)
projects/largeSMP/sys/ (props changed)
projects/largeSMP/sys/amd64/include/xen/ (props changed)
projects/largeSMP/sys/boot/ (props changed)
projects/largeSMP/sys/boot/i386/efi/ (props changed)
projects/largeSMP/sys/boot/ia64/efi/ (props changed)
projects/largeSMP/sys/boot/ia64/ski/ (props changed)
projects/largeSMP/sys/boot/powerpc/boot1.chrp/ (props changed)
projects/largeSMP/sys/boot/powerpc/ofw/ (props changed)
projects/largeSMP/sys/cddl/contrib/opensolaris/ (props changed)
projects/largeSMP/sys/conf/ (props changed)
projects/largeSMP/sys/contrib/dev/acpica/ (props changed)
projects/largeSMP/sys/contrib/octeon-sdk/ (props changed)
projects/largeSMP/sys/contrib/pf/ (props changed)
projects/largeSMP/sys/contrib/x86emu/ (props changed)
projects/largeSMP/usr.bin/calendar/ (props changed)
projects/largeSMP/usr.bin/csup/ (props changed)
projects/largeSMP/usr.bin/procstat/ (props changed)
projects/largeSMP/usr.sbin/ndiscvt/ (props changed)
projects/largeSMP/usr.sbin/zic/ (props changed)
Modified: projects/largeSMP/sbin/hastctl/hastctl.c
==============================================================================
--- projects/largeSMP/sbin/hastctl/hastctl.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sbin/hastctl/hastctl.c Mon May 23 23:58:02 2011 (r222237)
@@ -341,6 +341,17 @@ control_status(struct nv *nv)
printf(" dirty: %ju (%NB)\n",
(uintmax_t)nv_get_uint64(nv, "dirty%u", ii),
(intmax_t)nv_get_uint64(nv, "dirty%u", ii));
+ printf(" statistics:\n");
+ printf(" reads: %ju\n",
+ (uint64_t)nv_get_uint64(nv, "stat_read%u", ii));
+ printf(" writes: %ju\n",
+ (uint64_t)nv_get_uint64(nv, "stat_write%u", ii));
+ printf(" deletes: %ju\n",
+ (uint64_t)nv_get_uint64(nv, "stat_delete%u", ii));
+ printf(" flushes: %ju\n",
+ (uint64_t)nv_get_uint64(nv, "stat_flush%u", ii));
+ printf(" activemap updates: %ju\n",
+ (uint64_t)nv_get_uint64(nv, "stat_activemap_update%u", ii));
}
return (ret);
}
Modified: projects/largeSMP/sbin/hastd/control.c
==============================================================================
--- projects/largeSMP/sbin/hastd/control.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sbin/hastd/control.c Mon May 23 23:58:02 2011 (r222237)
@@ -199,6 +199,16 @@ control_status_worker(struct hast_resour
"extentsize%u", no);
nv_add_uint32(nvout, nv_get_uint32(cnvin, "keepdirty"),
"keepdirty%u", no);
+ nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_read"),
+ "stat_read%u", no);
+ nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_write"),
+ "stat_write%u", no);
+ nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_delete"),
+ "stat_delete%u", no);
+ nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_flush"),
+ "stat_flush%u", no);
+ nv_add_uint64(nvout, nv_get_uint64(cnvin, "stat_activemap_update"),
+ "stat_activemap_update%u", no);
end:
if (cnvin != NULL)
nv_free(cnvin);
@@ -446,6 +456,13 @@ ctrl_thread(void *arg)
nv_add_uint32(nvout, (uint32_t)0, "keepdirty");
nv_add_uint64(nvout, (uint64_t)0, "dirty");
}
+ nv_add_uint64(nvout, res->hr_stat_read, "stat_read");
+ nv_add_uint64(nvout, res->hr_stat_write, "stat_write");
+ nv_add_uint64(nvout, res->hr_stat_delete,
+ "stat_delete");
+ nv_add_uint64(nvout, res->hr_stat_flush, "stat_flush");
+ nv_add_uint64(nvout, res->hr_stat_activemap_update,
+ "stat_activemap_update");
nv_add_int16(nvout, 0, "error");
break;
case CONTROL_RELOAD:
Modified: projects/largeSMP/sbin/hastd/hast.h
==============================================================================
--- projects/largeSMP/sbin/hastd/hast.h Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sbin/hastd/hast.h Mon May 23 23:58:02 2011 (r222237)
@@ -218,6 +218,17 @@ struct hast_resource {
/* Locked used to synchronize access to hr_amp. */
pthread_mutex_t hr_amp_lock;
+ /* Number of BIO_READ requests. */
+ uint64_t hr_stat_read;
+ /* Number of BIO_WRITE requests. */
+ uint64_t hr_stat_write;
+ /* Number of BIO_DELETE requests. */
+ uint64_t hr_stat_delete;
+ /* Number of BIO_FLUSH requests. */
+ uint64_t hr_stat_flush;
+ /* Number of activemap updates. */
+ uint64_t hr_stat_activemap_update;
+
/* Next resource. */
TAILQ_ENTRY(hast_resource) hr_next;
};
Modified: projects/largeSMP/sbin/hastd/primary.c
==============================================================================
--- projects/largeSMP/sbin/hastd/primary.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sbin/hastd/primary.c Mon May 23 23:58:02 2011 (r222237)
@@ -1117,6 +1117,7 @@ ggate_recv_thread(void *arg)
*/
switch (ggio->gctl_cmd) {
case BIO_READ:
+ res->hr_stat_read++;
pjdlog_debug(2,
"ggate_recv: (%p) Moving request to the send queue.",
hio);
@@ -1145,6 +1146,7 @@ ggate_recv_thread(void *arg)
QUEUE_INSERT1(hio, send, ncomp);
break;
case BIO_WRITE:
+ res->hr_stat_write++;
if (res->hr_resuid == 0) {
/*
* This is first write, initialize localcnt and
@@ -1183,12 +1185,21 @@ ggate_recv_thread(void *arg)
mtx_lock(&res->hr_amp_lock);
if (activemap_write_start(res->hr_amp,
ggio->gctl_offset, ggio->gctl_length)) {
+ res->hr_stat_activemap_update++;
(void)hast_activemap_flush(res);
}
mtx_unlock(&res->hr_amp_lock);
/* FALLTHROUGH */
case BIO_DELETE:
case BIO_FLUSH:
+ switch (ggio->gctl_cmd) {
+ case BIO_DELETE:
+ res->hr_stat_delete++;
+ break;
+ case BIO_FLUSH:
+ res->hr_stat_flush++;
+ break;
+ }
pjdlog_debug(2,
"ggate_recv: (%p) Moving request to the send queues.",
hio);
Modified: projects/largeSMP/sbin/hastd/secondary.c
==============================================================================
--- projects/largeSMP/sbin/hastd/secondary.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sbin/hastd/secondary.c Mon May 23 23:58:02 2011 (r222237)
@@ -612,6 +612,20 @@ recv_thread(void *arg)
QUEUE_INSERT(send, hio);
continue;
}
+ switch (hio->hio_cmd) {
+ case HIO_READ:
+ res->hr_stat_read++;
+ break;
+ case HIO_WRITE:
+ res->hr_stat_write++;
+ break;
+ case HIO_DELETE:
+ res->hr_stat_delete++;
+ break;
+ case HIO_FLUSH:
+ res->hr_stat_flush++;
+ break;
+ }
reqlog(LOG_DEBUG, 2, -1, hio,
"recv: (%p) Got request header: ", hio);
if (hio->hio_cmd == HIO_KEEPALIVE) {
Modified: projects/largeSMP/sbin/hastd/subr.c
==============================================================================
--- projects/largeSMP/sbin/hastd/subr.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sbin/hastd/subr.c Mon May 23 23:58:02 2011 (r222237)
@@ -224,7 +224,13 @@ drop_privs(struct hast_resource *res)
return (-1);
}
- if (res == NULL || res->hr_role != HAST_ROLE_PRIMARY)
+ /*
+ * Until capsicum doesn't allow ioctl(2) we cannot use it to sandbox
+ * primary and secondary worker processes, as primary uses GGATE
+ * ioctls and secondary uses ioctls to handle BIO_DELETE and BIO_FLUSH.
+ * For now capsicum is only used to sandbox hastctl.
+ */
+ if (res == NULL)
capsicum = (cap_enter() == 0);
else
capsicum = false;
Modified: projects/largeSMP/share/man/man4/msk.4
==============================================================================
--- projects/largeSMP/share/man/man4/msk.4 Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/share/man/man4/msk.4 Mon May 23 23:58:02 2011 (r222237)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 23, 2010
+.Dd May 23, 2011
.Dt MSK 4
.Os
.Sh NAME
@@ -195,6 +195,8 @@ Marvell Yukon 88E8071 Gigabit Ethernet
.It
Marvell Yukon 88E8072 Gigabit Ethernet
.It
+Marvell Yukon 88E8075 Gigabit Ethernet
+.It
SysKonnect SK-9Sxx Gigabit Ethernet
.It
SysKonnect SK-9Exx Gigabit Ethernet
Modified: projects/largeSMP/sys/conf/kern.post.mk
==============================================================================
--- projects/largeSMP/sys/conf/kern.post.mk Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/conf/kern.post.mk Mon May 23 23:58:02 2011 (r222237)
@@ -228,7 +228,7 @@ kernel-install:
mkdir -p ${DESTDIR}${KODIR}
${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO} ${DESTDIR}${KODIR}
.if defined(DEBUG) && !defined(INSTALL_NODEBUG) && \
- (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} == "yes")
+ (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} != "no")
${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO}.symbols ${DESTDIR}${KODIR}
.endif
.if defined(KERNEL_EXTRA_INSTALL)
@@ -241,7 +241,7 @@ kernel-reinstall:
@-chflags -R noschg ${DESTDIR}${KODIR}
${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO} ${DESTDIR}${KODIR}
.if defined(DEBUG) && !defined(INSTALL_NODEBUG) && \
- (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} == "yes")
+ (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} != "no")
${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO}.symbols ${DESTDIR}${KODIR}
.endif
Modified: projects/largeSMP/sys/conf/kmod.mk
==============================================================================
--- projects/largeSMP/sys/conf/kmod.mk Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/conf/kmod.mk Mon May 23 23:58:02 2011 (r222237)
@@ -286,8 +286,8 @@ realinstall: _kmodinstall
_kmodinstall:
${INSTALL} -o ${KMODOWN} -g ${KMODGRP} -m ${KMODMODE} \
${_INSTALLFLAGS} ${PROG} ${DESTDIR}${KMODDIR}
-.if defined(DEBUG) && !defined(INSTALL_NODEBUG) && \
- (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} == "yes")
+.if defined(DEBUG_FLAGS) && !defined(INSTALL_NODEBUG) && \
+ (defined(MK_KERNEL_SYMBOLS) && ${MK_KERNEL_SYMBOLS} != "no")
${INSTALL} -o ${KMODOWN} -g ${KMODGRP} -m ${KMODMODE} \
${_INSTALLFLAGS} ${PROG}.symbols ${DESTDIR}${KMODDIR}
.endif
Modified: projects/largeSMP/sys/conf/newvers.sh
==============================================================================
--- projects/largeSMP/sys/conf/newvers.sh Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/conf/newvers.sh Mon May 23 23:58:02 2011 (r222237)
@@ -139,4 +139,4 @@ int osreldate = ${RELDATE};
char kern_ident[] = "${i}";
EOF
-echo `expr ${v} + 1` > version
+echo $((v + 1)) > version
Modified: projects/largeSMP/sys/dev/acpica/acpi_hpet.c
==============================================================================
--- projects/largeSMP/sys/dev/acpica/acpi_hpet.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/dev/acpica/acpi_hpet.c Mon May 23 23:58:02 2011 (r222237)
@@ -476,7 +476,7 @@ hpet_attach(device_t dev)
sc->tc.tc_get_timecount = hpet_get_timecount,
sc->tc.tc_counter_mask = ~0u,
sc->tc.tc_name = "HPET",
- sc->tc.tc_quality = 900,
+ sc->tc.tc_quality = 950,
sc->tc.tc_frequency = sc->freq;
sc->tc.tc_priv = sc;
tc_init(&sc->tc);
Modified: projects/largeSMP/sys/dev/acpica/acpi_timer.c
==============================================================================
--- projects/largeSMP/sys/dev/acpica/acpi_timer.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/dev/acpica/acpi_timer.c Mon May 23 23:58:02 2011 (r222237)
@@ -203,7 +203,7 @@ acpi_timer_probe(device_t dev)
if (j == 10) {
acpi_timer_timecounter.tc_name = "ACPI-fast";
acpi_timer_timecounter.tc_get_timecount = acpi_timer_get_timecount;
- acpi_timer_timecounter.tc_quality = 1000;
+ acpi_timer_timecounter.tc_quality = 900;
} else {
acpi_timer_timecounter.tc_name = "ACPI-safe";
acpi_timer_timecounter.tc_get_timecount = acpi_timer_get_timecount_safe;
Modified: projects/largeSMP/sys/dev/msk/if_msk.c
==============================================================================
--- projects/largeSMP/sys/dev/msk/if_msk.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/dev/msk/if_msk.c Mon May 23 23:58:02 2011 (r222237)
@@ -221,6 +221,10 @@ static struct msk_product {
"Marvell Yukon 88E8071 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_436C,
"Marvell Yukon 88E8072 Gigabit Ethernet" },
+ { VENDORID_MARVELL, DEVICEID_MRVL_436D,
+ "Marvell Yukon 88E8055 Gigabit Ethernet" },
+ { VENDORID_MARVELL, DEVICEID_MRVL_4370,
+ "Marvell Yukon 88E8075 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_4380,
"Marvell Yukon 88E8057 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_4381,
@@ -1030,7 +1034,10 @@ msk_ioctl(struct ifnet *ifp, u_long comm
}
}
ifp->if_mtu = ifr->ifr_mtu;
- msk_init_locked(sc_if);
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ msk_init_locked(sc_if);
+ }
}
MSK_IF_UNLOCK(sc_if);
break;
@@ -1212,37 +1219,30 @@ msk_phy_power(struct msk_softc *sc, int
*/
CSR_WRITE_1(sc, B2_Y2_CLK_GATE, val);
- val = CSR_PCI_READ_4(sc, PCI_OUR_REG_1);
- val &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
+ our = CSR_PCI_READ_4(sc, PCI_OUR_REG_1);
+ our &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
if (sc->msk_hw_id == CHIP_ID_YUKON_XL) {
if (sc->msk_hw_rev > CHIP_REV_YU_XL_A1) {
/* Deassert Low Power for 1st PHY. */
- val |= PCI_Y2_PHY1_COMA;
+ our |= PCI_Y2_PHY1_COMA;
if (sc->msk_num_port > 1)
- val |= PCI_Y2_PHY2_COMA;
+ our |= PCI_Y2_PHY2_COMA;
}
}
- /* Release PHY from PowerDown/COMA mode. */
- CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, val);
- switch (sc->msk_hw_id) {
- case CHIP_ID_YUKON_EC_U:
- case CHIP_ID_YUKON_EX:
- case CHIP_ID_YUKON_FE_P:
- case CHIP_ID_YUKON_UL_2:
- case CHIP_ID_YUKON_OPT:
- CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_OFF);
-
- /* Enable all clocks. */
- CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0);
- our = CSR_PCI_READ_4(sc, PCI_OUR_REG_4);
- our &= (PCI_FORCE_ASPM_REQUEST|PCI_ASPM_GPHY_LINK_DOWN|
- PCI_ASPM_INT_FIFO_EMPTY|PCI_ASPM_CLKRUN_REQUEST);
+ if (sc->msk_hw_id == CHIP_ID_YUKON_EC_U ||
+ sc->msk_hw_id == CHIP_ID_YUKON_EX ||
+ sc->msk_hw_id >= CHIP_ID_YUKON_FE_P) {
+ val = CSR_PCI_READ_4(sc, PCI_OUR_REG_4);
+ val &= (PCI_FORCE_ASPM_REQUEST |
+ PCI_ASPM_GPHY_LINK_DOWN | PCI_ASPM_INT_FIFO_EMPTY |
+ PCI_ASPM_CLKRUN_REQUEST);
/* Set all bits to 0 except bits 15..12. */
- CSR_PCI_WRITE_4(sc, PCI_OUR_REG_4, our);
- our = CSR_PCI_READ_4(sc, PCI_OUR_REG_5);
- our &= PCI_CTL_TIM_VMAIN_AV_MSK;
- CSR_PCI_WRITE_4(sc, PCI_OUR_REG_5, our);
+ CSR_PCI_WRITE_4(sc, PCI_OUR_REG_4, val);
+ val = CSR_PCI_READ_4(sc, PCI_OUR_REG_5);
+ val &= PCI_CTL_TIM_VMAIN_AV_MSK;
+ CSR_PCI_WRITE_4(sc, PCI_OUR_REG_5, val);
CSR_PCI_WRITE_4(sc, PCI_CFG_REG_1, 0);
+ CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_ON);
/*
* Disable status race, workaround for
* Yukon EC Ultra & Yukon EX.
@@ -1251,10 +1251,10 @@ msk_phy_power(struct msk_softc *sc, int
val |= GLB_GPIO_STAT_RACE_DIS;
CSR_WRITE_4(sc, B2_GP_IO, val);
CSR_READ_4(sc, B2_GP_IO);
- break;
- default:
- break;
}
+ /* Release PHY from PowerDown/COMA mode. */
+ CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, our);
+
for (i = 0; i < sc->msk_num_port; i++) {
CSR_WRITE_2(sc, MR_ADDR(i, GMAC_LINK_CTRL),
GMLC_RST_SET);
@@ -1300,28 +1300,33 @@ mskc_reset(struct msk_softc *sc)
bus_addr_t addr;
uint16_t status;
uint32_t val;
- int i;
-
- CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
+ int i, initram;
/* Disable ASF. */
- if (sc->msk_hw_id == CHIP_ID_YUKON_EX) {
- status = CSR_READ_2(sc, B28_Y2_ASF_HCU_CCSR);
- /* Clear AHB bridge & microcontroller reset. */
- status &= ~(Y2_ASF_HCU_CCSR_AHB_RST |
- Y2_ASF_HCU_CCSR_CPU_RST_MODE);
- /* Clear ASF microcontroller state. */
- status &= ~ Y2_ASF_HCU_CCSR_UC_STATE_MSK;
- CSR_WRITE_2(sc, B28_Y2_ASF_HCU_CCSR, status);
- } else
- CSR_WRITE_1(sc, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
- CSR_WRITE_2(sc, B0_CTST, Y2_ASF_DISABLE);
-
- /*
- * Since we disabled ASF, S/W reset is required for Power Management.
- */
- CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
- CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
+ if (sc->msk_hw_id >= CHIP_ID_YUKON_XL &&
+ sc->msk_hw_id <= CHIP_ID_YUKON_SUPR) {
+ if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
+ sc->msk_hw_id == CHIP_ID_YUKON_SUPR) {
+ CSR_WRITE_4(sc, B28_Y2_CPU_WDOG, 0);
+ status = CSR_READ_2(sc, B28_Y2_ASF_HCU_CCSR);
+ /* Clear AHB bridge & microcontroller reset. */
+ status &= ~(Y2_ASF_HCU_CCSR_AHB_RST |
+ Y2_ASF_HCU_CCSR_CPU_RST_MODE);
+ /* Clear ASF microcontroller state. */
+ status &= ~Y2_ASF_HCU_CCSR_UC_STATE_MSK;
+ status &= ~Y2_ASF_HCU_CCSR_CPU_CLK_DIVIDE_MSK;
+ CSR_WRITE_2(sc, B28_Y2_ASF_HCU_CCSR, status);
+ CSR_WRITE_4(sc, B28_Y2_CPU_WDOG, 0);
+ } else
+ CSR_WRITE_1(sc, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
+ CSR_WRITE_2(sc, B0_CTST, Y2_ASF_DISABLE);
+ /*
+ * Since we disabled ASF, S/W reset is required for
+ * Power Management.
+ */
+ CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
+ CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
+ }
/* Clear all error bits in the PCI status register. */
status = pci_read_config(sc->msk_dev, PCIR_STATUS, 2);
@@ -1362,17 +1367,22 @@ mskc_reset(struct msk_softc *sc)
/* Reset GPHY/GMAC Control */
for (i = 0; i < sc->msk_num_port; i++) {
/* GPHY Control reset. */
- CSR_WRITE_4(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_SET);
- CSR_WRITE_4(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_CLR);
+ CSR_WRITE_1(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_SET);
+ CSR_WRITE_1(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_CLR);
/* GMAC Control reset. */
CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_SET);
CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_CLR);
CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_F_LOOPB_OFF);
- if (sc->msk_hw_id == CHIP_ID_YUKON_EX)
+ if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
+ sc->msk_hw_id == CHIP_ID_YUKON_SUPR)
CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL),
GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON |
GMC_BYP_RETR_ON);
}
+
+ if (sc->msk_hw_id == CHIP_ID_YUKON_SUPR &&
+ sc->msk_hw_rev > CHIP_REV_YU_SU_B0)
+ CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, PCI_CLK_MACSEC_DIS);
if (sc->msk_hw_id == CHIP_ID_YUKON_OPT && sc->msk_hw_rev == 0) {
/* Disable PCIe PHY powerdown(reg 0x80, bit7). */
CSR_WRITE_4(sc, Y2_PEX_PHY_DATA, (0x0080 << 16) | 0x0080);
@@ -1396,8 +1406,14 @@ mskc_reset(struct msk_softc *sc)
CSR_WRITE_1(sc, GMAC_TI_ST_CTRL, GMT_ST_STOP);
CSR_WRITE_1(sc, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
+ initram = 0;
+ if (sc->msk_hw_id == CHIP_ID_YUKON_XL ||
+ sc->msk_hw_id == CHIP_ID_YUKON_EC ||
+ sc->msk_hw_id == CHIP_ID_YUKON_FE)
+ initram++;
+
/* Configure timeout values. */
- for (i = 0; i < sc->msk_num_port; i++) {
+ for (i = 0; initram > 0 && i < sc->msk_num_port; i++) {
CSR_WRITE_2(sc, SELECT_RAM_BUFFER(i, B3_RI_CTRL), RI_RST_SET);
CSR_WRITE_2(sc, SELECT_RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);
CSR_WRITE_1(sc, SELECT_RAM_BUFFER(i, B3_RI_WTO_R1),
@@ -1706,13 +1722,15 @@ mskc_attach(device_t dev)
}
}
+ /* Enable all clocks before accessing any registers. */
+ CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0);
+
CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
sc->msk_hw_id = CSR_READ_1(sc, B2_CHIP_ID);
sc->msk_hw_rev = (CSR_READ_1(sc, B2_MAC_CFG) >> 4) & 0x0f;
/* Bail out if chip is not recognized. */
if (sc->msk_hw_id < CHIP_ID_YUKON_XL ||
sc->msk_hw_id > CHIP_ID_YUKON_OPT ||
- sc->msk_hw_id == CHIP_ID_YUKON_SUPR ||
sc->msk_hw_id == CHIP_ID_YUKON_UNKNOWN) {
device_printf(dev, "unknown device: id=0x%02x, rev=0x%02x\n",
sc->msk_hw_id, sc->msk_hw_rev);
@@ -1746,9 +1764,6 @@ mskc_attach(device_t dev)
resource_int_value(device_get_name(dev), device_get_unit(dev),
"int_holdoff", &sc->msk_int_holdoff);
- /* Soft reset. */
- CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
- CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
sc->msk_pmd = CSR_READ_1(sc, B2_PMD_TYP);
/* Check number of MACs. */
sc->msk_num_port = 1;
@@ -1822,6 +1837,11 @@ mskc_attach(device_t dev)
sc->msk_clock = 156; /* 156 MHz */
sc->msk_pflags |= MSK_FLAG_JUMBO;
break;
+ case CHIP_ID_YUKON_SUPR:
+ sc->msk_clock = 125; /* 125 MHz */
+ sc->msk_pflags |= MSK_FLAG_JUMBO | MSK_FLAG_DESCV2 |
+ MSK_FLAG_AUTOTX_CSUM;
+ break;
case CHIP_ID_YUKON_UL_2:
sc->msk_clock = 125; /* 125 MHz */
sc->msk_pflags |= MSK_FLAG_JUMBO;
@@ -2963,6 +2983,7 @@ mskc_resume(device_t dev)
MSK_LOCK(sc);
+ CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0);
mskc_reset(sc);
for (i = 0; i < sc->msk_num_port; i++) {
if (sc->msk_if[i] != NULL && sc->msk_if[i]->msk_ifp != NULL &&
@@ -3654,37 +3675,24 @@ msk_set_tx_stfwd(struct msk_if_softc *sc
ifp = sc_if->msk_ifp;
sc = sc_if->msk_softc;
- switch (sc->msk_hw_id) {
- case CHIP_ID_YUKON_EX:
- if (sc->msk_hw_rev == CHIP_REV_YU_EX_A0)
- goto yukon_ex_workaround;
- if (ifp->if_mtu > ETHERMTU)
- CSR_WRITE_4(sc,
- MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
- TX_JUMBO_ENA | TX_STFW_ENA);
- else
- CSR_WRITE_4(sc,
- MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
- TX_JUMBO_DIS | TX_STFW_ENA);
- break;
- default:
-yukon_ex_workaround:
+ if ((sc->msk_hw_id == CHIP_ID_YUKON_EX &&
+ sc->msk_hw_rev != CHIP_REV_YU_EX_A0) ||
+ sc->msk_hw_id >= CHIP_ID_YUKON_SUPR) {
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
+ TX_STFW_ENA);
+ } else {
if (ifp->if_mtu > ETHERMTU) {
/* Set Tx GMAC FIFO Almost Empty Threshold. */
CSR_WRITE_4(sc,
MR_ADDR(sc_if->msk_port, TX_GMF_AE_THR),
MSK_ECU_JUMBO_WM << 16 | MSK_ECU_AE_THR);
/* Disable Store & Forward mode for Tx. */
- CSR_WRITE_4(sc,
- MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
- TX_JUMBO_ENA | TX_STFW_DIS);
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
+ TX_STFW_DIS);
} else {
- /* Enable Store & Forward mode for Tx. */
- CSR_WRITE_4(sc,
- MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
- TX_JUMBO_DIS | TX_STFW_ENA);
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
+ TX_STFW_ENA);
}
- break;
}
}
@@ -3737,7 +3745,8 @@ msk_init_locked(struct msk_if_softc *sc_
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET);
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR);
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF);
- if (sc->msk_hw_id == CHIP_ID_YUKON_EX)
+ if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
+ sc->msk_hw_id == CHIP_ID_YUKON_SUPR)
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL),
GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON |
GMC_BYP_RETR_ON);
@@ -3932,7 +3941,8 @@ msk_init_locked(struct msk_if_softc *sc_
msk_stop(sc_if);
return;
}
- if (sc->msk_hw_id == CHIP_ID_YUKON_EX) {
+ if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
+ sc->msk_hw_id == CHIP_ID_YUKON_SUPR) {
/* Disable flushing of non-ASF packets. */
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T),
GMF_RX_MACSEC_FLUSH_OFF);
Modified: projects/largeSMP/sys/dev/msk/if_mskreg.h
==============================================================================
--- projects/largeSMP/sys/dev/msk/if_mskreg.h Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/dev/msk/if_mskreg.h Mon May 23 23:58:02 2011 (r222237)
@@ -144,6 +144,8 @@
#define DEVICEID_MRVL_436A 0x436A
#define DEVICEID_MRVL_436B 0x436B
#define DEVICEID_MRVL_436C 0x436C
+#define DEVICEID_MRVL_436D 0x436D
+#define DEVICEID_MRVL_4370 0x4370
#define DEVICEID_MRVL_4380 0x4380
#define DEVICEID_MRVL_4381 0x4381
@@ -321,6 +323,9 @@
#define PCI_OS_SPD_X100 2 /* PCI-X 100MHz Bus */
#define PCI_OS_SPD_X133 3 /* PCI-X 133MHz Bus */
+/* PCI_OUR_REG_3 32 bit Our Register 3 (Yukon-ECU only) */
+#define PCI_CLK_MACSEC_DIS BIT_17 /* Disable Clock MACSec. */
+
/* PCI_OUR_REG_4 32 bit Our Register 4 (Yukon-ECU only) */
#define PCI_TIMER_VALUE_MSK (0xff<<16) /* Bit 23..16: Timer Value Mask */
#define PCI_FORCE_ASPM_REQUEST BIT_15 /* Force ASPM Request (A1 only) */
@@ -677,6 +682,7 @@
/* ASF Subsystem Registers (Yukon-2 only) */
#define B28_Y2_SMB_CONFIG 0x0e40 /* 32 bit ASF SMBus Config Register */
#define B28_Y2_SMB_CSD_REG 0x0e44 /* 32 bit ASF SMB Control/Status/Data */
+#define B28_Y2_CPU_WDOG 0x0e48 /* 32 bit Watchdog Register */
#define B28_Y2_ASF_IRQ_V_BASE 0x0e60 /* 32 bit ASF IRQ Vector Base */
#define B28_Y2_ASF_STAT_CMD 0x0e68 /* 32 bit ASF Status and Command Reg */
#define B28_Y2_ASF_HCU_CCSR 0x0e68 /* 32 bit ASF HCU CCSR (Yukon EX) */
@@ -918,6 +924,10 @@
#define CHIP_REV_YU_EX_A0 1 /* Chip Rev. for Yukon-2 EX A0 */
#define CHIP_REV_YU_EX_B0 2 /* Chip Rev. for Yukon-2 EX B0 */
+#define CHIP_REV_YU_SU_A0 0 /* Chip Rev. for Yukon-2 SUPR A0 */
+#define CHIP_REV_YU_SU_B0 1 /* Chip Rev. for Yukon-2 SUPR B0 */
+#define CHIP_REV_YU_SU_B1 3 /* Chip Rev. for Yukon-2 SUPR B1 */
+
/* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */
#define Y2_STATUS_LNK2_INAC BIT_7 /* Status Link 2 inactiv (0 = activ) */
#define Y2_CLK_GAT_LNK2_DIS BIT_6 /* Disable clock gating Link 2 */
Modified: projects/largeSMP/sys/fs/nfsclient/nfs_clvfsops.c
==============================================================================
--- projects/largeSMP/sys/fs/nfsclient/nfs_clvfsops.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/fs/nfsclient/nfs_clvfsops.c Mon May 23 23:58:02 2011 (r222237)
@@ -79,6 +79,7 @@ FEATURE(nfscl, "NFSv4 client");
extern int nfscl_ticks;
extern struct timeval nfsboottime;
extern struct nfsstats newnfsstats;
+extern int nfsrv_useacl;
MALLOC_DEFINE(M_NEWNFSREQ, "newnfsclient_req", "New NFS request header");
MALLOC_DEFINE(M_NEWNFSMNT, "newnfsmnt", "New NFS mount struct");
@@ -1331,6 +1332,15 @@ mountnfs(struct nfs_args *argp, struct m
if (argp->flags & NFSMNT_NFSV3)
ncl_fsinfo(nmp, *vpp, cred, td);
+ /* Mark if the mount point supports NFSv4 ACLs. */
+ if ((argp->flags & NFSMNT_NFSV4) != 0 && nfsrv_useacl != 0 &&
+ ret == 0 &&
+ NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL)) {
+ MNT_ILOCK(mp);
+ mp->mnt_flag |= MNT_NFS4ACLS;
+ MNT_IUNLOCK(mp);
+ }
+
/*
* Lose the lock but keep the ref.
*/
Modified: projects/largeSMP/sys/geom/gate/g_gate.c
==============================================================================
--- projects/largeSMP/sys/geom/gate/g_gate.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/geom/gate/g_gate.c Mon May 23 23:58:02 2011 (r222237)
@@ -180,6 +180,7 @@ g_gate_start(struct bio *bp)
break;
case BIO_DELETE:
case BIO_WRITE:
+ case BIO_FLUSH:
/* XXX: Hack to allow read-only mounts. */
if ((sc->sc_flags & G_GATE_FLAG_READONLY) != 0) {
g_io_deliver(bp, EPERM);
@@ -580,6 +581,7 @@ g_gate_ioctl(struct cdev *dev, u_long cm
switch (bp->bio_cmd) {
case BIO_READ:
case BIO_DELETE:
+ case BIO_FLUSH:
break;
case BIO_WRITE:
error = copyout(bp->bio_data, ggio->gctl_data,
@@ -643,6 +645,7 @@ start_end:
break;
case BIO_DELETE:
case BIO_WRITE:
+ case BIO_FLUSH:
break;
}
}
Modified: projects/largeSMP/sys/kern/kern_environment.c
==============================================================================
--- projects/largeSMP/sys/kern/kern_environment.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/kern/kern_environment.c Mon May 23 23:58:02 2011 (r222237)
@@ -225,13 +225,19 @@ static void
init_dynamic_kenv(void *data __unused)
{
char *cp;
- int len, i;
+ size_t len;
+ int i;
kenvp = malloc((KENV_SIZE + 1) * sizeof(char *), M_KENV,
M_WAITOK | M_ZERO);
i = 0;
for (cp = kern_envp; cp != NULL; cp = kernenv_next(cp)) {
len = strlen(cp) + 1;
+ if (len > KENV_MNAMELEN + 1 + KENV_MVALLEN + 1) {
+ printf("WARNING: too long kenv string, ignoring %s\n",
+ cp);
+ continue;
+ }
if (i < KENV_SIZE) {
kenvp[i] = malloc(len, M_KENV, M_WAITOK);
strcpy(kenvp[i++], cp);
Modified: projects/largeSMP/sys/kern/vfs_bio.c
==============================================================================
--- projects/largeSMP/sys/kern/vfs_bio.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/kern/vfs_bio.c Mon May 23 23:58:02 2011 (r222237)
@@ -654,7 +654,7 @@ bufinit(void)
* To support extreme low-memory systems, make sure hidirtybuffers cannot
* eat up all available buffer space. This occurs when our minimum cannot
* be met. We try to size hidirtybuffers to 3/4 our buffer space assuming
- * BKVASIZE'd (8K) buffers.
+ * BKVASIZE'd buffers.
*/
while ((long)hidirtybuffers * BKVASIZE > 3 * hibufspace / 4) {
hidirtybuffers >>= 1;
Modified: projects/largeSMP/sys/netinet/in_pcb.c
==============================================================================
--- projects/largeSMP/sys/netinet/in_pcb.c Mon May 23 23:51:01 2011 (r222236)
+++ projects/largeSMP/sys/netinet/in_pcb.c Mon May 23 23:58:02 2011 (r222237)
@@ -2,8 +2,12 @@
* Copyright (c) 1982, 1986, 1991, 1993, 1995
* The Regents of the University of California.
* Copyright (c) 2007-2009 Robert N. M. Watson
+ * Copyright (c) 2010-2011 Juniper Networks, Inc.
* All rights reserved.
*
+ * Portions of this software were developed by Robert N. M. Watson under
+ * contract to Juniper Networks, Inc.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -50,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socketvar.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/refcount.h>
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
@@ -287,7 +292,7 @@ in_pcballoc(struct socket *so, struct in
#endif
INP_WLOCK(inp);
inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
- inp->inp_refcount = 1; /* Reference from the inpcbinfo */
+ refcount_init(&inp->inp_refcount, 1); /* Reference from inpcbinfo */
#if defined(IPSEC) || defined(MAC)
out:
if (error != 0) {
@@ -329,7 +334,7 @@ in_pcbbind(struct inpcb *inp, struct soc
#if defined(INET) || defined(INET6)
int
in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, u_short *lportp,
- struct ucred *cred, int wild)
+ struct ucred *cred, int lookupflags)
{
struct inpcbinfo *pcbinfo;
struct inpcb *tmpinp;
@@ -424,14 +429,14 @@ in_pcb_lport(struct inpcb *inp, struct i
#ifdef INET6
if ((inp->inp_vflag & INP_IPV6) != 0)
tmpinp = in6_pcblookup_local(pcbinfo,
- &inp->in6p_laddr, lport, wild, cred);
+ &inp->in6p_laddr, lport, lookupflags, cred);
#endif
#if defined(INET) && defined(INET6)
else
#endif
#ifdef INET
tmpinp = in_pcblookup_local(pcbinfo, laddr,
- lport, wild, cred);
+ lport, lookupflags, cred);
#endif
} while (tmpinp != NULL);
@@ -464,7 +469,7 @@ in_pcbbind_setup(struct inpcb *inp, stru
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
struct in_addr laddr;
u_short lport = 0;
- int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
+ int lookupflags = 0, reuseport = (so->so_options & SO_REUSEPORT);
int error;
/*
@@ -480,7 +485,7 @@ in_pcbbind_setup(struct inpcb *inp, stru
if (nam != NULL && laddr.s_addr != INADDR_ANY)
return (EINVAL);
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
- wild = INPLOOKUP_WILDCARD;
+ lookupflags = INPLOOKUP_WILDCARD;
if (nam == NULL) {
if ((error = prison_local_ip4(cred, &laddr)) != 0)
return (error);
@@ -561,7 +566,7 @@ in_pcbbind_setup(struct inpcb *inp, stru
return (EADDRINUSE);
}
t = in_pcblookup_local(pcbinfo, sin->sin_addr,
- lport, wild, cred);
+ lport, lookupflags, cred);
if (t && (t->inp_flags & INP_TIMEWAIT)) {
/*
* XXXRW: If an incpb has had its timewait
@@ -590,7 +595,7 @@ in_pcbbind_setup(struct inpcb *inp, stru
if (*lportp != 0)
lport = *lportp;
if (lport == 0) {
- error = in_pcb_lport(inp, &laddr, &lport, cred, wild);
+ error = in_pcb_lport(inp, &laddr, &lport, cred, lookupflags);
if (error != 0)
return (error);
@@ -1028,56 +1033,18 @@ in_pcbdetach(struct inpcb *inp)
}
/*
- * in_pcbfree_internal() frees an inpcb that has been detached from its
- * socket, and whose reference count has reached 0. It will also remove the
- * inpcb from any global lists it might remain on.
- */
-static void
-in_pcbfree_internal(struct inpcb *inp)
-{
- struct inpcbinfo *ipi = inp->inp_pcbinfo;
-
- KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
- KASSERT(inp->inp_refcount == 0, ("%s: refcount !0", __func__));
-
- INP_INFO_WLOCK_ASSERT(ipi);
- INP_WLOCK_ASSERT(inp);
-
-#ifdef IPSEC
- if (inp->inp_sp != NULL)
- ipsec_delete_pcbpolicy(inp);
-#endif /* IPSEC */
- inp->inp_gencnt = ++ipi->ipi_gencnt;
- in_pcbremlists(inp);
-#ifdef INET6
- if (inp->inp_vflag & INP_IPV6PROTO) {
- ip6_freepcbopts(inp->in6p_outputopts);
- if (inp->in6p_moptions != NULL)
- ip6_freemoptions(inp->in6p_moptions);
- }
-#endif
- if (inp->inp_options)
- (void)m_free(inp->inp_options);
-#ifdef INET
- if (inp->inp_moptions != NULL)
- inp_freemoptions(inp->inp_moptions);
-#endif
- inp->inp_vflag = 0;
- crfree(inp->inp_cred);
-
-#ifdef MAC
- mac_inpcb_destroy(inp);
-#endif
- INP_WUNLOCK(inp);
- uma_zfree(ipi->ipi_zone, inp);
-}
-
-/*
* in_pcbref() bumps the reference count on an inpcb in order to maintain
* stability of an inpcb pointer despite the inpcb lock being released. This
* is used in TCP when the inpcbinfo lock needs to be acquired or upgraded,
* but where the inpcb lock is already held.
*
+ * in_pcbref() should be used only to provide brief memory stability, and
+ * must always be followed by a call to INP_WLOCK() and in_pcbrele() to
+ * garbage collect the inpcb if it has been in_pcbfree()'d from another
+ * context. Until in_pcbrele() has returned that the inpcb is still valid,
+ * lock and rele are the *only* safe operations that may be performed on the
+ * inpcb.
+ *
* While the inpcb will not be freed, releasing the inpcb lock means that the
* connection's state may change, so the caller should be careful to
* revalidate any cached state on reacquiring the lock. Drop the reference
@@ -1091,7 +1058,7 @@ in_pcbref(struct inpcb *inp)
KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
- inp->inp_refcount++;
+ refcount_acquire(&inp->inp_refcount);
}
/*
@@ -1099,47 +1066,108 @@ in_pcbref(struct inpcb *inp)
* in_pcbfree() may have been made between in_pcbref() and in_pcbrele(), we
* return a flag indicating whether or not the inpcb remains valid. If it is
* valid, we return with the inpcb lock held.
+ *
+ * Notice that, unlike in_pcbref(), the inpcb lock must be held to drop a
+ * reference on an inpcb. Historically more work was done here (actually, in
+ * in_pcbfree_internal()) but has been moved to in_pcbfree() to avoid the
+ * need for the pcbinfo lock in in_pcbrele(). Deferring the free is entirely
+ * about memory stability (and continued use of the write lock).
*/
int
-in_pcbrele(struct inpcb *inp)
+in_pcbrele_rlocked(struct inpcb *inp)
{
-#ifdef INVARIANTS
- struct inpcbinfo *ipi = inp->inp_pcbinfo;
-#endif
+ struct inpcbinfo *pcbinfo;
+
+ KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
+
+ INP_RLOCK_ASSERT(inp);
+
+ if (refcount_release(&inp->inp_refcount) == 0)
+ return (0);
+
+ KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
+
+ INP_RUNLOCK(inp);
+ pcbinfo = inp->inp_pcbinfo;
+ uma_zfree(pcbinfo->ipi_zone, inp);
+ return (1);
+}
+
+int
+in_pcbrele_wlocked(struct inpcb *inp)
+{
+ struct inpcbinfo *pcbinfo;
KASSERT(inp->inp_refcount > 0, ("%s: refcount 0", __func__));
- INP_INFO_WLOCK_ASSERT(ipi);
INP_WLOCK_ASSERT(inp);
- inp->inp_refcount--;
- if (inp->inp_refcount > 0)
+ if (refcount_release(&inp->inp_refcount) == 0)
return (0);
- in_pcbfree_internal(inp);
+
+ KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
+
+ INP_WUNLOCK(inp);
+ pcbinfo = inp->inp_pcbinfo;
+ uma_zfree(pcbinfo->ipi_zone, inp);
return (1);
}
/*
+ * Temporary wrapper.
+ */
+int
+in_pcbrele(struct inpcb *inp)
+{
+
+ return (in_pcbrele_wlocked(inp));
+}
+
+/*
* Unconditionally schedule an inpcb to be freed by decrementing its
* reference count, which should occur only after the inpcb has been detached
* from its socket. If another thread holds a temporary reference (acquired
* using in_pcbref()) then the free is deferred until that reference is
- * released using in_pcbrele(), but the inpcb is still unlocked.
+ * released using in_pcbrele(), but the inpcb is still unlocked. Almost all
+ * work, including removal from global lists, is done in this context, where
+ * the pcbinfo lock is held.
*/
void
in_pcbfree(struct inpcb *inp)
{
-#ifdef INVARIANTS
- struct inpcbinfo *ipi = inp->inp_pcbinfo;
-#endif
+ struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
- KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL",
- __func__));
+ KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__));
- INP_INFO_WLOCK_ASSERT(ipi);
+ INP_INFO_WLOCK_ASSERT(pcbinfo);
INP_WLOCK_ASSERT(inp);
- if (!in_pcbrele(inp))
+ /* XXXRW: Do as much as possible here. */
+#ifdef IPSEC
+ if (inp->inp_sp != NULL)
+ ipsec_delete_pcbpolicy(inp);
+#endif /* IPSEC */
+ inp->inp_gencnt = ++pcbinfo->ipi_gencnt;
+ in_pcbremlists(inp);
+#ifdef INET6
+ if (inp->inp_vflag & INP_IPV6PROTO) {
+ ip6_freepcbopts(inp->in6p_outputopts);
+ if (inp->in6p_moptions != NULL)
+ ip6_freemoptions(inp->in6p_moptions);
+ }
+#endif
+ if (inp->inp_options)
+ (void)m_free(inp->inp_options);
+#ifdef INET
+ if (inp->inp_moptions != NULL)
+ inp_freemoptions(inp->inp_moptions);
+#endif
+ inp->inp_vflag = 0;
+ crfree(inp->inp_cred);
+#ifdef MAC
+ mac_inpcb_destroy(inp);
+#endif
+ if (!in_pcbrele_wlocked(inp))
INP_WUNLOCK(inp);
}
@@ -1307,7 +1335,7 @@ in_pcbpurgeif0(struct inpcbinfo *pcbinfo
#define INP_LOOKUP_MAPPED_PCB_COST 3
struct inpcb *
in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr,
- u_short lport, int wild_okay, struct ucred *cred)
+ u_short lport, int lookupflags, struct ucred *cred)
{
struct inpcb *inp;
#ifdef INET6
@@ -1317,9 +1345,12 @@ in_pcblookup_local(struct inpcbinfo *pcb
#endif
int wildcard;
+ KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
+ ("%s: invalid lookup flags %d", __func__, lookupflags));
+
INP_INFO_LOCK_ASSERT(pcbinfo);
- if (!wild_okay) {
+ if ((lookupflags & INPLOOKUP_WILDCARD) == 0) {
struct inpcbhead *head;
/*
* Look for an unconnected (wildcard foreign addr) PCB that
@@ -1425,13 +1456,16 @@ in_pcblookup_local(struct inpcbinfo *pcb
*/
struct inpcb *
in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr,
- u_int fport_arg, struct in_addr laddr, u_int lport_arg, int wildcard,
+ u_int fport_arg, struct in_addr laddr, u_int lport_arg, int lookupflags,
struct ifnet *ifp)
{
struct inpcbhead *head;
struct inpcb *inp, *tmpinp;
u_short fport = fport_arg, lport = lport_arg;
+ KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
+ ("%s: invalid lookup flags %d", __func__, lookupflags));
+
INP_INFO_LOCK_ASSERT(pcbinfo);
/*
@@ -1467,7 +1501,7 @@ in_pcblookup_hash(struct inpcbinfo *pcbi
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list