diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 8fc9c5a86a75..e76b2f88b5d3 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,7 +38,7 @@ # xargs -n1 | sort | uniq -d; # done -# 20141128: new clang import which bumps version from 3.4.1 to 3.5.0. +# 20141201: new clang import which bumps version from 3.4.1 to 3.5.0. OLD_FILES+=usr/include/clang/3.4.1/__wmmintrin_aes.h OLD_FILES+=usr/include/clang/3.4.1/__wmmintrin_pclmul.h OLD_FILES+=usr/include/clang/3.4.1/altivec.h @@ -74,6 +74,8 @@ OLD_FILES+=usr/include/clang/3.4.1/x86intrin.h OLD_FILES+=usr/include/clang/3.4.1/xmmintrin.h OLD_FILES+=usr/include/clang/3.4.1/xopintrin.h OLD_DIRS+=usr/include/clang/3.4.1 +# 20141129: mrouted rc.d scripts removed from base +OLD_FILES+=etc/rc.d/mrouted # 20141126: convert sbin/mdconfig/tests to ATF format tests OLD_FILES+=usr/tests/sbin/mdconfig/legacy_test OLD_FILES+=usr/tests/sbin/mdconfig/mdconfig.test diff --git a/bin/sh/eval.c b/bin/sh/eval.c index c1a9cdbfcd93..d0460a024e3d 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -774,15 +774,7 @@ xtracecommand(struct arglist *varlist, struct arglist *arglist) for (sp = arglist->list ; sp ; sp = sp->next) { if (sep != 0) out2c(' '); - /* Disambiguate command looking like assignment. */ - if (sp == arglist->list && - strchr(sp->text, '=') != NULL && - strchr(sp->text, '\'') == NULL) { - out2c('\''); - out2str(sp->text); - out2c('\''); - } else - out2qstr(sp->text); + out2qstr(sp->text); sep = ' '; } out2c('\n'); diff --git a/bin/sh/output.c b/bin/sh/output.c index bf8e17d97ece..c6d118f11535 100644 --- a/bin/sh/output.c +++ b/bin/sh/output.c @@ -122,8 +122,7 @@ outqstr(const char *p, struct output *file) outstr("''", file); return; } - /* Caller will handle '=' if necessary */ - if (p[strcspn(p, "|&;<>()$`\\\"' \t\n*?[~#")] == '\0' || + if (p[strcspn(p, "|&;<>()$`\\\"' \t\n*?[~#=")] == '\0' || strcmp(p, "[") == 0) { outstr(p, file); return; diff --git a/contrib/binutils/bfd/elf32-arm.c b/contrib/binutils/bfd/elf32-arm.c index 83acfe564714..47b6566c2e2b 100644 --- a/contrib/binutils/bfd/elf32-arm.c +++ b/contrib/binutils/bfd/elf32-arm.c @@ -4960,7 +4960,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, + input_section->output_offset + rel->r_offset); - value = abs (relocation); + value = llabs (relocation); if (value >= 0x1000) return bfd_reloc_overflow; @@ -4998,7 +4998,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, + input_section->output_offset + rel->r_offset); - value = abs (relocation); + value = llabs (relocation); if (value >= 0x1000) return bfd_reloc_overflow; @@ -5984,7 +5984,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, /* Calculate the value of the relevant G_n, in encoded constant-with-rotation format. */ - g_n = calculate_group_reloc_mask (abs (signed_value), group, + g_n = calculate_group_reloc_mask (llabs (signed_value), group, &residual); /* Check for overflow if required. */ @@ -5998,7 +5998,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, (*_bfd_error_handler) (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"), input_bfd, input_section, - (long) rel->r_offset, abs (signed_value), howto->name); + (long) rel->r_offset, llabs (signed_value), howto->name); return bfd_reloc_overflow; } @@ -6077,7 +6077,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, /* Calculate the value of the relevant G_{n-1} to obtain the residual at that stage. */ - calculate_group_reloc_mask (abs (signed_value), group - 1, &residual); + calculate_group_reloc_mask (llabs (signed_value), group - 1, &residual); /* Check for overflow. */ if (residual >= 0x1000) @@ -6085,7 +6085,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, (*_bfd_error_handler) (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"), input_bfd, input_section, - (long) rel->r_offset, abs (signed_value), howto->name); + (long) rel->r_offset, llabs (signed_value), howto->name); return bfd_reloc_overflow; } @@ -6160,7 +6160,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, /* Calculate the value of the relevant G_{n-1} to obtain the residual at that stage. */ - calculate_group_reloc_mask (abs (signed_value), group - 1, &residual); + calculate_group_reloc_mask (llabs (signed_value), group - 1, &residual); /* Check for overflow. */ if (residual >= 0x100) @@ -6168,7 +6168,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, (*_bfd_error_handler) (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"), input_bfd, input_section, - (long) rel->r_offset, abs (signed_value), howto->name); + (long) rel->r_offset, llabs (signed_value), howto->name); return bfd_reloc_overflow; } @@ -6243,7 +6243,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, /* Calculate the value of the relevant G_{n-1} to obtain the residual at that stage. */ - calculate_group_reloc_mask (abs (signed_value), group - 1, &residual); + calculate_group_reloc_mask (llabs (signed_value), group - 1, &residual); /* Check for overflow. (The absolute value to go in the place must be divisible by four and, after having been divided by four, must @@ -6253,7 +6253,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, (*_bfd_error_handler) (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"), input_bfd, input_section, - (long) rel->r_offset, abs (signed_value), howto->name); + (long) rel->r_offset, llabs (signed_value), howto->name); return bfd_reloc_overflow; } diff --git a/contrib/gcc/config/arm/lib1funcs.asm b/contrib/gcc/config/arm/lib1funcs.asm index 9245b3ca0c0d..c29f89496cf2 100644 --- a/contrib/gcc/config/arm/lib1funcs.asm +++ b/contrib/gcc/config/arm/lib1funcs.asm @@ -980,8 +980,6 @@ LSYM(Lover12): RET - FUNC_END aeabi_ldiv0 - FUNC_END aeabi_idiv0 FUNC_END div0 #endif /* L_divmodsi_tools */ diff --git a/contrib/ofed/librdmacm/examples/build/cmatose/Makefile b/contrib/ofed/librdmacm/examples/build/cmatose/Makefile index c4515ac33ebc..31d2ae7f7f6b 100644 --- a/contrib/ofed/librdmacm/examples/build/cmatose/Makefile +++ b/contrib/ofed/librdmacm/examples/build/cmatose/Makefile @@ -6,5 +6,6 @@ PROG= cmatose MAN= SRCS= cmatose.c LDADD+= -libverbs -lrdmacm -lpthread +LDADD+= -lmlx4 .include <bsd.prog.mk> diff --git a/contrib/ofed/librdmacm/examples/build/mckey/Makefile b/contrib/ofed/librdmacm/examples/build/mckey/Makefile index d4ad2954d52b..4abaf2786d56 100644 --- a/contrib/ofed/librdmacm/examples/build/mckey/Makefile +++ b/contrib/ofed/librdmacm/examples/build/mckey/Makefile @@ -6,5 +6,6 @@ PROG= mckey MAN= SRCS= mckey.c LDADD+= -libverbs -lrdmacm -lpthread +LDADD+= -lmlx4 .include <bsd.prog.mk> diff --git a/contrib/ofed/librdmacm/examples/build/rping/Makefile b/contrib/ofed/librdmacm/examples/build/rping/Makefile index 05ef562400e9..b167a543c092 100644 --- a/contrib/ofed/librdmacm/examples/build/rping/Makefile +++ b/contrib/ofed/librdmacm/examples/build/rping/Makefile @@ -6,5 +6,6 @@ PROG= rping MAN= SRCS= rping.c LDADD+= -libverbs -lrdmacm -lpthread +LDADD+= -lmlx4 .include <bsd.prog.mk> diff --git a/contrib/ofed/librdmacm/examples/build/udaddy/Makefile b/contrib/ofed/librdmacm/examples/build/udaddy/Makefile index 16d941974b65..1e325505bc86 100644 --- a/contrib/ofed/librdmacm/examples/build/udaddy/Makefile +++ b/contrib/ofed/librdmacm/examples/build/udaddy/Makefile @@ -6,5 +6,6 @@ PROG= udaddy MAN= SRCS= udaddy.c LDADD+= -libverbs -lrdmacm -lpthread +LDADD+= -lmlx4 .include <bsd.prog.mk> diff --git a/contrib/ofed/management/infiniband-diags/src/ibnetdiscover.c b/contrib/ofed/management/infiniband-diags/src/ibnetdiscover.c index 2cfaa8ae55ef..5e092f7b0877 100644 --- a/contrib/ofed/management/infiniband-diags/src/ibnetdiscover.c +++ b/contrib/ofed/management/infiniband-diags/src/ibnetdiscover.c @@ -50,7 +50,7 @@ #include <infiniband/common.h> #include <infiniband/umad.h> #include <infiniband/mad.h> -#include <infiniband/complib/cl_nodenamemap.h> +#include <complib/cl_nodenamemap.h> #include "ibnetdiscover.h" #include "grouping.h" diff --git a/contrib/ofed/management/infiniband-diags/src/ibroute.c b/contrib/ofed/management/infiniband-diags/src/ibroute.c index f2ee170cedc0..9607aa9999a5 100644 --- a/contrib/ofed/management/infiniband-diags/src/ibroute.c +++ b/contrib/ofed/management/infiniband-diags/src/ibroute.c @@ -49,7 +49,7 @@ #include <infiniband/common.h> #include <infiniband/umad.h> #include <infiniband/mad.h> -#include <infiniband/complib/cl_nodenamemap.h> +#include <complib/cl_nodenamemap.h> #include "ibdiag_common.h" diff --git a/contrib/ofed/management/infiniband-diags/src/ibsendtrap.c b/contrib/ofed/management/infiniband-diags/src/ibsendtrap.c index 66620de62e2b..2754dc008dea 100644 --- a/contrib/ofed/management/infiniband-diags/src/ibsendtrap.c +++ b/contrib/ofed/management/infiniband-diags/src/ibsendtrap.c @@ -43,7 +43,7 @@ #include <getopt.h> #include <infiniband/mad.h> -#include <infiniband/iba/ib_types.h> +#include <iba/ib_types.h> #include "ibdiag_common.h" diff --git a/contrib/ofed/management/infiniband-diags/src/ibtracert.c b/contrib/ofed/management/infiniband-diags/src/ibtracert.c index bde0ea795326..f8ecf76483cc 100644 --- a/contrib/ofed/management/infiniband-diags/src/ibtracert.c +++ b/contrib/ofed/management/infiniband-diags/src/ibtracert.c @@ -49,7 +49,7 @@ #include <infiniband/common.h> #include <infiniband/umad.h> #include <infiniband/mad.h> -#include <infiniband/complib/cl_nodenamemap.h> +#include <complib/cl_nodenamemap.h> #include "ibdiag_common.h" diff --git a/contrib/ofed/management/infiniband-diags/src/saquery.c b/contrib/ofed/management/infiniband-diags/src/saquery.c index 97663d1d538f..9f882e73a401 100644 --- a/contrib/ofed/management/infiniband-diags/src/saquery.c +++ b/contrib/ofed/management/infiniband-diags/src/saquery.c @@ -50,12 +50,12 @@ #include <getopt.h> #include <infiniband/mad.h> -#include <infiniband/opensm/osm_log.h> -#include <infiniband/vendor/osm_vendor_api.h> -#include <infiniband/vendor/osm_vendor_sa_api.h> -#include <infiniband/opensm/osm_mad_pool.h> -#include <infiniband/complib/cl_debug.h> -#include <infiniband/complib/cl_nodenamemap.h> +#include <opensm/osm_log.h> +#include <vendor/osm_vendor_api.h> +#include <vendor/osm_vendor_sa_api.h> +#include <opensm/osm_mad_pool.h> +#include <complib/cl_debug.h> +#include <complib/cl_nodenamemap.h> #include <netinet/in.h> diff --git a/contrib/ofed/management/infiniband-diags/src/smpquery.c b/contrib/ofed/management/infiniband-diags/src/smpquery.c index ed8ec83c9a06..01ccfaf16412 100644 --- a/contrib/ofed/management/infiniband-diags/src/smpquery.c +++ b/contrib/ofed/management/infiniband-diags/src/smpquery.c @@ -50,7 +50,7 @@ #include <infiniband/common.h> #include <infiniband/umad.h> #include <infiniband/mad.h> -#include <infiniband/complib/cl_nodenamemap.h> +#include <complib/cl_nodenamemap.h> #include "ibdiag_common.h" diff --git a/contrib/ofed/usr.bin/Makefile.inc b/contrib/ofed/usr.bin/Makefile.inc index e6a0550b82d3..d05778c68d37 100644 --- a/contrib/ofed/usr.bin/Makefile.inc +++ b/contrib/ofed/usr.bin/Makefile.inc @@ -1,4 +1,9 @@ DIAGPATH= ${.CURDIR}/../../management/infiniband-diags BINDIR?= /usr/bin CFLAGS+= -I${.CURDIR}/../../include/infiniband +CFLAGS+= -I${.CURDIR}/../../include CFLAGS+= -I${.CURDIR}/../../management/opensm/include/ +CFLAGS+= -I${.CURDIR}/../../management/opensm +CFLAGS+= -I${.CURDIR}/../../management/libibcommon/include +CFLAGS+= -I${.CURDIR}/../../management/libibumad/include +CFLAGS+= -I${.CURDIR}/../../management/libibmad/include diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 645a2542848b..4519e87f8458 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -390,12 +390,6 @@ gateway_enable="NO" # Set to YES if this host will be a gateway. routed_enable="NO" # Set to YES to enable a routing daemon. routed_program="/sbin/routed" # Name of routing daemon to use if enabled. routed_flags="-q" # Flags for routing daemon. -mrouted_enable="NO" # Do IPv4 multicast routing. -mrouted_program="/usr/local/sbin/mrouted" # Name of IPv4 multicast - # routing daemon. You need to - # install it from package or - # port. -mrouted_flags="" # Flags for multicast routing daemon. arpproxy_all="NO" # replaces obsolete kernel option ARP_PROXYALL. forward_sourceroute="NO" # do source routing (only if gateway_enable is set to "YES") accept_sourceroute="NO" # accept source routed packets to us diff --git a/etc/rc b/etc/rc index 21efc18c8a73..4efc293b6b2b 100644 --- a/etc/rc +++ b/etc/rc @@ -69,19 +69,16 @@ fi # and to make the configuration file variables available to rc itself. # . /etc/rc.subr -load_rc_config 'XXX' +load_rc_config # If we receive a SIGALRM, re-source /etc/rc.conf; this allows rc.d # scripts to perform "boot-time configuration" including enabling and # disabling rc.d scripts which appear later in the boot order. -trap "_rc_conf_loaded=false; load_rc_config 'XXX'" ALRM +trap "_rc_conf_loaded=false; load_rc_config" ALRM skip="-s nostart" if [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ]; then skip="$skip -s nojail" - if [ "$early_late_divider" = "FILESYSTEMS" ]; then - early_late_divider=NETWORKING - fi if [ `/sbin/sysctl -n security.jail.vnet` -ne 1 ]; then skip="$skip -s nojailvnet" fi diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index f26c190fe9dd..4994e9da8aa8 100644 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -90,7 +90,6 @@ FILES= DAEMON \ mountd \ moused \ mroute6d \ - mrouted \ msgs \ natd \ netif \ diff --git a/etc/rc.d/NETWORKING b/etc/rc.d/NETWORKING index 12dd3b0d71b5..750d78af67d9 100755 --- a/etc/rc.d/NETWORKING +++ b/etc/rc.d/NETWORKING @@ -5,7 +5,7 @@ # PROVIDE: NETWORKING NETWORK # REQUIRE: netif netoptions routing ppp ipfw stf -# REQUIRE: defaultroute routed mrouted route6d mroute6d resolv bridge +# REQUIRE: defaultroute routed route6d mroute6d resolv bridge # REQUIRE: static_arp static_ndp local_unbound # This is a dummy dependency, for services which require networking diff --git a/etc/rc.d/ipmon b/etc/rc.d/ipmon index cdd87426695c..8e42a186f438 100755 --- a/etc/rc.d/ipmon +++ b/etc/rc.d/ipmon @@ -4,7 +4,7 @@ # # PROVIDE: ipmon -# REQUIRE: FILESYSTEMS hostname sysctl FILESYSTEMS ipfilter +# REQUIRE: FILESYSTEMS hostname sysctl ipfilter # BEFORE: SERVERS # KEYWORD: nojail diff --git a/etc/rc.d/mrouted b/etc/rc.d/mrouted deleted file mode 100755 index d15299f35ce1..000000000000 --- a/etc/rc.d/mrouted +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -# -# $FreeBSD$ -# - -# PROVIDE: mrouted -# REQUIRE: netif routing FILESYSTEMS -# KEYWORD: nojail - -. /etc/rc.subr - -name="mrouted" -rcvar="mrouted_enable" -command="/usr/local/sbin/${name}" -pidfile="/var/run/${name}.pid" -required_files="/etc/${name}.conf" -extra_commands="reload" - -load_rc_config $name -run_rc_command "$1" diff --git a/etc/rc.d/pflog b/etc/rc.d/pflog index 7647ebf676e7..3deceabf2ef9 100755 --- a/etc/rc.d/pflog +++ b/etc/rc.d/pflog @@ -4,7 +4,7 @@ # # PROVIDE: pflog -# REQUIRE: FILESYSTEMS netif FILESYSTEMS +# REQUIRE: FILESYSTEMS netif # KEYWORD: nojail . /etc/rc.subr diff --git a/etc/rc.subr b/etc/rc.subr index 6534f6858f65..7b1e38737c10 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -1315,9 +1315,6 @@ load_rc_config() { local _name _rcvar_val _var _defval _v _msg _new _d _name=$1 - if [ -z "$_name" ]; then - err 3 'USAGE: load_rc_config name' - fi if ${_rc_conf_loaded:-false}; then : @@ -1333,20 +1330,24 @@ load_rc_config() _rc_conf_loaded=true fi - for _d in /etc ${local_startup%*/rc.d}; do - if [ -f ${_d}/rc.conf.d/"$_name" ]; then - debug "Sourcing ${_d}/rc.conf.d/$_name" - . ${_d}/rc.conf.d/"$_name" - elif [ -d ${_d}/rc.conf.d/"$_name" ] ; then - local _rc - for _rc in ${_d}/rc.conf.d/"$_name"/* ; do - if [ -f "$_rc" ] ; then - debug "Sourcing $_rc" - . "$_rc" - fi - done - fi - done + # If a service name was specified, attempt to load + # service-specific configuration + if [ -n "$_name" ] ; then + for _d in /etc ${local_startup%*/rc.d}; do + if [ -f ${_d}/rc.conf.d/"$_name" ]; then + debug "Sourcing ${_d}/rc.conf.d/$_name" + . ${_d}/rc.conf.d/"$_name" + elif [ -d ${_d}/rc.conf.d/"$_name" ] ; then + local _rc + for _rc in ${_d}/rc.conf.d/"$_name"/* ; do + if [ -f "$_rc" ] ; then + debug "Sourcing $_rc" + . "$_rc" + fi + done + fi + done + fi # Set defaults if defined. for _var in $rcvar $rcvars; do diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile index 885f8a9922bd..572c0613904c 100644 --- a/sbin/ifconfig/Makefile +++ b/sbin/ifconfig/Makefile @@ -30,7 +30,7 @@ SRCS+= ifmac.c # MAC support SRCS+= ifmedia.c # SIOC[GS]IFMEDIA support SRCS+= iffib.c # non-default FIB support SRCS+= ifvlan.c # SIOC[GS]ETVLAN support -SRCS+= ifvxlan.c # VXLAN support +#SRCS+= ifvxlan.c # VXLAN support SRCS+= ifgre.c # GRE keys etc SRCS+= ifgif.c # GIF reversed header workaround diff --git a/share/man/man4/tap.4 b/share/man/man4/tap.4 index d68dab30b037..229de6028eb3 100644 --- a/share/man/man4/tap.4 +++ b/share/man/man4/tap.4 @@ -1,7 +1,7 @@ .\" $FreeBSD$ .\" Based on PR#2411 .\" -.Dd November 4, 2014 +.Dd November 30, 2014 .Dt TAP 4 .Os .Sh NAME @@ -34,6 +34,17 @@ or a terminal for and a character-special device .Dq control interface. +A client program transfers Ethernet frames to or from the +.Nm +.Dq control +interface. +The +.Xr tun 4 +interface provides similar functionality at the network layer: +a client will transfer IP (by default) packets to or from a +.Xr tun 4 +.Dq control +interface. .Pp The network interfaces are named .Dq Li tap0 , @@ -314,4 +325,5 @@ VMware .El .Sh SEE ALSO .Xr inet 4 , -.Xr intro 4 +.Xr intro 4 , +.Xr tun 4 diff --git a/share/man/man4/tun.4 b/share/man/man4/tun.4 index b5139a7cdf0d..0b88b7213b07 100644 --- a/share/man/man4/tun.4 +++ b/share/man/man4/tun.4 @@ -2,7 +2,7 @@ .\" $FreeBSD$ .\" Based on PR#2411 .\" -.Dd February 4, 2007 +.Dd November 30, 2014 .Dt TUN 4 .Os .Sh NAME @@ -35,6 +35,17 @@ or a terminal for and a character-special device .Dq control interface. +A client program transfers IP (by default) packets to or from the +.Nm +.Dq control +interface. +The +.Xr tap 4 +interface provides similar functionality at the Ethernet layer: +a client will transfer Ethernet frames to or from a +.Xr tap 4 +.Dq control +interface. .Pp The network interfaces are named .Dq Li tun0 , @@ -307,6 +318,7 @@ them pile up. .Xr inet 4 , .Xr intro 4 , .Xr pty 4 , +.Xr tap 4 , .Xr ifconfig 8 .Sh AUTHORS This manual page was originally obtained from diff --git a/sys/arm/arm/cpufunc_asm_armv5.S b/sys/arm/arm/cpufunc_asm_armv5.S index 7435b462e51b..582ea504c14f 100644 --- a/sys/arm/arm/cpufunc_asm_armv5.S +++ b/sys/arm/arm/cpufunc_asm_armv5.S @@ -194,7 +194,6 @@ ENTRY(armv5_idcache_wbinv_range) END(armv5_idcache_wbinv_range) ENTRY_NP(armv5_idcache_wbinv_all) -armv5_idcache_wbinv_all: .Larmv5_idcache_wbinv_all: /* * We assume that the code here can never be out of sync with the diff --git a/sys/arm/arm/cpufunc_asm_xscale_c3.S b/sys/arm/arm/cpufunc_asm_xscale_c3.S index 6766a327156a..78fa2d578dcf 100644 --- a/sys/arm/arm/cpufunc_asm_xscale_c3.S +++ b/sys/arm/arm/cpufunc_asm_xscale_c3.S @@ -144,7 +144,6 @@ __FBSDID("$FreeBSD$"); ENTRY_NP(xscalec3_cache_syncI) -xscalec3_cache_purgeID: EENTRY_NP(xscalec3_cache_purgeID) mcr p15, 0, r0, c7, c5, 0 /* flush I cache (D cleaned below) */ EENTRY_NP(xscalec3_cache_cleanID) diff --git a/sys/arm/arm/fusu.S b/sys/arm/arm/fusu.S index c70215c297db..b55f443c2f9f 100644 --- a/sys/arm/arm/fusu.S +++ b/sys/arm/arm/fusu.S @@ -129,7 +129,7 @@ EENTRY_NP(fuword32) str r1, [r2, #PCB_ONFAULT] mov r0, r3 RET -END(fuword32) +EEND(fuword32) END(fuword) /* @@ -295,7 +295,7 @@ EENTRY_NP(suword32) mov r0, #0x00000000 str r0, [r2, #PCB_ONFAULT] RET -END(suword32) +EEND(suword32) END(suword) /* diff --git a/sys/arm/arm/support.S b/sys/arm/arm/support.S index 2a6eec9828e0..1714b0f0d203 100644 --- a/sys/arm/arm/support.S +++ b/sys/arm/arm/support.S @@ -130,7 +130,7 @@ ENTRY(bzero) .Lnormal0: mov r3, #0x00 b do_memset -EEND(bzero) +END(bzero) /* LINTSTUB: Func: void *memset(void *, int, size_t) */ ENTRY(memset) and r3, r1, #0xff /* We deal with bytes */ diff --git a/sys/arm/include/asm.h b/sys/arm/include/asm.h index 9577001917b2..bd4b6361f3cd 100644 --- a/sys/arm/include/asm.h +++ b/sys/arm/include/asm.h @@ -57,19 +57,6 @@ #define _FNEND #endif -/* - * gas/arm uses @ as a single comment character and thus cannot be used here - * Instead it recognised the # instead of an @ symbols in .type directives - * We define a couple of macros so that assembly code will not be dependent - * on one or the other. - */ -#define _ASM_TYPE_FUNCTION #function -#define _ASM_TYPE_OBJECT #object -#define GLOBAL(X) .globl x -#define _ENTRY(x) \ - .text; _ALIGN_TEXT; .globl x; .type x,_ASM_TYPE_FUNCTION; x: _FNSTART -#define _END(x) .size x, . - x; _FNEND - /* * EENTRY()/EEND() mark "extra" entry/exit points from a function. * The unwind info cannot handle the concept of a nested function, or a function @@ -79,8 +66,21 @@ * basically just a label that you can jump to. The EEND() macro does nothing * at all, except document the exit point associated with the same-named entry. */ -#define _EENTRY(x) .globl x; .type x,_ASM_TYPE_FUNCTION; x: -#define _EEND(x) /* nothing */ +#define _EENTRY(x) .globl x; .type x,_ASM_TYPE_FUNCTION; x: +#define _EEND(x) /* nothing */ + +/* + * gas/arm uses @ as a single comment character and thus cannot be used here + * Instead it recognised the # instead of an @ symbols in .type directives + * We define a couple of macros so that assembly code will not be dependent + * on one or the other. + */ +#define _ASM_TYPE_FUNCTION #function +#define _ASM_TYPE_OBJECT #object +#define GLOBAL(X) .globl x +#define _ENTRY(x) \ + .text; _ALIGN_TEXT; _EENTRY(x) _FNSTART +#define _END(x) .size x, . - x; _FNEND #ifdef GPROF # define _PROF_PROLOGUE \ diff --git a/sys/boot/i386/boot2/boot2.c b/sys/boot/i386/boot2/boot2.c index 001126fb83f8..75abc7e895e7 100644 --- a/sys/boot/i386/boot2/boot2.c +++ b/sys/boot/i386/boot2/boot2.c @@ -418,7 +418,7 @@ parse() #if SERIAL } else if (c == 'S') { j = 0; - while ((i = *arg++ - '0') <= 9) + while ((unsigned int)(i = *arg++ - '0') <= 9) j = j * 10 + i; if (j > 0 && i == -'0') { comspeed = j; diff --git a/sys/dev/bxe/bxe.c b/sys/dev/bxe/bxe.c index a27b3e7a56bd..3509f2d023df 100644 --- a/sys/dev/bxe/bxe.c +++ b/sys/dev/bxe/bxe.c @@ -3219,7 +3219,7 @@ bxe_tpa_stop(struct bxe_softc *sc, #if __FreeBSD_version >= 800000 /* specify what RSS queue was used for this flow */ m->m_pkthdr.flowid = fp->index; - m->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); #endif if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); @@ -3454,7 +3454,7 @@ bxe_rxeof(struct bxe_softc *sc, #if __FreeBSD_version >= 800000 /* specify what RSS queue was used for this flow */ m->m_pkthdr.flowid = fp->index; - m->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); #endif next_rx: @@ -6037,10 +6037,9 @@ bxe_tx_mq_start(struct ifnet *ifp, fp_index = 0; /* default is the first queue */ - /* change the queue if using flow ID */ - if ((m->m_flags & M_FLOWID) != 0) { + /* check if flowid is set */ + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) fp_index = (m->m_pkthdr.flowid % sc->num_queues); - } fp = &sc->fp[fp_index]; diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c index a7f39a510109..2b08183b0cd5 100644 --- a/sys/dev/cxgb/cxgb_sge.c +++ b/sys/dev/cxgb/cxgb_sge.c @@ -1733,8 +1733,9 @@ cxgb_transmit(struct ifnet *ifp, struct mbuf *m) m_freem(m); return (0); } - - if (m->m_flags & M_FLOWID) + + /* check if flowid is set */ + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) qidx = (m->m_pkthdr.flowid % pi->nqsets) + pi->first_qset; qs = &pi->adapter->sge.qs[qidx]; @@ -2899,9 +2900,10 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget) eop = get_packet(adap, drop_thresh, qs, mh, r); if (eop) { - if (r->rss_hdr.hash_type && !adap->timestamp) - mh->mh_head->m_flags |= M_FLOWID; - mh->mh_head->m_pkthdr.flowid = rss_hash; + if (r->rss_hdr.hash_type && !adap->timestamp) { + M_HASHTYPE_SET(mh->mh_head, M_HASHTYPE_OPAQUE); + mh->mh_head->m_pkthdr.flowid = rss_hash; + } } ethpad = 2; diff --git a/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c b/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c index 81a446a64a4f..a4b67088db93 100644 --- a/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c +++ b/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c @@ -1199,7 +1199,7 @@ do_rx_data(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) } toep->tp_enqueued += m->m_pkthdr.len; - sbappendstream_locked(so_rcv, m); + sbappendstream_locked(so_rcv, m, 0); sorwakeup_locked(so); SOCKBUF_UNLOCK_ASSERT(so_rcv); diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index f9caf2eec1d8..2c384fd0f1a6 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -1440,7 +1440,8 @@ cxgbe_transmit(struct ifnet *ifp, struct mbuf *m) return (ENETDOWN); } - if (m->m_flags & M_FLOWID) + /* check if flowid is set */ + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) txq += ((m->m_pkthdr.flowid % (pi->ntxq - pi->rsrv_noflowq)) + pi->rsrv_noflowq); br = txq->br; diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c index 499f25205998..58940fe4959c 100644 --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -1734,7 +1734,7 @@ t4_eth_rx(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m0) m0->m_data += fl_pktshift; m0->m_pkthdr.rcvif = ifp; - m0->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m0, M_HASHTYPE_OPAQUE); m0->m_pkthdr.flowid = be32toh(rss->hash_val); if (cpl->csum_calc && !cpl->err_vec) { diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c index 29e5fa243be5..5dc843428448 100644 --- a/sys/dev/cxgbe/tom/t4_cpl_io.c +++ b/sys/dev/cxgbe/tom/t4_cpl_io.c @@ -1086,7 +1086,7 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) #ifdef USE_DDP_RX_FLOW_CONTROL toep->rx_credits -= m->m_len; /* adjust for F_RX_FC_DDP */ #endif - sbappendstream_locked(sb, m); + sbappendstream_locked(sb, m, 0); toep->sb_cc = sbused(sb); } socantrcvmore_locked(so); /* unlocks the sockbuf */ @@ -1586,7 +1586,7 @@ do_rx_data(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) ("%s: sb %p has more data (%d) than last time (%d).", __func__, sb, sbused(sb), toep->sb_cc)); toep->rx_credits += toep->sb_cc - sbused(sb); - sbappendstream_locked(sb, m); + sbappendstream_locked(sb, m, 0); toep->sb_cc = sbused(sb); sorwakeup_locked(so); SOCKBUF_UNLOCK_ASSERT(sb); diff --git a/sys/dev/cxgbe/tom/t4_ddp.c b/sys/dev/cxgbe/tom/t4_ddp.c index 89585cf83039..17eb071b3cb7 100644 --- a/sys/dev/cxgbe/tom/t4_ddp.c +++ b/sys/dev/cxgbe/tom/t4_ddp.c @@ -231,7 +231,7 @@ insert_ddp_data(struct toepcb *toep, uint32_t n) #ifdef USE_DDP_RX_FLOW_CONTROL toep->rx_credits -= n; /* adjust for F_RX_FC_DDP */ #endif - sbappendstream_locked(sb, m); + sbappendstream_locked(sb, m, 0); toep->sb_cc = sbused(sb); } @@ -466,7 +466,7 @@ handle_ddp_data(struct toepcb *toep, __be32 ddp_report, __be32 rcv_nxt, int len) #ifdef USE_DDP_RX_FLOW_CONTROL toep->rx_credits -= len; /* adjust for F_RX_FC_DDP */ #endif - sbappendstream_locked(sb, m); + sbappendstream_locked(sb, m, 0); toep->sb_cc = sbused(sb); wakeup: KASSERT(toep->ddp_flags & db_flag, @@ -971,8 +971,9 @@ handle_ddp(struct socket *so, struct uio *uio, int flags, int error) */ rc = sbwait(sb); while (toep->ddp_flags & buf_flag) { + /* XXXGL: shouldn't here be sbwait() call? */ sb->sb_flags |= SB_WAIT; - msleep(&sb->sb_cc, &sb->sb_mtx, PSOCK , "sbwait", 0); + msleep(&sb->sb_acc, &sb->sb_mtx, PSOCK , "sbwait", 0); } unwire_ddp_buffer(db); return (rc); diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c index 335aa01d95c9..75f0fb419d50 100644 --- a/sys/dev/e1000/if_igb.c +++ b/sys/dev/e1000/if_igb.c @@ -990,7 +990,7 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m) * If everything is setup correctly, it should be the * same bucket that the current CPU we're on is. */ - if ((m->m_flags & M_FLOWID) != 0) { + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) { #ifdef RSS if (rss_hash2bucket(m->m_pkthdr.flowid, M_HASHTYPE_GET(m), &bucket_id) == 0) { @@ -5166,7 +5166,6 @@ igb_rxeof(struct igb_queue *que, int count, int *done) /* XXX set flowtype once this works right */ rxr->fmp->m_pkthdr.flowid = le32toh(cur->wb.lower.hi_dword.rss); - rxr->fmp->m_flags |= M_FLOWID; switch (pkt_info & E1000_RXDADV_RSSTYPE_MASK) { case E1000_RXDADV_RSSTYPE_IPV4_TCP: M_HASHTYPE_SET(rxr->fmp, M_HASHTYPE_RSS_TCP_IPV4); @@ -5196,11 +5195,11 @@ igb_rxeof(struct igb_queue *que, int count, int *done) default: /* XXX fallthrough */ - M_HASHTYPE_SET(rxr->fmp, M_HASHTYPE_NONE); + M_HASHTYPE_SET(rxr->fmp, M_HASHTYPE_OPAQUE); } #elif !defined(IGB_LEGACY_TX) rxr->fmp->m_pkthdr.flowid = que->msix; - rxr->fmp->m_flags |= M_FLOWID; + M_HASHTYPE_SET(rxr->fmp, M_HASHTYPE_OPAQUE); #endif sendmp = rxr->fmp; /* Make sure to set M_PKTHDR. */ diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index 9ac70eeac5e4..2fd126c5396e 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -833,7 +833,7 @@ ixgbe_mq_start(struct ifnet *ifp, struct mbuf *m) * If everything is setup correctly, it should be the * same bucket that the current CPU we're on is. */ - if ((m->m_flags & M_FLOWID) != 0) { + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) { #ifdef RSS if (rss_hash2bucket(m->m_pkthdr.flowid, M_HASHTYPE_GET(m), &bucket_id) == 0) { @@ -4764,7 +4764,6 @@ ixgbe_rxeof(struct ix_queue *que) #ifdef RSS sendmp->m_pkthdr.flowid = le32toh(cur->wb.lower.hi_dword.rss); - sendmp->m_flags |= M_FLOWID; switch (pkt_info & IXGBE_RXDADV_RSSTYPE_MASK) { case IXGBE_RXDADV_RSSTYPE_IPV4_TCP: M_HASHTYPE_SET(sendmp, M_HASHTYPE_RSS_TCP_IPV4); @@ -4795,11 +4794,12 @@ ixgbe_rxeof(struct ix_queue *que) break; default: /* XXX fallthrough */ - M_HASHTYPE_SET(sendmp, M_HASHTYPE_NONE); + M_HASHTYPE_SET(sendmp, M_HASHTYPE_OPAQUE); + break; } #else /* RSS */ sendmp->m_pkthdr.flowid = que->msix; - sendmp->m_flags |= M_FLOWID; + M_HASHTYPE_SET(sendmp, M_HASHTYPE_OPAQUE); #endif /* RSS */ #endif /* FreeBSD_version */ } diff --git a/sys/dev/ixgbe/ixv.c b/sys/dev/ixgbe/ixv.c index 1d77e8b5a27a..edbdfca85920 100644 --- a/sys/dev/ixgbe/ixv.c +++ b/sys/dev/ixgbe/ixv.c @@ -580,7 +580,7 @@ ixv_mq_start(struct ifnet *ifp, struct mbuf *m) int i = 0, err = 0; /* Which queue to use */ - if ((m->m_flags & M_FLOWID) != 0) + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) i = m->m_pkthdr.flowid % adapter->num_queues; txr = &adapter->tx_rings[i]; @@ -3464,7 +3464,7 @@ ixv_rxeof(struct ix_queue *que, int count) ixv_rx_checksum(staterr, sendmp, ptype); #if __FreeBSD_version >= 800000 sendmp->m_pkthdr.flowid = que->msix; - sendmp->m_flags |= M_FLOWID; + M_HASHTYPE_SET(sendmp, M_HASHTYPE_OPAQUE); #endif } next_desc: diff --git a/sys/dev/ixl/ixl_txrx.c b/sys/dev/ixl/ixl_txrx.c index 6322f2c9fd0e..f36b8318961d 100755 --- a/sys/dev/ixl/ixl_txrx.c +++ b/sys/dev/ixl/ixl_txrx.c @@ -66,8 +66,8 @@ ixl_mq_start(struct ifnet *ifp, struct mbuf *m) struct tx_ring *txr; int err, i; - /* Which queue to use */ - if ((m->m_flags & M_FLOWID) != 0) + /* check if flowid is set */ + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) i = m->m_pkthdr.flowid % vsi->num_queues; else i = curcpu % vsi->num_queues; @@ -1543,7 +1543,7 @@ ixl_rxeof(struct ixl_queue *que, int count) if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) ixl_rx_checksum(sendmp, status, error, ptype); sendmp->m_pkthdr.flowid = que->msix; - sendmp->m_flags |= M_FLOWID; + M_HASHTYPE_SET(sendmp, M_HASHTYPE_OPAQUE); } next_desc: bus_dmamap_sync(rxr->dma.tag, rxr->dma.map, diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c index e97ae5c7130e..fe8c08a72495 100644 --- a/sys/dev/mxge/if_mxge.c +++ b/sys/dev/mxge/if_mxge.c @@ -2719,7 +2719,7 @@ mxge_rx_done_big(struct mxge_slice_state *ss, uint32_t len, /* flowid only valid if RSS hashing is enabled */ if (sc->num_slices > 1) { m->m_pkthdr.flowid = (ss - sc->ss); - m->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); } /* pass the frame up the stack */ (*ifp->if_input)(ifp, m); @@ -2787,7 +2787,7 @@ mxge_rx_done_small(struct mxge_slice_state *ss, uint32_t len, /* flowid only valid if RSS hashing is enabled */ if (sc->num_slices > 1) { m->m_pkthdr.flowid = (ss - sc->ss); - m->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); } /* pass the frame up the stack */ (*ifp->if_input)(ifp, m); diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c index 322670814553..dd968ca51577 100644 --- a/sys/dev/netmap/netmap_freebsd.c +++ b/sys/dev/netmap/netmap_freebsd.c @@ -204,7 +204,7 @@ netmap_catch_tx(struct netmap_generic_adapter *gna, int enable) * of the transmission does not consume resources. * * On FreeBSD, and on multiqueue cards, we can force the queue using - * if ((m->m_flags & M_FLOWID) != 0) + * if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) * i = m->m_pkthdr.flowid % adapter->num_queues; * else * i = curcpu % adapter->num_queues; @@ -240,7 +240,7 @@ generic_xmit_frame(struct ifnet *ifp, struct mbuf *m, m->m_len = m->m_pkthdr.len = len; // inc refcount. All ours, we could skip the atomic atomic_fetchadd_int(PNT_MBUF_REFCNT(m), 1); - m->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); m->m_pkthdr.flowid = ring_nr; m->m_pkthdr.rcvif = ifp; /* used for tx notification */ ret = NA(ifp)->if_transmit(ifp, m); diff --git a/sys/dev/oce/oce_if.c b/sys/dev/oce/oce_if.c index fe48007e8973..062181b2367b 100644 --- a/sys/dev/oce/oce_if.c +++ b/sys/dev/oce/oce_if.c @@ -563,7 +563,7 @@ oce_multiq_start(struct ifnet *ifp, struct mbuf *m) int queue_index = 0; int status = 0; - if ((m->m_flags & M_FLOWID) != 0) + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) queue_index = m->m_pkthdr.flowid % sc->nwqs; wq = sc->wq[queue_index]; @@ -1374,7 +1374,7 @@ oce_rx(struct oce_rq *rq, uint32_t rqe_idx, struct oce_nic_rx_cqe *cqe) m->m_pkthdr.flowid = (rq->queue_index - 1); else m->m_pkthdr.flowid = rq->queue_index; - m->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); #endif /* This deternies if vlan tag is Valid */ if (oce_cqe_vtp_valid(sc, cqe)) { diff --git a/sys/dev/qlxgbe/ql_isr.c b/sys/dev/qlxgbe/ql_isr.c index db0029822927..dee8e198e8f4 100644 --- a/sys/dev/qlxgbe/ql_isr.c +++ b/sys/dev/qlxgbe/ql_isr.c @@ -159,7 +159,7 @@ qla_rx_intr(qla_host_t *ha, qla_sgl_rcv_t *sgc, uint32_t sds_idx) if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); mpf->m_pkthdr.flowid = sgc->rss_hash; - mpf->m_flags |= M_FLOWID; + M_HASHTYPE_SET(mpf, M_HASHTYPE_OPAQUE); (*ifp->if_input)(ifp, mpf); @@ -324,7 +324,7 @@ qla_lro_intr(qla_host_t *ha, qla_sgl_lro_t *sgc, uint32_t sds_idx) mpf->m_pkthdr.csum_data = 0xFFFF; mpf->m_pkthdr.flowid = sgc->rss_hash; - mpf->m_flags |= M_FLOWID; + M_HASHTYPE_SET(mpf, M_HASHTYPE_OPAQUE); if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); diff --git a/sys/dev/qlxgbe/ql_os.c b/sys/dev/qlxgbe/ql_os.c index 1684c070fcd8..04fbf7195529 100644 --- a/sys/dev/qlxgbe/ql_os.c +++ b/sys/dev/qlxgbe/ql_os.c @@ -1140,7 +1140,8 @@ qla_send(qla_host_t *ha, struct mbuf **m_headp) QL_DPRINT8(ha, (ha->pci_dev, "%s: enter\n", __func__)); - if (m_head->m_flags & M_FLOWID) + /* check if flowid is set */ + if (M_HASHTYPE_GET(m_head) != M_HASHTYPE_NONE) txr_idx = m_head->m_pkthdr.flowid & (ha->hw.num_tx_rings - 1); tx_idx = ha->hw.tx_cntxt[txr_idx].txr_next; diff --git a/sys/dev/qlxge/qls_isr.c b/sys/dev/qlxge/qls_isr.c index 14b4839be913..03b3a3c52152 100644 --- a/sys/dev/qlxge/qls_isr.c +++ b/sys/dev/qlxge/qls_isr.c @@ -190,7 +190,7 @@ qls_rx_comp(qla_host_t *ha, uint32_t rxr_idx, uint32_t cq_idx, q81_rx_t *cq_e) if ((cq_e->flags1 & Q81_RX_FLAGS1_RSS_MATCH_MASK)) { rxr->rss_int++; mp->m_pkthdr.flowid = cq_e->rss; - mp->m_flags |= M_FLOWID; + M_HASHTYPE_SET(mp, M_HASHTYPE_OPAQUE); } if (cq_e->flags0 & (Q81_RX_FLAGS0_TE | Q81_RX_FLAGS0_NU | Q81_RX_FLAGS0_IE)) { diff --git a/sys/dev/qlxge/qls_os.c b/sys/dev/qlxge/qls_os.c index 4f4097935f0c..1617d24095e1 100644 --- a/sys/dev/qlxge/qls_os.c +++ b/sys/dev/qlxge/qls_os.c @@ -1136,7 +1136,8 @@ qls_send(qla_host_t *ha, struct mbuf **m_headp) QL_DPRINT8((ha->pci_dev, "%s: enter\n", __func__)); - if (m_head->m_flags & M_FLOWID) + /* check if flowid is set */ + if (M_HASHTYPE_GET(m_head) != M_HASHTYPE_NONE) txr_idx = m_head->m_pkthdr.flowid & (ha->num_tx_rings - 1); tx_idx = ha->tx_ring[txr_idx].txr_next; diff --git a/sys/dev/sfxge/sfxge_rx.c b/sys/dev/sfxge/sfxge_rx.c index 66083d832857..ccfdfb023d07 100644 --- a/sys/dev/sfxge/sfxge_rx.c +++ b/sys/dev/sfxge/sfxge_rx.c @@ -302,7 +302,7 @@ sfxge_rx_deliver(struct sfxge_softc *sc, struct sfxge_rx_sw_desc *rx_desc) if (rx_desc->flags & EFX_PKT_TCP) { m->m_pkthdr.flowid = EFX_RX_HASH_VALUE(EFX_RX_HASHALG_TOEPLITZ, mtod(m, uint8_t *)); - m->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); } #endif m->m_data += sc->rx_prefix_size; @@ -353,7 +353,7 @@ sfxge_lro_deliver(struct sfxge_lro_state *st, struct sfxge_lro_conn *c) #ifdef SFXGE_HAVE_MQ m->m_pkthdr.flowid = c->conn_hash; - m->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); #endif m->m_pkthdr.csum_flags = csum_flags; __sfxge_rx_deliver(sc, m); diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c index a12c74756ea5..3fb76d92b6db 100644 --- a/sys/dev/sfxge/sfxge_tx.c +++ b/sys/dev/sfxge/sfxge_tx.c @@ -631,7 +631,8 @@ sfxge_if_transmit(struct ifnet *ifp, struct mbuf *m) if (m->m_pkthdr.csum_flags & (CSUM_DELAY_DATA | CSUM_TSO)) { int index = 0; - if (m->m_flags & M_FLOWID) { + /* check if flowid is set */ + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) { uint32_t hash = m->m_pkthdr.flowid; index = sc->rx_indir_table[hash % SFXGE_RX_SCALE_MAX]; diff --git a/sys/dev/virtio/block/virtio_blk.c b/sys/dev/virtio/block/virtio_blk.c index b15cb75a3f40..a65e23d37b4c 100644 --- a/sys/dev/virtio/block/virtio_blk.c +++ b/sys/dev/virtio/block/virtio_blk.c @@ -58,7 +58,6 @@ struct vtblk_request { struct virtio_blk_outhdr vbr_hdr; struct bio *vbr_bp; uint8_t vbr_ack; - TAILQ_ENTRY(vtblk_request) vbr_link; }; @@ -132,53 +131,60 @@ static int vtblk_dump(void *, void *, vm_offset_t, off_t, size_t); static void vtblk_strategy(struct bio *); static void vtblk_negotiate_features(struct vtblk_softc *); +static void vtblk_setup_features(struct vtblk_softc *); static int vtblk_maximum_segments(struct vtblk_softc *, struct virtio_blk_config *); static int vtblk_alloc_virtqueue(struct vtblk_softc *); static void vtblk_resize_disk(struct vtblk_softc *, uint64_t); -static void vtblk_set_write_cache(struct vtblk_softc *, int); -static int vtblk_write_cache_enabled(struct vtblk_softc *sc, - struct virtio_blk_config *); -static int vtblk_write_cache_sysctl(SYSCTL_HANDLER_ARGS); static void vtblk_alloc_disk(struct vtblk_softc *, struct virtio_blk_config *); static void vtblk_create_disk(struct vtblk_softc *); -static int vtblk_quiesce(struct vtblk_softc *); -static void vtblk_startio(struct vtblk_softc *); -static struct vtblk_request * vtblk_bio_request(struct vtblk_softc *); -static int vtblk_execute_request(struct vtblk_softc *, +static int vtblk_request_prealloc(struct vtblk_softc *); +static void vtblk_request_free(struct vtblk_softc *); +static struct vtblk_request * + vtblk_request_dequeue(struct vtblk_softc *); +static void vtblk_request_enqueue(struct vtblk_softc *, struct vtblk_request *); - -static void vtblk_vq_intr(void *); - -static void vtblk_stop(struct vtblk_softc *); - -static void vtblk_read_config(struct vtblk_softc *, - struct virtio_blk_config *); -static void vtblk_get_ident(struct vtblk_softc *); -static void vtblk_prepare_dump(struct vtblk_softc *); -static int vtblk_write_dump(struct vtblk_softc *, void *, off_t, size_t); -static int vtblk_flush_dump(struct vtblk_softc *); -static int vtblk_poll_request(struct vtblk_softc *, +static struct vtblk_request * + vtblk_request_next_ready(struct vtblk_softc *); +static void vtblk_request_requeue_ready(struct vtblk_softc *, struct vtblk_request *); +static struct vtblk_request * + vtblk_request_next(struct vtblk_softc *); +static struct vtblk_request * + vtblk_request_bio(struct vtblk_softc *); +static int vtblk_request_execute(struct vtblk_softc *, + struct vtblk_request *); +static int vtblk_request_error(struct vtblk_request *); -static void vtblk_finish_completed(struct vtblk_softc *); +static void vtblk_queue_completed(struct vtblk_softc *, + struct bio_queue *); +static void vtblk_done_completed(struct vtblk_softc *, + struct bio_queue *); static void vtblk_drain_vq(struct vtblk_softc *, int); static void vtblk_drain(struct vtblk_softc *); -static int vtblk_alloc_requests(struct vtblk_softc *); -static void vtblk_free_requests(struct vtblk_softc *); -static struct vtblk_request * vtblk_dequeue_request(struct vtblk_softc *); -static void vtblk_enqueue_request(struct vtblk_softc *, - struct vtblk_request *); +static void vtblk_startio(struct vtblk_softc *); +static void vtblk_bio_done(struct vtblk_softc *, struct bio *, int); -static struct vtblk_request * vtblk_dequeue_ready(struct vtblk_softc *); -static void vtblk_enqueue_ready(struct vtblk_softc *, +static void vtblk_read_config(struct vtblk_softc *, + struct virtio_blk_config *); +static void vtblk_ident(struct vtblk_softc *); +static int vtblk_poll_request(struct vtblk_softc *, struct vtblk_request *); +static int vtblk_quiesce(struct vtblk_softc *); +static void vtblk_vq_intr(void *); +static void vtblk_stop(struct vtblk_softc *); -static int vtblk_request_error(struct vtblk_request *); -static void vtblk_finish_bio(struct bio *, int); +static void vtblk_dump_prepare(struct vtblk_softc *); +static int vtblk_dump_write(struct vtblk_softc *, void *, off_t, size_t); +static int vtblk_dump_flush(struct vtblk_softc *); + +static void vtblk_set_write_cache(struct vtblk_softc *, int); +static int vtblk_write_cache_enabled(struct vtblk_softc *sc, + struct virtio_blk_config *); +static int vtblk_write_cache_sysctl(SYSCTL_HANDLER_ARGS); static void vtblk_setup_sysctl(struct vtblk_softc *); static int vtblk_tunable_int(struct vtblk_softc *, const char *, int); @@ -290,30 +296,18 @@ vtblk_attach(device_t dev) struct virtio_blk_config blkcfg; int error; + virtio_set_feature_desc(dev, vtblk_feature_desc); + sc = device_get_softc(dev); sc->vtblk_dev = dev; - VTBLK_LOCK_INIT(sc, device_get_nameunit(dev)); - bioq_init(&sc->vtblk_bioq); TAILQ_INIT(&sc->vtblk_req_free); TAILQ_INIT(&sc->vtblk_req_ready); - virtio_set_feature_desc(dev, vtblk_feature_desc); - vtblk_negotiate_features(sc); - - if (virtio_with_feature(dev, VIRTIO_RING_F_INDIRECT_DESC)) - sc->vtblk_flags |= VTBLK_FLAG_INDIRECT; - if (virtio_with_feature(dev, VIRTIO_BLK_F_RO)) - sc->vtblk_flags |= VTBLK_FLAG_READONLY; - if (virtio_with_feature(dev, VIRTIO_BLK_F_BARRIER)) - sc->vtblk_flags |= VTBLK_FLAG_BARRIER; - if (virtio_with_feature(dev, VIRTIO_BLK_F_CONFIG_WCE)) - sc->vtblk_flags |= VTBLK_FLAG_WC_CONFIG; - vtblk_setup_sysctl(sc); + vtblk_setup_features(sc); - /* Get local copy of config. */ vtblk_read_config(sc, &blkcfg); /* @@ -352,7 +346,7 @@ vtblk_attach(device_t dev) goto fail; } - error = vtblk_alloc_requests(sc); + error = vtblk_request_prealloc(sc); if (error) { device_printf(dev, "cannot preallocate requests\n"); goto fail; @@ -519,14 +513,14 @@ vtblk_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset, VTBLK_LOCK(sc); if ((sc->vtblk_flags & VTBLK_FLAG_DUMPING) == 0) { - vtblk_prepare_dump(sc); + vtblk_dump_prepare(sc); sc->vtblk_flags |= VTBLK_FLAG_DUMPING; } if (length > 0) - error = vtblk_write_dump(sc, virtual, offset, length); + error = vtblk_dump_write(sc, virtual, offset, length); else if (virtual == NULL && offset == 0) - error = vtblk_flush_dump(sc); + error = vtblk_dump_flush(sc); else { error = EINVAL; sc->vtblk_flags &= ~VTBLK_FLAG_DUMPING; @@ -543,7 +537,7 @@ vtblk_strategy(struct bio *bp) struct vtblk_softc *sc; if ((sc = bp->bio_disk->d_drv1) == NULL) { - vtblk_finish_bio(bp, EINVAL); + vtblk_bio_done(NULL, bp, EINVAL); return; } @@ -553,37 +547,21 @@ vtblk_strategy(struct bio *bp) */ if (sc->vtblk_flags & VTBLK_FLAG_READONLY && (bp->bio_cmd == BIO_WRITE || bp->bio_cmd == BIO_FLUSH)) { - vtblk_finish_bio(bp, EROFS); + vtblk_bio_done(sc, bp, EROFS); return; } -#ifdef INVARIANTS - /* - * Prevent read/write buffers spanning too many segments from - * getting into the queue. This should only trip if d_maxsize - * was incorrectly set. - */ - if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) { - int nsegs, max_nsegs; - - nsegs = sglist_count(bp->bio_data, bp->bio_bcount); - max_nsegs = sc->vtblk_max_nsegs - VTBLK_MIN_SEGMENTS; - - KASSERT(nsegs <= max_nsegs, - ("%s: bio %p spanned too many segments: %d, max: %d", - __func__, bp, nsegs, max_nsegs)); - } -#endif - VTBLK_LOCK(sc); - if (sc->vtblk_flags & VTBLK_FLAG_DETACH) - vtblk_finish_bio(bp, ENXIO); - else { - bioq_insert_tail(&sc->vtblk_bioq, bp); - if ((sc->vtblk_flags & VTBLK_FLAG_SUSPEND) == 0) - vtblk_startio(sc); + if (sc->vtblk_flags & VTBLK_FLAG_DETACH) { + VTBLK_UNLOCK(sc); + vtblk_bio_done(sc, bp, ENXIO); + return; } + + bioq_insert_tail(&sc->vtblk_bioq, bp); + vtblk_startio(sc); + VTBLK_UNLOCK(sc); } @@ -599,6 +577,25 @@ vtblk_negotiate_features(struct vtblk_softc *sc) sc->vtblk_features = virtio_negotiate_features(dev, features); } +static void +vtblk_setup_features(struct vtblk_softc *sc) +{ + device_t dev; + + dev = sc->vtblk_dev; + + vtblk_negotiate_features(sc); + + if (virtio_with_feature(dev, VIRTIO_RING_F_INDIRECT_DESC)) + sc->vtblk_flags |= VTBLK_FLAG_INDIRECT; + if (virtio_with_feature(dev, VIRTIO_BLK_F_RO)) + sc->vtblk_flags |= VTBLK_FLAG_READONLY; + if (virtio_with_feature(dev, VIRTIO_BLK_F_BARRIER)) + sc->vtblk_flags |= VTBLK_FLAG_BARRIER; + if (virtio_with_feature(dev, VIRTIO_BLK_F_CONFIG_WCE)) + sc->vtblk_flags |= VTBLK_FLAG_WC_CONFIG; +} + static int vtblk_maximum_segments(struct vtblk_softc *sc, struct virtio_blk_config *blkcfg) @@ -659,59 +656,6 @@ vtblk_resize_disk(struct vtblk_softc *sc, uint64_t new_capacity) } } -static void -vtblk_set_write_cache(struct vtblk_softc *sc, int wc) -{ - - /* Set either writeback (1) or writethrough (0) mode. */ - virtio_write_dev_config_1(sc->vtblk_dev, - offsetof(struct virtio_blk_config, writeback), wc); -} - -static int -vtblk_write_cache_enabled(struct vtblk_softc *sc, - struct virtio_blk_config *blkcfg) -{ - int wc; - - if (sc->vtblk_flags & VTBLK_FLAG_WC_CONFIG) { - wc = vtblk_tunable_int(sc, "writecache_mode", - vtblk_writecache_mode); - if (wc >= 0 && wc < VTBLK_CACHE_MAX) - vtblk_set_write_cache(sc, wc); - else - wc = blkcfg->writeback; - } else - wc = virtio_with_feature(sc->vtblk_dev, VIRTIO_BLK_F_WCE); - - return (wc); -} - -static int -vtblk_write_cache_sysctl(SYSCTL_HANDLER_ARGS) -{ - struct vtblk_softc *sc; - int wc, error; - - sc = oidp->oid_arg1; - wc = sc->vtblk_write_cache; - - error = sysctl_handle_int(oidp, &wc, 0, req); - if (error || req->newptr == NULL) - return (error); - if ((sc->vtblk_flags & VTBLK_FLAG_WC_CONFIG) == 0) - return (EPERM); - if (wc < 0 || wc >= VTBLK_CACHE_MAX) - return (EINVAL); - - VTBLK_LOCK(sc); - sc->vtblk_write_cache = wc; - vtblk_set_write_cache(sc, sc->vtblk_write_cache); - VTBLK_UNLOCK(sc); - - return (0); -} - static void vtblk_alloc_disk(struct vtblk_softc *sc, struct virtio_blk_config *blkcfg) { @@ -728,7 +672,8 @@ vtblk_alloc_disk(struct vtblk_softc *sc, struct virtio_blk_config *blkcfg) dp->d_name = VTBLK_DISK_NAME; dp->d_unit = device_get_unit(dev); dp->d_drv1 = sc; - dp->d_flags = DISKFLAG_CANFLUSHCACHE | DISKFLAG_UNMAPPED_BIO; + dp->d_flags = DISKFLAG_CANFLUSHCACHE | DISKFLAG_UNMAPPED_BIO | + DISKFLAG_DIRECT_COMPLETION; dp->d_hba_vendor = virtio_get_vendor(dev); dp->d_hba_device = virtio_get_device(dev); dp->d_hba_subvendor = virtio_get_subvendor(dev); @@ -789,11 +734,7 @@ vtblk_create_disk(struct vtblk_softc *sc) dp = sc->vtblk_disk; - /* - * Retrieving the identification string must be done after - * the virtqueue interrupt is setup otherwise it will hang. - */ - vtblk_get_ident(sc); + vtblk_ident(sc); device_printf(sc->vtblk_dev, "%juMB (%ju %u byte sectors)\n", (uintmax_t) dp->d_mediasize >> 20, @@ -804,57 +745,107 @@ vtblk_create_disk(struct vtblk_softc *sc) } static int -vtblk_quiesce(struct vtblk_softc *sc) +vtblk_request_prealloc(struct vtblk_softc *sc) { - int error; + struct vtblk_request *req; + int i, nreqs; - error = 0; + nreqs = virtqueue_size(sc->vtblk_vq); - VTBLK_LOCK_ASSERT(sc); + /* + * Preallocate sufficient requests to keep the virtqueue full. Each + * request consumes VTBLK_MIN_SEGMENTS or more descriptors so reduce + * the number allocated when indirect descriptors are not available. + */ + if ((sc->vtblk_flags & VTBLK_FLAG_INDIRECT) == 0) + nreqs /= VTBLK_MIN_SEGMENTS; - while (!virtqueue_empty(sc->vtblk_vq)) { - if (mtx_sleep(&sc->vtblk_vq, VTBLK_MTX(sc), PRIBIO, "vtblkq", - VTBLK_QUIESCE_TIMEOUT) == EWOULDBLOCK) { - error = EBUSY; - break; - } + for (i = 0; i < nreqs; i++) { + req = malloc(sizeof(struct vtblk_request), M_DEVBUF, M_NOWAIT); + if (req == NULL) + return (ENOMEM); + + MPASS(sglist_count(&req->vbr_hdr, sizeof(req->vbr_hdr)) == 1); + MPASS(sglist_count(&req->vbr_ack, sizeof(req->vbr_ack)) == 1); + + sc->vtblk_request_count++; + vtblk_request_enqueue(sc, req); } - return (error); + return (0); } static void -vtblk_startio(struct vtblk_softc *sc) +vtblk_request_free(struct vtblk_softc *sc) { - struct virtqueue *vq; struct vtblk_request *req; - int enq; - vq = sc->vtblk_vq; - enq = 0; + MPASS(TAILQ_EMPTY(&sc->vtblk_req_ready)); - VTBLK_LOCK_ASSERT(sc); - - while (!virtqueue_full(vq)) { - if ((req = vtblk_dequeue_ready(sc)) == NULL) - req = vtblk_bio_request(sc); - if (req == NULL) - break; - - if (vtblk_execute_request(sc, req) != 0) { - vtblk_enqueue_ready(sc, req); - break; - } - - enq++; + while ((req = vtblk_request_dequeue(sc)) != NULL) { + sc->vtblk_request_count--; + free(req, M_DEVBUF); } - if (enq > 0) - virtqueue_notify(vq); + KASSERT(sc->vtblk_request_count == 0, + ("%s: leaked %d requests", __func__, sc->vtblk_request_count)); } static struct vtblk_request * -vtblk_bio_request(struct vtblk_softc *sc) +vtblk_request_dequeue(struct vtblk_softc *sc) +{ + struct vtblk_request *req; + + req = TAILQ_FIRST(&sc->vtblk_req_free); + if (req != NULL) { + TAILQ_REMOVE(&sc->vtblk_req_free, req, vbr_link); + bzero(req, sizeof(struct vtblk_request)); + } + + return (req); +} + +static void +vtblk_request_enqueue(struct vtblk_softc *sc, struct vtblk_request *req) +{ + + TAILQ_INSERT_HEAD(&sc->vtblk_req_free, req, vbr_link); +} + +static struct vtblk_request * +vtblk_request_next_ready(struct vtblk_softc *sc) +{ + struct vtblk_request *req; + + req = TAILQ_FIRST(&sc->vtblk_req_ready); + if (req != NULL) + TAILQ_REMOVE(&sc->vtblk_req_ready, req, vbr_link); + + return (req); +} + +static void +vtblk_request_requeue_ready(struct vtblk_softc *sc, struct vtblk_request *req) +{ + + /* NOTE: Currently, there will be at most one request in the queue. */ + TAILQ_INSERT_HEAD(&sc->vtblk_req_ready, req, vbr_link); +} + +static struct vtblk_request * +vtblk_request_next(struct vtblk_softc *sc) +{ + struct vtblk_request *req; + + req = vtblk_request_next_ready(sc); + if (req != NULL) + return (req); + + return (vtblk_request_bio(sc)); +} + +static struct vtblk_request * +vtblk_request_bio(struct vtblk_softc *sc) { struct bio_queue_head *bioq; struct vtblk_request *req; @@ -865,7 +856,7 @@ vtblk_bio_request(struct vtblk_softc *sc) if (bioq_first(bioq) == NULL) return (NULL); - req = vtblk_dequeue_request(sc); + req = vtblk_request_dequeue(sc); if (req == NULL) return (NULL); @@ -890,11 +881,14 @@ vtblk_bio_request(struct vtblk_softc *sc) panic("%s: bio with unhandled cmd: %d", __func__, bp->bio_cmd); } + if (bp->bio_flags & BIO_ORDERED) + req->vbr_hdr.type |= VIRTIO_BLK_T_BARRIER; + return (req); } static int -vtblk_execute_request(struct vtblk_softc *sc, struct vtblk_request *req) +vtblk_request_execute(struct vtblk_softc *sc, struct vtblk_request *req) { struct virtqueue *vq; struct sglist *sg; @@ -907,26 +901,20 @@ vtblk_execute_request(struct vtblk_softc *sc, struct vtblk_request *req) ordered = 0; writable = 0; - VTBLK_LOCK_ASSERT(sc); - /* - * Wait until the ordered request completes before - * executing subsequent requests. + * Some hosts (such as bhyve) do not implement the barrier feature, + * so we emulate it in the driver by allowing the barrier request + * to be the only one in flight. */ - if (sc->vtblk_req_ordered != NULL) - return (EBUSY); - - if (bp->bio_flags & BIO_ORDERED) { - if ((sc->vtblk_flags & VTBLK_FLAG_BARRIER) == 0) { - /* - * This request will be executed once all - * the in-flight requests are completed. - */ + if ((sc->vtblk_flags & VTBLK_FLAG_BARRIER) == 0) { + if (sc->vtblk_req_ordered != NULL) + return (EBUSY); + if (bp->bio_flags & BIO_ORDERED) { if (!virtqueue_empty(vq)) return (EBUSY); ordered = 1; - } else - req->vbr_hdr.type |= VIRTIO_BLK_T_BARRIER; + req->vbr_hdr.type &= ~VIRTIO_BLK_T_BARRIER; + } } sglist_reset(sg); @@ -935,7 +923,7 @@ vtblk_execute_request(struct vtblk_softc *sc, struct vtblk_request *req) if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) { error = sglist_append_bio(sg, bp); if (error || sg->sg_nseg == sg->sg_maxseg) { - panic("%s: data buffer too big bio:%p error:%d", + panic("%s: bio %p data buffer too big %d", __func__, bp, error); } @@ -955,44 +943,156 @@ vtblk_execute_request(struct vtblk_softc *sc, struct vtblk_request *req) return (error); } -static void -vtblk_vq_intr(void *xsc) +static int +vtblk_request_error(struct vtblk_request *req) { - struct vtblk_softc *sc; - struct virtqueue *vq; + int error; - sc = xsc; - vq = sc->vtblk_vq; - -again: - VTBLK_LOCK(sc); - if (sc->vtblk_flags & VTBLK_FLAG_DETACH) { - VTBLK_UNLOCK(sc); - return; + switch (req->vbr_ack) { + case VIRTIO_BLK_S_OK: + error = 0; + break; + case VIRTIO_BLK_S_UNSUPP: + error = ENOTSUP; + break; + default: + error = EIO; + break; } - vtblk_finish_completed(sc); - - if ((sc->vtblk_flags & VTBLK_FLAG_SUSPEND) == 0) - vtblk_startio(sc); - else - wakeup(&sc->vtblk_vq); - - if (virtqueue_enable_intr(vq) != 0) { - virtqueue_disable_intr(vq); - VTBLK_UNLOCK(sc); - goto again; - } - - VTBLK_UNLOCK(sc); + return (error); } static void -vtblk_stop(struct vtblk_softc *sc) +vtblk_queue_completed(struct vtblk_softc *sc, struct bio_queue *queue) +{ + struct vtblk_request *req; + struct bio *bp; + + while ((req = virtqueue_dequeue(sc->vtblk_vq, NULL)) != NULL) { + if (sc->vtblk_req_ordered != NULL) { + MPASS(sc->vtblk_req_ordered == req); + sc->vtblk_req_ordered = NULL; + } + + bp = req->vbr_bp; + bp->bio_error = vtblk_request_error(req); + TAILQ_INSERT_TAIL(queue, bp, bio_queue); + + vtblk_request_enqueue(sc, req); + } +} + +static void +vtblk_done_completed(struct vtblk_softc *sc, struct bio_queue *queue) +{ + struct bio *bp, *tmp; + + TAILQ_FOREACH_SAFE(bp, queue, bio_queue, tmp) { + if (bp->bio_error != 0) + disk_err(bp, "hard error", -1, 1); + vtblk_bio_done(sc, bp, bp->bio_error); + } +} + +static void +vtblk_drain_vq(struct vtblk_softc *sc, int skip_done) +{ + struct virtqueue *vq; + struct vtblk_request *req; + int last; + + vq = sc->vtblk_vq; + last = 0; + + while ((req = virtqueue_drain(vq, &last)) != NULL) { + if (!skip_done) + vtblk_bio_done(sc, req->vbr_bp, ENXIO); + + vtblk_request_enqueue(sc, req); + } + + sc->vtblk_req_ordered = NULL; + KASSERT(virtqueue_empty(vq), ("virtqueue not empty")); +} + +static void +vtblk_drain(struct vtblk_softc *sc) +{ + struct bio_queue queue; + struct bio_queue_head *bioq; + struct vtblk_request *req; + struct bio *bp; + + bioq = &sc->vtblk_bioq; + TAILQ_INIT(&queue); + + if (sc->vtblk_vq != NULL) { + vtblk_queue_completed(sc, &queue); + vtblk_done_completed(sc, &queue); + + vtblk_drain_vq(sc, 0); + } + + while ((req = vtblk_request_next_ready(sc)) != NULL) { + vtblk_bio_done(sc, req->vbr_bp, ENXIO); + vtblk_request_enqueue(sc, req); + } + + while (bioq_first(bioq) != NULL) { + bp = bioq_takefirst(bioq); + vtblk_bio_done(sc, bp, ENXIO); + } + + vtblk_request_free(sc); +} + +static void +vtblk_startio(struct vtblk_softc *sc) +{ + struct virtqueue *vq; + struct vtblk_request *req; + int enq; + + VTBLK_LOCK_ASSERT(sc); + vq = sc->vtblk_vq; + enq = 0; + + if (sc->vtblk_flags & VTBLK_FLAG_SUSPEND) + return; + + while (!virtqueue_full(vq)) { + req = vtblk_request_next(sc); + if (req == NULL) + break; + + if (vtblk_request_execute(sc, req) != 0) { + vtblk_request_requeue_ready(sc, req); + break; + } + + enq++; + } + + if (enq > 0) + virtqueue_notify(vq); +} + +static void +vtblk_bio_done(struct vtblk_softc *sc, struct bio *bp, int error) { - virtqueue_disable_intr(sc->vtblk_vq); - virtio_stop(sc->vtblk_dev); + /* Because of GEOM direct dispatch, we cannot hold any locks. */ + if (sc != NULL) + VTBLK_LOCK_ASSERT_NOTOWNED(sc); + + if (error) { + bp->bio_resid = bp->bio_bcount; + bp->bio_error = error; + bp->bio_flags |= BIO_ERROR; + } + + biodone(bp); } #define VTBLK_GET_CONFIG(_dev, _feature, _field, _cfg) \ @@ -1027,7 +1127,7 @@ vtblk_read_config(struct vtblk_softc *sc, struct virtio_blk_config *blkcfg) #undef VTBLK_GET_CONFIG static void -vtblk_get_ident(struct vtblk_softc *sc) +vtblk_ident(struct vtblk_softc *sc) { struct bio buf; struct disk *dp; @@ -1040,7 +1140,7 @@ vtblk_get_ident(struct vtblk_softc *sc) if (vtblk_tunable_int(sc, "no_ident", vtblk_no_ident) != 0) return; - req = vtblk_dequeue_request(sc); + req = vtblk_request_dequeue(sc); if (req == NULL) return; @@ -1060,7 +1160,7 @@ vtblk_get_ident(struct vtblk_softc *sc) error = vtblk_poll_request(sc, req); VTBLK_UNLOCK(sc); - vtblk_enqueue_request(sc, req); + vtblk_request_enqueue(sc, req); if (error) { device_printf(sc->vtblk_dev, @@ -1068,8 +1168,95 @@ vtblk_get_ident(struct vtblk_softc *sc) } } +static int +vtblk_poll_request(struct vtblk_softc *sc, struct vtblk_request *req) +{ + struct virtqueue *vq; + int error; + + vq = sc->vtblk_vq; + + if (!virtqueue_empty(vq)) + return (EBUSY); + + error = vtblk_request_execute(sc, req); + if (error) + return (error); + + virtqueue_notify(vq); + virtqueue_poll(vq, NULL); + + error = vtblk_request_error(req); + if (error && bootverbose) { + device_printf(sc->vtblk_dev, + "%s: IO error: %d\n", __func__, error); + } + + return (error); +} + +static int +vtblk_quiesce(struct vtblk_softc *sc) +{ + int error; + + VTBLK_LOCK_ASSERT(sc); + error = 0; + + while (!virtqueue_empty(sc->vtblk_vq)) { + if (mtx_sleep(&sc->vtblk_vq, VTBLK_MTX(sc), PRIBIO, "vtblkq", + VTBLK_QUIESCE_TIMEOUT) == EWOULDBLOCK) { + error = EBUSY; + break; + } + } + + return (error); +} + static void -vtblk_prepare_dump(struct vtblk_softc *sc) +vtblk_vq_intr(void *xsc) +{ + struct vtblk_softc *sc; + struct virtqueue *vq; + struct bio_queue queue; + + sc = xsc; + vq = sc->vtblk_vq; + TAILQ_INIT(&queue); + + VTBLK_LOCK(sc); + +again: + if (sc->vtblk_flags & VTBLK_FLAG_DETACH) + goto out; + + vtblk_queue_completed(sc, &queue); + vtblk_startio(sc); + + if (virtqueue_enable_intr(vq) != 0) { + virtqueue_disable_intr(vq); + goto again; + } + + if (sc->vtblk_flags & VTBLK_FLAG_SUSPEND) + wakeup(&sc->vtblk_vq); + +out: + VTBLK_UNLOCK(sc); + vtblk_done_completed(sc, &queue); +} + +static void +vtblk_stop(struct vtblk_softc *sc) +{ + + virtqueue_disable_intr(sc->vtblk_vq); + virtio_stop(sc->vtblk_dev); +} + +static void +vtblk_dump_prepare(struct vtblk_softc *sc) { device_t dev; struct virtqueue *vq; @@ -1097,7 +1284,7 @@ vtblk_prepare_dump(struct vtblk_softc *sc) } static int -vtblk_write_dump(struct vtblk_softc *sc, void *virtual, off_t offset, +vtblk_dump_write(struct vtblk_softc *sc, void *virtual, off_t offset, size_t length) { struct bio buf; @@ -1120,7 +1307,7 @@ vtblk_write_dump(struct vtblk_softc *sc, void *virtual, off_t offset, } static int -vtblk_flush_dump(struct vtblk_softc *sc) +vtblk_dump_flush(struct vtblk_softc *sc) { struct bio buf; struct vtblk_request *req; @@ -1139,241 +1326,59 @@ vtblk_flush_dump(struct vtblk_softc *sc) return (vtblk_poll_request(sc, req)); } -static int -vtblk_poll_request(struct vtblk_softc *sc, struct vtblk_request *req) +static void +vtblk_set_write_cache(struct vtblk_softc *sc, int wc) { - struct virtqueue *vq; - int error; - vq = sc->vtblk_vq; + /* Set either writeback (1) or writethrough (0) mode. */ + virtio_write_dev_config_1(sc->vtblk_dev, + offsetof(struct virtio_blk_config, writeback), wc); +} - if (!virtqueue_empty(vq)) - return (EBUSY); +static int +vtblk_write_cache_enabled(struct vtblk_softc *sc, + struct virtio_blk_config *blkcfg) +{ + int wc; - error = vtblk_execute_request(sc, req); - if (error) + if (sc->vtblk_flags & VTBLK_FLAG_WC_CONFIG) { + wc = vtblk_tunable_int(sc, "writecache_mode", + vtblk_writecache_mode); + if (wc >= 0 && wc < VTBLK_CACHE_MAX) + vtblk_set_write_cache(sc, wc); + else + wc = blkcfg->writeback; + } else + wc = virtio_with_feature(sc->vtblk_dev, VIRTIO_BLK_F_WCE); + + return (wc); +} + +static int +vtblk_write_cache_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct vtblk_softc *sc; + int wc, error; + + sc = oidp->oid_arg1; + wc = sc->vtblk_write_cache; + + error = sysctl_handle_int(oidp, &wc, 0, req); + if (error || req->newptr == NULL) return (error); + if ((sc->vtblk_flags & VTBLK_FLAG_WC_CONFIG) == 0) + return (EPERM); + if (wc < 0 || wc >= VTBLK_CACHE_MAX) + return (EINVAL); - virtqueue_notify(vq); - virtqueue_poll(vq, NULL); - - error = vtblk_request_error(req); - if (error && bootverbose) { - device_printf(sc->vtblk_dev, - "%s: IO error: %d\n", __func__, error); - } - - return (error); -} - -static void -vtblk_finish_completed(struct vtblk_softc *sc) -{ - struct vtblk_request *req; - struct bio *bp; - int error; - - while ((req = virtqueue_dequeue(sc->vtblk_vq, NULL)) != NULL) { - bp = req->vbr_bp; - - if (sc->vtblk_req_ordered != NULL) { - /* This should be the only outstanding request. */ - MPASS(sc->vtblk_req_ordered == req); - sc->vtblk_req_ordered = NULL; - } - - error = vtblk_request_error(req); - if (error) - disk_err(bp, "hard error", -1, 1); - - vtblk_finish_bio(bp, error); - vtblk_enqueue_request(sc, req); - } -} - -static void -vtblk_drain_vq(struct vtblk_softc *sc, int skip_done) -{ - struct virtqueue *vq; - struct vtblk_request *req; - int last; - - vq = sc->vtblk_vq; - last = 0; - - while ((req = virtqueue_drain(vq, &last)) != NULL) { - if (!skip_done) - vtblk_finish_bio(req->vbr_bp, ENXIO); - - vtblk_enqueue_request(sc, req); - } - - sc->vtblk_req_ordered = NULL; - KASSERT(virtqueue_empty(vq), ("virtqueue not empty")); -} - -static void -vtblk_drain(struct vtblk_softc *sc) -{ - struct bio_queue_head *bioq; - struct vtblk_request *req; - struct bio *bp; - - bioq = &sc->vtblk_bioq; - - if (sc->vtblk_vq != NULL) { - vtblk_finish_completed(sc); - vtblk_drain_vq(sc, 0); - } - - while ((req = vtblk_dequeue_ready(sc)) != NULL) { - vtblk_finish_bio(req->vbr_bp, ENXIO); - vtblk_enqueue_request(sc, req); - } - - while (bioq_first(bioq) != NULL) { - bp = bioq_takefirst(bioq); - vtblk_finish_bio(bp, ENXIO); - } - - vtblk_free_requests(sc); -} - -#ifdef INVARIANTS -static void -vtblk_request_invariants(struct vtblk_request *req) -{ - int hdr_nsegs, ack_nsegs; - - hdr_nsegs = sglist_count(&req->vbr_hdr, sizeof(req->vbr_hdr)); - ack_nsegs = sglist_count(&req->vbr_ack, sizeof(req->vbr_ack)); - - KASSERT(hdr_nsegs == 1, ("request header crossed page boundary")); - KASSERT(ack_nsegs == 1, ("request ack crossed page boundary")); -} -#endif - -static int -vtblk_alloc_requests(struct vtblk_softc *sc) -{ - struct vtblk_request *req; - int i, nreqs; - - nreqs = virtqueue_size(sc->vtblk_vq); - - /* - * Preallocate sufficient requests to keep the virtqueue full. Each - * request consumes VTBLK_MIN_SEGMENTS or more descriptors so reduce - * the number allocated when indirect descriptors are not available. - */ - if ((sc->vtblk_flags & VTBLK_FLAG_INDIRECT) == 0) - nreqs /= VTBLK_MIN_SEGMENTS; - - for (i = 0; i < nreqs; i++) { - req = malloc(sizeof(struct vtblk_request), M_DEVBUF, M_NOWAIT); - if (req == NULL) - return (ENOMEM); - -#ifdef INVARIANTS - vtblk_request_invariants(req); -#endif - - sc->vtblk_request_count++; - vtblk_enqueue_request(sc, req); - } + VTBLK_LOCK(sc); + sc->vtblk_write_cache = wc; + vtblk_set_write_cache(sc, sc->vtblk_write_cache); + VTBLK_UNLOCK(sc); return (0); } -static void -vtblk_free_requests(struct vtblk_softc *sc) -{ - struct vtblk_request *req; - - KASSERT(TAILQ_EMPTY(&sc->vtblk_req_ready), - ("%s: ready requests left on queue", __func__)); - - while ((req = vtblk_dequeue_request(sc)) != NULL) { - sc->vtblk_request_count--; - free(req, M_DEVBUF); - } - - KASSERT(sc->vtblk_request_count == 0, - ("%s: leaked %d requests", __func__, sc->vtblk_request_count)); -} - -static struct vtblk_request * -vtblk_dequeue_request(struct vtblk_softc *sc) -{ - struct vtblk_request *req; - - req = TAILQ_FIRST(&sc->vtblk_req_free); - if (req != NULL) - TAILQ_REMOVE(&sc->vtblk_req_free, req, vbr_link); - - return (req); -} - -static void -vtblk_enqueue_request(struct vtblk_softc *sc, struct vtblk_request *req) -{ - - bzero(req, sizeof(struct vtblk_request)); - TAILQ_INSERT_HEAD(&sc->vtblk_req_free, req, vbr_link); -} - -static struct vtblk_request * -vtblk_dequeue_ready(struct vtblk_softc *sc) -{ - struct vtblk_request *req; - - req = TAILQ_FIRST(&sc->vtblk_req_ready); - if (req != NULL) - TAILQ_REMOVE(&sc->vtblk_req_ready, req, vbr_link); - - return (req); -} - -static void -vtblk_enqueue_ready(struct vtblk_softc *sc, struct vtblk_request *req) -{ - - TAILQ_INSERT_HEAD(&sc->vtblk_req_ready, req, vbr_link); -} - -static int -vtblk_request_error(struct vtblk_request *req) -{ - int error; - - switch (req->vbr_ack) { - case VIRTIO_BLK_S_OK: - error = 0; - break; - case VIRTIO_BLK_S_UNSUPP: - error = ENOTSUP; - break; - default: - error = EIO; - break; - } - - return (error); -} - -static void -vtblk_finish_bio(struct bio *bp, int error) -{ - - if (error) { - bp->bio_resid = bp->bio_bcount; - bp->bio_error = error; - bp->bio_flags |= BIO_ERROR; - } - - biodone(bp); -} - static void vtblk_setup_sysctl(struct vtblk_softc *sc) { diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c index 83cb2d79fe25..9fba9bdabe0b 100644 --- a/sys/dev/virtio/network/if_vtnet.c +++ b/sys/dev/virtio/network/if_vtnet.c @@ -1701,7 +1701,7 @@ vtnet_rxq_input(struct vtnet_rxq *rxq, struct mbuf *m, } m->m_pkthdr.flowid = rxq->vtnrx_id; - m->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); /* * BMV: FreeBSD does not have the UNNECESSARY and PARTIAL checksum @@ -2347,7 +2347,8 @@ vtnet_txq_mq_start(struct ifnet *ifp, struct mbuf *m) sc = ifp->if_softc; npairs = sc->vtnet_act_vq_pairs; - if (m->m_flags & M_FLOWID) + /* check if flowid is set */ + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) i = m->m_pkthdr.flowid % npairs; else i = curcpu % npairs; diff --git a/sys/dev/vmware/vmxnet3/if_vmx.c b/sys/dev/vmware/vmxnet3/if_vmx.c index 1d8c12e2fc9b..5faf716acf4d 100644 --- a/sys/dev/vmware/vmxnet3/if_vmx.c +++ b/sys/dev/vmware/vmxnet3/if_vmx.c @@ -2059,7 +2059,7 @@ vmxnet3_rxq_input(struct vmxnet3_rxqueue *rxq, } #else m->m_pkthdr.flowid = rxq->vxrxq_id; - m->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); #endif if (!rxcd->no_csum) @@ -3002,7 +3002,8 @@ vmxnet3_txq_mq_start(struct ifnet *ifp, struct mbuf *m) sc = ifp->if_softc; ntxq = sc->vmx_ntxqueues; - if (m->m_flags & M_FLOWID) + /* check if flowid is set */ + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) i = m->m_pkthdr.flowid % ntxq; else i = curcpu % ntxq; diff --git a/sys/dev/vxge/vxge.c b/sys/dev/vxge/vxge.c index b89ba6cca51e..9a3cab654f95 100644 --- a/sys/dev/vxge/vxge.c +++ b/sys/dev/vxge/vxge.c @@ -660,7 +660,7 @@ vxge_mq_send(ifnet_t ifp, mbuf_t m_head) if (vdev->config.tx_steering) { i = vxge_vpath_get(vdev, m_head); - } else if ((m_head->m_flags & M_FLOWID) != 0) { + } else if (M_HASHTYPE_GET(m_head) != M_HASHTYPE_NONE) { i = m_head->m_pkthdr.flowid % vdev->no_of_vpath; } @@ -1070,7 +1070,7 @@ vxge_rx_compl(vxge_hal_vpath_h vpath_handle, vxge_hal_rxd_h rxdh, vxge_rx_checksum(ext_info, mbuf_up); #if __FreeBSD_version >= 800000 - mbuf_up->m_flags |= M_FLOWID; + M_HASHTYPE_SET(mbuf_up, M_HASHTYPE_OPAQUE); mbuf_up->m_pkthdr.flowid = vpath->vp_index; #endif /* Post-Read sync for buffers */ diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c index 3a3dbc44c04f..f82e2457b012 100644 --- a/sys/kern/subr_taskqueue.c +++ b/sys/kern/subr_taskqueue.c @@ -661,11 +661,11 @@ taskqueue_thread_enqueue(void *context) TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, NULL, swi_add(NULL, "task queue", taskqueue_swi_run, NULL, SWI_TQ, - INTR_MPSAFE, &taskqueue_ih)); + INTR_MPSAFE, &taskqueue_ih)); TASKQUEUE_DEFINE(swi_giant, taskqueue_swi_giant_enqueue, NULL, swi_add(NULL, "Giant taskq", taskqueue_swi_giant_run, - NULL, SWI_TQ_GIANT, 0, &taskqueue_giant_ih)); + NULL, SWI_TQ_GIANT, 0, &taskqueue_giant_ih)); TASKQUEUE_DEFINE_THREAD(thread); diff --git a/sys/kern/uipc_debug.c b/sys/kern/uipc_debug.c index 0f233ecebd69..c3081a497ae6 100644 --- a/sys/kern/uipc_debug.c +++ b/sys/kern/uipc_debug.c @@ -401,7 +401,8 @@ db_print_sockbuf(struct sockbuf *sb, const char *sockbufname, int indent) db_printf("sb_sndptroff: %u\n", sb->sb_sndptroff); db_print_indent(indent); - db_printf("sb_cc: %u ", sb->sb_cc); + db_printf("sb_acc: %u ", sb->sb_acc); + db_printf("sb_ccc: %u ", sb->sb_ccc); db_printf("sb_hiwat: %u ", sb->sb_hiwat); db_printf("sb_mbcnt: %u ", sb->sb_mbcnt); db_printf("sb_mbmax: %u\n", sb->sb_mbmax); diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 709cc0eb0569..9eda77c0f2d8 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -152,6 +152,7 @@ protosw_init(struct protosw *pr) DEFAULT(pu->pru_sosend, sosend_generic); DEFAULT(pu->pru_soreceive, soreceive_generic); DEFAULT(pu->pru_sopoll, sopoll_generic); + DEFAULT(pu->pru_ready, pru_ready_notsupp); #undef DEFAULT if (pr->pr_init) (*pr->pr_init)(); diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 323426898d09..3880456bddf7 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -388,7 +388,7 @@ mb_dupcl(struct mbuf *n, struct mbuf *m) * cleaned too. */ void -m_demote(struct mbuf *m0, int all) +m_demote(struct mbuf *m0, int all, int flags) { struct mbuf *m; @@ -400,7 +400,7 @@ m_demote(struct mbuf *m0, int all) m->m_flags &= ~M_PKTHDR; bzero(&m->m_pkthdr, sizeof(struct pkthdr)); } - m->m_flags = m->m_flags & (M_EXT|M_RDONLY|M_NOFREE); + m->m_flags = m->m_flags & (M_EXT | M_RDONLY | M_NOFREE | flags); } } @@ -997,7 +997,7 @@ m_catpkt(struct mbuf *m, struct mbuf *n) M_ASSERTPKTHDR(n); m->m_pkthdr.len += n->m_pkthdr.len; - m_demote(n, 1); + m_demote(n, 1, 0); m_cat(m, n); } diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index 01e48b55aac0..537f9c867bf8 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -68,6 +68,123 @@ static u_long sb_efficiency = 8; /* parameter for sbreserve() */ static struct mbuf *sbcut_internal(struct sockbuf *sb, int len); static void sbflush_internal(struct sockbuf *sb); +/* + * Mark ready "count" mbufs starting with "m". + */ +int +sbready(struct sockbuf *sb, struct mbuf *m, int count) +{ + u_int blocker; + + SOCKBUF_LOCK_ASSERT(sb); + KASSERT(sb->sb_fnrdy != NULL, ("%s: sb %p NULL fnrdy", __func__, sb)); + + blocker = (sb->sb_fnrdy == m) ? M_BLOCKED : 0; + + for (int i = 0; i < count; i++, m = m->m_next) { + KASSERT(m->m_flags & M_NOTREADY, + ("%s: m %p !M_NOTREADY", __func__, m)); + m->m_flags &= ~(M_NOTREADY | blocker); + if (blocker) + sb->sb_acc += m->m_len; + } + + if (!blocker) + return (EINPROGRESS); + + /* This one was blocking all the queue. */ + for (; m && (m->m_flags & M_NOTREADY) == 0; m = m->m_next) { + KASSERT(m->m_flags & M_BLOCKED, + ("%s: m %p !M_BLOCKED", __func__, m)); + m->m_flags &= ~M_BLOCKED; + sb->sb_acc += m->m_len; + } + + sb->sb_fnrdy = m; + + return (0); +} + +/* + * Adjust sockbuf state reflecting allocation of m. + */ +void +sballoc(struct sockbuf *sb, struct mbuf *m) +{ + + SOCKBUF_LOCK_ASSERT(sb); + + sb->sb_ccc += m->m_len; + + if (sb->sb_fnrdy == NULL) { + if (m->m_flags & M_NOTREADY) + sb->sb_fnrdy = m; + else + sb->sb_acc += m->m_len; + } else + m->m_flags |= M_BLOCKED; + + if (m->m_type != MT_DATA && m->m_type != MT_OOBDATA) + sb->sb_ctl += m->m_len; + + sb->sb_mbcnt += MSIZE; + sb->sb_mcnt += 1; + + if (m->m_flags & M_EXT) { + sb->sb_mbcnt += m->m_ext.ext_size; + sb->sb_ccnt += 1; + } +} + +/* + * Adjust sockbuf state reflecting freeing of m. + */ +void +sbfree(struct sockbuf *sb, struct mbuf *m) +{ + +#if 0 /* XXX: not yet: soclose() call path comes here w/o lock. */ + SOCKBUF_LOCK_ASSERT(sb); +#endif + + sb->sb_ccc -= m->m_len; + + if (!(m->m_flags & M_NOTAVAIL)) + sb->sb_acc -= m->m_len; + + if (m == sb->sb_fnrdy) { + struct mbuf *n; + + KASSERT(m->m_flags & M_NOTREADY, + ("%s: m %p !M_NOTREADY", __func__, m)); + + n = m->m_next; + while (n != NULL && !(n->m_flags & M_NOTREADY)) { + n->m_flags &= ~M_BLOCKED; + sb->sb_acc += n->m_len; + n = n->m_next; + } + sb->sb_fnrdy = n; + } + + if (m->m_type != MT_DATA && m->m_type != MT_OOBDATA) + sb->sb_ctl -= m->m_len; + + sb->sb_mbcnt -= MSIZE; + sb->sb_mcnt -= 1; + if (m->m_flags & M_EXT) { + sb->sb_mbcnt -= m->m_ext.ext_size; + sb->sb_ccnt -= 1; + } + + if (sb->sb_sndptr == m) { + sb->sb_sndptr = NULL; + sb->sb_sndptroff = 0; + } + if (sb->sb_sndptroff != 0) + sb->sb_sndptroff -= m->m_len; +} + /* * Socantsendmore indicates that no more data will be sent on the socket; it * would normally be applied to a socket when the user informs the system @@ -127,7 +244,7 @@ sbwait(struct sockbuf *sb) SOCKBUF_LOCK_ASSERT(sb); sb->sb_flags |= SB_WAIT; - return (msleep_sbt(&sb->sb_cc, &sb->sb_mtx, + return (msleep_sbt(&sb->sb_acc, &sb->sb_mtx, (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "sbwait", sb->sb_timeo, 0, 0)); } @@ -184,7 +301,7 @@ sowakeup(struct socket *so, struct sockbuf *sb) sb->sb_flags &= ~SB_SEL; if (sb->sb_flags & SB_WAIT) { sb->sb_flags &= ~SB_WAIT; - wakeup(&sb->sb_cc); + wakeup(&sb->sb_acc); } KNOTE_LOCKED(&sb->sb_sel.si_note, 0); if (sb->sb_upcall != NULL) { @@ -519,7 +636,7 @@ sbappend(struct sockbuf *sb, struct mbuf *m) * that is, a stream protocol (such as TCP). */ void -sbappendstream_locked(struct sockbuf *sb, struct mbuf *m) +sbappendstream_locked(struct sockbuf *sb, struct mbuf *m, int flags) { SOCKBUF_LOCK_ASSERT(sb); @@ -529,8 +646,8 @@ sbappendstream_locked(struct sockbuf *sb, struct mbuf *m) SBLASTMBUFCHK(sb); /* Remove all packet headers and mbuf tags to get a pure data chain. */ - m_demote(m, 1); - + m_demote(m, 1, flags & PRUS_NOTREADY ? M_NOTREADY : 0); + sbcompress(sb, m, sb->sb_mbtail); sb->sb_lastrecord = sb->sb_mb; @@ -543,38 +660,63 @@ sbappendstream_locked(struct sockbuf *sb, struct mbuf *m) * that is, a stream protocol (such as TCP). */ void -sbappendstream(struct sockbuf *sb, struct mbuf *m) +sbappendstream(struct sockbuf *sb, struct mbuf *m, int flags) { SOCKBUF_LOCK(sb); - sbappendstream_locked(sb, m); + sbappendstream_locked(sb, m, flags); SOCKBUF_UNLOCK(sb); } #ifdef SOCKBUF_DEBUG void -sbcheck(struct sockbuf *sb) +sbcheck(struct sockbuf *sb, const char *file, int line) { - struct mbuf *m; - struct mbuf *n = 0; - u_long len = 0, mbcnt = 0; + struct mbuf *m, *n, *fnrdy; + u_long acc, ccc, mbcnt; SOCKBUF_LOCK_ASSERT(sb); + acc = ccc = mbcnt = 0; + fnrdy = NULL; + for (m = sb->sb_mb; m; m = n) { n = m->m_nextpkt; for (; m; m = m->m_next) { - len += m->m_len; + if (m->m_len == 0) { + printf("sb %p empty mbuf %p\n", sb, m); + goto fail; + } + if ((m->m_flags & M_NOTREADY) && fnrdy == NULL) { + if (m != sb->sb_fnrdy) { + printf("sb %p: fnrdy %p != m %p\n", + sb, sb->sb_fnrdy, m); + goto fail; + } + fnrdy = m; + } + if (fnrdy) { + if (!(m->m_flags & M_NOTAVAIL)) { + printf("sb %p: fnrdy %p, m %p is avail\n", + sb, sb->sb_fnrdy, m); + goto fail; + } + } else + acc += m->m_len; + ccc += m->m_len; mbcnt += MSIZE; if (m->m_flags & M_EXT) /*XXX*/ /* pretty sure this is bogus */ mbcnt += m->m_ext.ext_size; } } - if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) { - printf("cc %ld != %u || mbcnt %ld != %u\n", len, sb->sb_cc, - mbcnt, sb->sb_mbcnt); - panic("sbcheck"); + if (acc != sb->sb_acc || ccc != sb->sb_ccc || mbcnt != sb->sb_mbcnt) { + printf("acc %ld/%u ccc %ld/%u mbcnt %ld/%u\n", + acc, sb->sb_acc, ccc, sb->sb_ccc, mbcnt, sb->sb_mbcnt); + goto fail; } + return; +fail: + panic("%s from %s:%u", __func__, file, line); } #endif @@ -770,8 +912,8 @@ sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control) * * (2) The mbuf may be coalesced -- i.e., data in the mbuf may be copied into * an mbuf already in the socket buffer. This can occur if an - * appropriate mbuf exists, there is room, and no merging of data types - * will occur. + * appropriate mbuf exists, there is room, both mbufs are not marked as + * not ready, and no merging of data types will occur. * * (3) The mbuf may be appended to the end of the existing mbuf chain. * @@ -800,13 +942,17 @@ sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n) if (n && (n->m_flags & M_EOR) == 0 && M_WRITABLE(n) && ((sb->sb_flags & SB_NOCOALESCE) == 0) && + !(m->m_flags & M_NOTREADY) && + !(n->m_flags & M_NOTREADY) && m->m_len <= MCLBYTES / 4 && /* XXX: Don't copy too much */ m->m_len <= M_TRAILINGSPACE(n) && n->m_type == m->m_type) { bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len, (unsigned)m->m_len); n->m_len += m->m_len; - sb->sb_cc += m->m_len; + sb->sb_ccc += m->m_len; + if (sb->sb_fnrdy == NULL) + sb->sb_acc += m->m_len; if (m->m_type != MT_DATA && m->m_type != MT_OOBDATA) /* XXX: Probably don't need.*/ sb->sb_ctl += m->m_len; @@ -843,13 +989,13 @@ sbflush_internal(struct sockbuf *sb) * Don't call sbcut(sb, 0) if the leading mbuf is non-empty: * we would loop forever. Panic instead. */ - if (!sb->sb_cc && (sb->sb_mb == NULL || sb->sb_mb->m_len)) + if (sb->sb_ccc == 0 && (sb->sb_mb == NULL || sb->sb_mb->m_len)) break; - m_freem(sbcut_internal(sb, (int)sb->sb_cc)); + m_freem(sbcut_internal(sb, (int)sb->sb_ccc)); } - if (sb->sb_cc || sb->sb_mb || sb->sb_mbcnt) - panic("sbflush_internal: cc %u || mb %p || mbcnt %u", - sb->sb_cc, (void *)sb->sb_mb, sb->sb_mbcnt); + KASSERT(sb->sb_ccc == 0 && sb->sb_mb == 0 && sb->sb_mbcnt == 0, + ("%s: ccc %u mb %p mbcnt %u", __func__, + sb->sb_ccc, (void *)sb->sb_mb, sb->sb_mbcnt)); } void @@ -875,7 +1021,7 @@ sbflush(struct sockbuf *sb) static struct mbuf * sbcut_internal(struct sockbuf *sb, int len) { - struct mbuf *m, *n, *next, *mfree; + struct mbuf *m, *next, *mfree; next = (m = sb->sb_mb) ? m->m_nextpkt : 0; mfree = NULL; @@ -887,9 +1033,12 @@ sbcut_internal(struct sockbuf *sb, int len) next = m->m_nextpkt; } if (m->m_len > len) { + KASSERT(!(m->m_flags & M_NOTAVAIL), + ("%s: m %p M_NOTAVAIL", __func__, m)); m->m_len -= len; m->m_data += len; - sb->sb_cc -= len; + sb->sb_ccc -= len; + sb->sb_acc -= len; if (sb->sb_sndptroff != 0) sb->sb_sndptroff -= len; if (m->m_type != MT_DATA && m->m_type != MT_OOBDATA) @@ -898,10 +1047,20 @@ sbcut_internal(struct sockbuf *sb, int len) } len -= m->m_len; sbfree(sb, m); - n = m->m_next; - m->m_next = mfree; - mfree = m; - m = n; + /* + * Do not put M_NOTREADY buffers to the free list, they + * are referenced from outside. + */ + if (m->m_flags & M_NOTREADY) + m = m->m_next; + else { + struct mbuf *n; + + n = m->m_next; + m->m_next = mfree; + mfree = m; + m = n; + } } if (m) { sb->sb_mb = m; @@ -968,8 +1127,8 @@ sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff) struct mbuf *m, *ret; KASSERT(sb->sb_mb != NULL, ("%s: sb_mb is NULL", __func__)); - KASSERT(off + len <= sb->sb_cc, ("%s: beyond sb", __func__)); - KASSERT(sb->sb_sndptroff <= sb->sb_cc, ("%s: sndptroff broken", __func__)); + KASSERT(off + len <= sb->sb_acc, ("%s: beyond sb", __func__)); + KASSERT(sb->sb_sndptroff <= sb->sb_acc, ("%s: sndptroff broken", __func__)); /* * Is off below stored offset? Happens on retransmits. @@ -1118,7 +1277,7 @@ void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb) { - xsb->sb_cc = sb->sb_cc; + xsb->sb_cc = sb->sb_ccc; xsb->sb_hiwat = sb->sb_hiwat; xsb->sb_mbcnt = sb->sb_mbcnt; xsb->sb_mcnt = sb->sb_mcnt; diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 240421f694b2..b2091ea28417 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1706,7 +1706,8 @@ dontblock: */ moff = 0; offset = 0; - while (m != NULL && uio->uio_resid > 0 && error == 0) { + while (m != NULL && !(m->m_flags & M_NOTAVAIL) && uio->uio_resid > 0 + && error == 0) { /* * If the type of mbuf has changed since the last mbuf * examined ('type'), end the receive operation. @@ -2044,6 +2045,8 @@ deliver: for (m = sb->sb_mb; m != NULL && m->m_len <= len; m = m->m_next) { + KASSERT(!(m->m_flags & M_NOTAVAIL), + ("%s: m %p not available", __func__, m)); len -= m->m_len; uio->uio_resid -= m->m_len; sbfree(sb, m); @@ -3175,6 +3178,13 @@ pru_send_notsupp(struct socket *so, int flags, struct mbuf *m, return EOPNOTSUPP; } +int +pru_ready_notsupp(struct socket *so, struct mbuf *m, int count) +{ + + return (EOPNOTSUPP); +} + /* * This isn't really a ``null'' operation, but it's the default one and * doesn't do anything destructive. diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 00fd8099c2e4..a540cc0dfa85 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1047,6 +1047,32 @@ release: return (error); } +static int +uipc_ready(struct socket *so, struct mbuf *m, int count) +{ + struct unpcb *unp, *unp2; + struct socket *so2; + int error; + + unp = sotounpcb(so); + + UNP_LINK_RLOCK(); + unp2 = unp->unp_conn; + UNP_PCB_LOCK(unp2); + so2 = unp2->unp_socket; + + SOCKBUF_LOCK(&so2->so_rcv); + if ((error = sbready(&so2->so_rcv, m, count)) == 0) + sorwakeup_locked(so2); + else + SOCKBUF_UNLOCK(&so2->so_rcv); + + UNP_PCB_UNLOCK(unp2); + UNP_LINK_RUNLOCK(); + + return (error); +} + static int uipc_sense(struct socket *so, struct stat *sb) { @@ -1161,6 +1187,7 @@ static struct pr_usrreqs uipc_usrreqs_stream = { .pru_peeraddr = uipc_peeraddr, .pru_rcvd = uipc_rcvd, .pru_send = uipc_send, + .pru_ready = uipc_ready, .pru_sense = uipc_sense, .pru_shutdown = uipc_shutdown, .pru_sockaddr = uipc_sockaddr, diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index fe6a52cd3c10..0d584fea3581 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -688,8 +688,8 @@ flowtable_lookup(sa_family_t sa, struct mbuf *m, struct route *ro) if (fle == NULL) return (EHOSTUNREACH); - if (!(m->m_flags & M_FLOWID)) { - m->m_flags |= M_FLOWID; + if (M_HASHTYPE_GET(m) == M_HASHTYPE_NONE) { + M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); m->m_pkthdr.flowid = fle->f_hash; } diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c index 106df68e807a..75f6366e7888 100644 --- a/sys/net/ieee8023ad_lacp.c +++ b/sys/net/ieee8023ad_lacp.c @@ -835,7 +835,8 @@ lacp_select_tx_port(struct lagg_softc *sc, struct mbuf *m) return (NULL); } - if ((sc->sc_opts & LAGG_OPT_USE_FLOWID) && (m->m_flags & M_FLOWID)) + if ((sc->sc_opts & LAGG_OPT_USE_FLOWID) && + M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) hash = m->m_pkthdr.flowid >> sc->flowid_shift; else hash = lagg_hashmbuf(sc, m, lsc->lsc_hashkey); diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index 5c8b2e1d2bdf..45315b6b3b55 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -247,14 +247,14 @@ SYSCTL_INT(_net_link_lagg, OID_AUTO, failover_rx_all, CTLFLAG_RW | CTLFLAG_VNET, &VNET_NAME(lagg_failover_rx_all), 0, "Accept input from any interface in a failover lagg"); -/* Default value for using M_FLOWID */ +/* Default value for using flowid */ static VNET_DEFINE(int, def_use_flowid) = 1; #define V_def_use_flowid VNET(def_use_flowid) SYSCTL_INT(_net_link_lagg, OID_AUTO, default_use_flowid, CTLFLAG_RWTUN, &VNET_NAME(def_use_flowid), 0, "Default setting for using flow id for load sharing"); -/* Default value for using M_FLOWID */ +/* Default value for flowid shift */ static VNET_DEFINE(int, def_flowid_shift) = 16; #define V_def_flowid_shift VNET(def_flowid_shift) SYSCTL_INT(_net_link_lagg, OID_AUTO, default_flowid_shift, CTLFLAG_RWTUN, @@ -2148,7 +2148,8 @@ lagg_lb_start(struct lagg_softc *sc, struct mbuf *m) struct lagg_port *lp = NULL; uint32_t p = 0; - if ((sc->sc_opts & LAGG_OPT_USE_FLOWID) && (m->m_flags & M_FLOWID)) + if ((sc->sc_opts & LAGG_OPT_USE_FLOWID) && + M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) p = m->m_pkthdr.flowid >> sc->flowid_shift; else p = lagg_hashmbuf(sc, m, lb->lb_key); diff --git a/sys/net/if_lagg.h b/sys/net/if_lagg.h index e86ed06fcca7..8d6decd3c069 100644 --- a/sys/net/if_lagg.h +++ b/sys/net/if_lagg.h @@ -143,9 +143,9 @@ struct lagg_reqopts { int ro_opts; /* Option bitmap */ #define LAGG_OPT_NONE 0x00 -#define LAGG_OPT_USE_FLOWID 0x01 /* use M_FLOWID */ +#define LAGG_OPT_USE_FLOWID 0x01 /* enable use of flowid */ /* Pseudo flags which are used in ro_opts but not stored into sc_opts. */ -#define LAGG_OPT_FLOWIDSHIFT 0x02 /* Set flowid */ +#define LAGG_OPT_FLOWIDSHIFT 0x02 /* set flowid shift */ #define LAGG_OPT_FLOWIDSHIFT_MASK 0x1f /* flowid is uint32_t */ #define LAGG_OPT_LACP_STRICT 0x10 /* LACP strict mode */ #define LAGG_OPT_LACP_TXTEST 0x20 /* LACP debug: txtest */ diff --git a/sys/net/if_vxlan.c b/sys/net/if_vxlan.c index 5badf00051fd..59c76ebf4f1b 100644 --- a/sys/net/if_vxlan.c +++ b/sys/net/if_vxlan.c @@ -2236,6 +2236,7 @@ vxlan_pick_source_port(struct vxlan_softc *sc, struct mbuf *m) range = sc->vxl_max_port - sc->vxl_min_port + 1; + /* check if flowid is set and not opaque */ if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE && M_HASHTYPE_GET(m) != M_HASHTYPE_OPAQUE) hash = m->m_pkthdr.flowid; diff --git a/sys/net/netisr.c b/sys/net/netisr.c index 049bbf192b53..178c3cbd1479 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -682,12 +682,13 @@ netisr_select_cpuid(struct netisr_proto *npp, u_int dispatch_policy, } if (policy == NETISR_POLICY_FLOW) { - if (!(m->m_flags & M_FLOWID) && npp->np_m2flow != NULL) { + if (M_HASHTYPE_GET(m) == M_HASHTYPE_NONE && + npp->np_m2flow != NULL) { m = npp->np_m2flow(m, source); if (m == NULL) return (NULL); } - if (m->m_flags & M_FLOWID) { + if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) { *cpuidp = netisr_default_flow2cpu(m->m_pkthdr.flowid); return (m); diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 04ed0b0bdf83..606795a69bb0 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -530,8 +530,8 @@ short inp_so_options(const struct inpcb *inp); #define INP_ONESBCAST 0x02000000 /* send all-ones broadcast */ #define INP_DROPPED 0x04000000 /* protocol drop flag */ #define INP_SOCKREF 0x08000000 /* strong socket reference */ -#define INP_SW_FLOWID 0x10000000 /* software generated flow id */ -#define INP_HW_FLOWID 0x20000000 /* hardware generated flow id */ +#define INP_RESERVED_0 0x10000000 /* reserved field */ +#define INP_RESERVED_1 0x20000000 /* reserved field */ #define IN6P_RFC2292 0x40000000 /* used RFC2292 API on the socket */ #define IN6P_MTU 0x80000000 /* receive path MTU */ diff --git a/sys/netinet/in_rss.c b/sys/netinet/in_rss.c index 7a548c2a8d2e..5d4f3c0dd37f 100644 --- a/sys/netinet/in_rss.c +++ b/sys/netinet/in_rss.c @@ -568,6 +568,8 @@ rss_mbuf_software_hash_v4(const struct mbuf *m, int dir, uint32_t *hashval, const struct ip *ip; const struct tcphdr *th; const struct udphdr *uh; + uint32_t flowid; + uint32_t flowtype; uint8_t proto; int iphlen; int is_frag = 0; @@ -617,12 +619,10 @@ rss_mbuf_software_hash_v4(const struct mbuf *m, int dir, uint32_t *hashval, * then we shouldn't just "trust" the 2-tuple hash. We need * a 4-tuple hash. */ - if (m->m_flags & M_FLOWID) { - uint32_t flowid, flowtype; - - flowid = m->m_pkthdr.flowid; - flowtype = M_HASHTYPE_GET(m); + flowid = m->m_pkthdr.flowid; + flowtype = M_HASHTYPE_GET(m); + if (flowtype != M_HASHTYPE_NONE) { switch (proto) { case IPPROTO_UDP: if ((rss_gethashconfig_local() & RSS_HASHTYPE_RSS_UDP_IPV4) && @@ -743,7 +743,6 @@ rss_soft_m2cpuid(struct mbuf *m, uintptr_t source, u_int *cpuid) /* hash was done; update */ m->m_pkthdr.flowid = hash_val; M_HASHTYPE_SET(m, hash_type); - m->m_flags |= M_FLOWID; *cpuid = rss_hash2cpuid(m->m_pkthdr.flowid, M_HASHTYPE_GET(m)); } else { /* ret < 0 */ /* no hash was done */ diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index d0229b2dccd1..7b8127e90dae 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1196,7 +1196,6 @@ found: if (rss_mbuf_software_hash_v4(m, 0, &rss_hash, &rss_type) == 0) { m->m_pkthdr.flowid = rss_hash; M_HASHTYPE_SET(m, rss_type); - m->m_flags |= M_FLOWID; } /* diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 5d791e57e99f..611c53c7e941 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -147,11 +147,9 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, if (inp != NULL) { INP_LOCK_ASSERT(inp); M_SETFIB(m, inp->inp_inc.inc_fibnum); - if (((flags & IP_NODEFAULTFLOWID) == 0) && - inp->inp_flags & (INP_HW_FLOWID|INP_SW_FLOWID)) { + if ((flags & IP_NODEFAULTFLOWID) == 0) { m->m_pkthdr.flowid = inp->inp_flowid; M_HASHTYPE_SET(m, inp->inp_flowtype); - m->m_flags |= M_FLOWID; } } diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 2065bb4fdae4..97ca01338e83 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -70,14 +70,14 @@ sctp_calc_rwnd(struct sctp_tcb *stcb, struct sctp_association *asoc) /* * This is really set wrong with respect to a 1-2-m socket. Since - * the sb_cc is the count that everyone as put up. When we re-write + * the sb_ccc is the count that everyone as put up. When we re-write * sctp_soreceive then we will fix this so that ONLY this * associations data is taken into account. */ if (stcb->sctp_socket == NULL) return (calc); - if (stcb->asoc.sb_cc == 0 && + if (stcb->asoc.sb_ccc == 0 && asoc->size_on_reasm_queue == 0 && asoc->size_on_all_streams == 0) { /* Full rwnd granted */ @@ -1363,7 +1363,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc, * When we have NO room in the rwnd we check to make sure * the reader is doing its job... */ - if (stcb->sctp_socket->so_rcv.sb_cc) { + if (stcb->sctp_socket->so_rcv.sb_ccc) { /* some to read, wake-up */ #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) struct socket *so; diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 62de260179ad..52ac81e92fb7 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -1032,7 +1032,7 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED, if (stcb->sctp_socket) { if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { - stcb->sctp_socket->so_snd.sb_cc = 0; + stcb->sctp_socket->so_snd.sb_ccc = 0; } sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED); } diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index 558d4e18357c..69ecf40655dd 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -399,7 +399,7 @@ typedef struct callout sctp_os_timer_t; #define SCTP_SOWAKEUP(so) wakeup(&(so)->so_timeo) /* clear the socket buffer state */ #define SCTP_SB_CLEAR(sb) \ - (sb).sb_cc = 0; \ + (sb).sb_ccc = 0; \ (sb).sb_mb = NULL; \ (sb).sb_mbcnt = 0; diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index a122325a28e6..3139be08091f 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -7250,7 +7250,7 @@ one_more_time: if ((stcb->sctp_socket != NULL) && \ ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { - atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_cc, sp->length); + atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_ccc, sp->length); } if (sp->data) { sctp_m_freem(sp->data); @@ -11532,7 +11532,7 @@ jump_out: drp->current_onq = htonl(asoc->size_on_reasm_queue + asoc->size_on_all_streams + asoc->my_rwnd_control_len + - stcb->sctp_socket->so_rcv.sb_cc); + stcb->sctp_socket->so_rcv.sb_ccc); } else { /*- * If my rwnd is 0, possibly from mbuf depletion as well as diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 2fa99b9e6243..72c3f042f7de 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -3397,7 +3397,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) if ((asoc->asoc.size_on_reasm_queue > 0) || (asoc->asoc.control_pdapi) || (asoc->asoc.size_on_all_streams > 0) || - (so && (so->so_rcv.sb_cc > 0))) { + (so && (so->so_rcv.sb_ccc > 0))) { /* Left with Data unread */ struct mbuf *op_err; @@ -3625,7 +3625,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) TAILQ_REMOVE(&inp->read_queue, sq, next); sctp_free_remote_addr(sq->whoFrom); if (so) - so->so_rcv.sb_cc -= sq->length; + so->so_rcv.sb_ccc -= sq->length; if (sq->data) { sctp_m_freem(sq->data); sq->data = NULL; @@ -4853,7 +4853,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre inp->sctp_flags |= SCTP_PCB_FLAGS_WAS_CONNECTED; if (so) { SOCK_LOCK(so); - if (so->so_rcv.sb_cc == 0) { + if (so->so_rcv.sb_ccc == 0) { so->so_state &= ~(SS_ISCONNECTING | SS_ISDISCONNECTING | SS_ISCONFIRMING | diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h index c9183b1d8207..25416283f916 100644 --- a/sys/netinet/sctp_pcb.h +++ b/sys/netinet/sctp_pcb.h @@ -369,7 +369,7 @@ struct sctp_inpcb { } ip_inp; - /* Socket buffer lock protects read_queue and of course sb_cc */ + /* Socket buffer lock protects read_queue and of course sb_ccc */ struct sctp_readhead read_queue; LIST_ENTRY(sctp_inpcb) sctp_list; /* lists all endpoints */ diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index 3f6d935ba173..127068145525 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -990,7 +990,7 @@ struct sctp_association { uint32_t total_output_queue_size; - uint32_t sb_cc; /* shadow of sb_cc */ + uint32_t sb_ccc; /* shadow of sb_ccc */ uint32_t sb_send_resv; /* amount reserved on a send */ uint32_t my_rwnd_control_len; /* shadow of sb_mbcnt used for rwnd * control */ diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index e1ad178135e0..9dc7cdced64a 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -586,7 +586,7 @@ sctp_must_try_again: if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) || - (so->so_rcv.sb_cc > 0)) { + (so->so_rcv.sb_ccc > 0)) { #ifdef SCTP_LOG_CLOSING sctp_log_closing(inp, NULL, 13); #endif @@ -751,7 +751,7 @@ sctp_disconnect(struct socket *so) } if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) || - (so->so_rcv.sb_cc > 0)) { + (so->so_rcv.sb_ccc > 0)) { if (SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT) { /* Left with Data unread */ @@ -916,7 +916,7 @@ sctp_flush(struct socket *so, int how) inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_CANT_READ; SCTP_INP_READ_UNLOCK(inp); SCTP_INP_WUNLOCK(inp); - so->so_rcv.sb_cc = 0; + so->so_rcv.sb_ccc = 0; so->so_rcv.sb_mbcnt = 0; so->so_rcv.sb_mb = NULL; } @@ -925,7 +925,7 @@ sctp_flush(struct socket *so, int how) * First make sure the sb will be happy, we don't use these * except maybe the count */ - so->so_snd.sb_cc = 0; + so->so_snd.sb_ccc = 0; so->so_snd.sb_mbcnt = 0; so->so_snd.sb_mb = NULL; diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h index 31d93dd21bd9..bab8a7709dd5 100644 --- a/sys/netinet/sctp_var.h +++ b/sys/netinet/sctp_var.h @@ -82,9 +82,9 @@ extern struct pr_usrreqs sctp_usrreqs; #define sctp_maxspace(sb) (max((sb)->sb_hiwat,SCTP_MINIMAL_RWND)) -#define sctp_sbspace(asoc, sb) ((long) ((sctp_maxspace(sb) > (asoc)->sb_cc) ? (sctp_maxspace(sb) - (asoc)->sb_cc) : 0)) +#define sctp_sbspace(asoc, sb) ((long) ((sctp_maxspace(sb) > (asoc)->sb_ccc) ? (sctp_maxspace(sb) - (asoc)->sb_ccc) : 0)) -#define sctp_sbspace_failedmsgs(sb) ((long) ((sctp_maxspace(sb) > (sb)->sb_cc) ? (sctp_maxspace(sb) - (sb)->sb_cc) : 0)) +#define sctp_sbspace_failedmsgs(sb) ((long) ((sctp_maxspace(sb) > (sb)->sb_ccc) ? (sctp_maxspace(sb) - (sb)->sb_ccc) : 0)) #define sctp_sbspace_sub(a,b) ((a > b) ? (a - b) : 0) @@ -195,10 +195,10 @@ extern struct pr_usrreqs sctp_usrreqs; } #define sctp_sbfree(ctl, stcb, sb, m) { \ - SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, SCTP_BUF_LEN((m))); \ + SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_ccc, SCTP_BUF_LEN((m))); \ SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_mbcnt, MSIZE); \ if (((ctl)->do_not_ref_stcb == 0) && stcb) {\ - SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.sb_cc, SCTP_BUF_LEN((m))); \ + SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.sb_ccc, SCTP_BUF_LEN((m))); \ SCTP_SAVE_ATOMIC_DECREMENT(&(stcb)->asoc.my_rwnd_control_len, MSIZE); \ } \ if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \ @@ -207,10 +207,10 @@ extern struct pr_usrreqs sctp_usrreqs; } #define sctp_sballoc(stcb, sb, m) { \ - atomic_add_int(&(sb)->sb_cc,SCTP_BUF_LEN((m))); \ + atomic_add_int(&(sb)->sb_ccc,SCTP_BUF_LEN((m))); \ atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \ if (stcb) { \ - atomic_add_int(&(stcb)->asoc.sb_cc,SCTP_BUF_LEN((m))); \ + atomic_add_int(&(stcb)->asoc.sb_ccc,SCTP_BUF_LEN((m))); \ atomic_add_int(&(stcb)->asoc.my_rwnd_control_len, MSIZE); \ } \ if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \ diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 1e87a17b2cba..e0e0670d5a50 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -67,9 +67,9 @@ sctp_sblog(struct sockbuf *sb, struct sctp_tcb *stcb, int from, int incr) struct sctp_cwnd_log sctp_clog; sctp_clog.x.sb.stcb = stcb; - sctp_clog.x.sb.so_sbcc = sb->sb_cc; + sctp_clog.x.sb.so_sbcc = sb->sb_ccc; if (stcb) - sctp_clog.x.sb.stcb_sbcc = stcb->asoc.sb_cc; + sctp_clog.x.sb.stcb_sbcc = stcb->asoc.sb_ccc; else sctp_clog.x.sb.stcb_sbcc = 0; sctp_clog.x.sb.incr = incr; @@ -4363,7 +4363,7 @@ sctp_add_to_readq(struct sctp_inpcb *inp, { /* * Here we must place the control on the end of the socket read - * queue AND increment sb_cc so that select will work properly on + * queue AND increment sb_ccc so that select will work properly on * read. */ struct mbuf *m, *prev = NULL; @@ -4489,7 +4489,7 @@ sctp_append_to_readq(struct sctp_inpcb *inp, * the reassembly queue. * * If PDAPI this means we need to add m to the end of the data. - * Increase the length in the control AND increment the sb_cc. + * Increase the length in the control AND increment the sb_ccc. * Otherwise sb is NULL and all we need to do is put it at the end * of the mbuf chain. */ @@ -4701,10 +4701,10 @@ sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc, if (stcb->sctp_socket && (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) || ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)))) { - if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) { - stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size; + if (stcb->sctp_socket->so_snd.sb_ccc >= tp1->book_size) { + stcb->sctp_socket->so_snd.sb_ccc -= tp1->book_size; } else { - stcb->sctp_socket->so_snd.sb_cc = 0; + stcb->sctp_socket->so_snd.sb_ccc = 0; } } @@ -5254,11 +5254,11 @@ sctp_sorecvmsg(struct socket *so, in_eeor_mode = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RECV_RWND_LOGGING_ENABLE) { sctp_misc_ints(SCTP_SORECV_ENTER, - rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, uio->uio_resid); + rwnd_req, in_eeor_mode, so->so_rcv.sb_ccc, uio->uio_resid); } if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RECV_RWND_LOGGING_ENABLE) { sctp_misc_ints(SCTP_SORECV_ENTERPL, - rwnd_req, block_allowed, so->so_rcv.sb_cc, uio->uio_resid); + rwnd_req, block_allowed, so->so_rcv.sb_ccc, uio->uio_resid); } error = sblock(&so->so_rcv, (block_allowed ? SBL_WAIT : 0)); if (error) { @@ -5277,23 +5277,23 @@ restart_nosblocks: (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) { goto out; } - if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) && (so->so_rcv.sb_cc == 0)) { + if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) && (so->so_rcv.sb_ccc == 0)) { if (so->so_error) { error = so->so_error; if ((in_flags & MSG_PEEK) == 0) so->so_error = 0; goto out; } else { - if (so->so_rcv.sb_cc == 0) { + if (so->so_rcv.sb_ccc == 0) { /* indicate EOF */ error = 0; goto out; } } } - if ((so->so_rcv.sb_cc <= held_length) && block_allowed) { + if ((so->so_rcv.sb_ccc <= held_length) && block_allowed) { /* we need to wait for data */ - if ((so->so_rcv.sb_cc == 0) && + if ((so->so_rcv.sb_ccc == 0) && ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0) { @@ -5329,7 +5329,7 @@ restart_nosblocks: } held_length = 0; goto restart_nosblocks; - } else if (so->so_rcv.sb_cc == 0) { + } else if (so->so_rcv.sb_ccc == 0) { if (so->so_error) { error = so->so_error; if ((in_flags & MSG_PEEK) == 0) @@ -5386,11 +5386,11 @@ restart_nosblocks: SCTP_INP_READ_LOCK(inp); } control = TAILQ_FIRST(&inp->read_queue); - if ((control == NULL) && (so->so_rcv.sb_cc != 0)) { + if ((control == NULL) && (so->so_rcv.sb_ccc != 0)) { #ifdef INVARIANTS panic("Huh, its non zero and nothing on control?"); #endif - so->so_rcv.sb_cc = 0; + so->so_rcv.sb_ccc = 0; } SCTP_INP_READ_UNLOCK(inp); hold_rlock = 0; @@ -5511,11 +5511,11 @@ restart_nosblocks: } /* * if we reach here, not suitable replacement is available - * <or> fragment interleave is NOT on. So stuff the sb_cc + * <or> fragment interleave is NOT on. So stuff the sb_ccc * into the our held count, and its time to sleep again. */ - held_length = so->so_rcv.sb_cc; - control->held_length = so->so_rcv.sb_cc; + held_length = so->so_rcv.sb_ccc; + control->held_length = so->so_rcv.sb_ccc; goto restart; } /* Clear the held length since there is something to read */ @@ -5812,10 +5812,10 @@ get_more_data: if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { sctp_sblog(&so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, cp_len); } - atomic_subtract_int(&so->so_rcv.sb_cc, cp_len); + atomic_subtract_int(&so->so_rcv.sb_ccc, cp_len); if ((control->do_not_ref_stcb == 0) && stcb) { - atomic_subtract_int(&stcb->asoc.sb_cc, cp_len); + atomic_subtract_int(&stcb->asoc.sb_ccc, cp_len); } copied_so_far += cp_len; freed_so_far += cp_len; @@ -5960,7 +5960,7 @@ wait_some_more: (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))) { goto release; } - if (so->so_rcv.sb_cc <= control->held_length) { + if (so->so_rcv.sb_ccc <= control->held_length) { error = sbwait(&so->so_rcv); if (error) { goto release; @@ -5987,8 +5987,8 @@ wait_some_more: } goto done_with_control; } - if (so->so_rcv.sb_cc > held_length) { - control->held_length = so->so_rcv.sb_cc; + if (so->so_rcv.sb_ccc > held_length) { + control->held_length = so->so_rcv.sb_ccc; held_length = 0; } goto wait_some_more; @@ -6135,13 +6135,13 @@ out: freed_so_far, ((uio) ? (slen - uio->uio_resid) : slen), stcb->asoc.my_rwnd, - so->so_rcv.sb_cc); + so->so_rcv.sb_ccc); } else { sctp_misc_ints(SCTP_SORECV_DONE, freed_so_far, ((uio) ? (slen - uio->uio_resid) : slen), 0, - so->so_rcv.sb_cc); + so->so_rcv.sb_ccc); } } stage_left: diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h index 559daa3764fa..a9e72625c5e3 100644 --- a/sys/netinet/sctputil.h +++ b/sys/netinet/sctputil.h @@ -286,10 +286,10 @@ do { \ } \ if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \ (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \ - if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) { \ - atomic_subtract_int(&((stcb)->sctp_socket->so_snd.sb_cc), tp1->book_size); \ + if (stcb->sctp_socket->so_snd.sb_ccc >= tp1->book_size) { \ + atomic_subtract_int(&((stcb)->sctp_socket->so_snd.sb_ccc), tp1->book_size); \ } else { \ - stcb->sctp_socket->so_snd.sb_cc = 0; \ + stcb->sctp_socket->so_snd.sb_ccc = 0; \ } \ } \ } \ @@ -307,10 +307,10 @@ do { \ } \ if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \ (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \ - if (stcb->sctp_socket->so_snd.sb_cc >= sp->length) { \ - atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_cc,sp->length); \ + if (stcb->sctp_socket->so_snd.sb_ccc >= sp->length) { \ + atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_ccc,sp->length); \ } else { \ - stcb->sctp_socket->so_snd.sb_cc = 0; \ + stcb->sctp_socket->so_snd.sb_ccc = 0; \ } \ } \ } \ @@ -322,7 +322,7 @@ do { \ if ((stcb->sctp_socket != NULL) && \ ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \ (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \ - atomic_add_int(&stcb->sctp_socket->so_snd.sb_cc,sz); \ + atomic_add_int(&stcb->sctp_socket->so_snd.sb_ccc,sz); \ } \ } while (0) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 468f14210565..e19d05ee318c 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -884,12 +884,10 @@ findpcb: goto dropwithreset; } INP_WLOCK_ASSERT(inp); - if (!(inp->inp_flags & INP_HW_FLOWID) - && (m->m_flags & M_FLOWID) - && ((inp->inp_socket == NULL) - || !(inp->inp_socket->so_options & SO_ACCEPTCONN))) { - inp->inp_flags |= INP_HW_FLOWID; - inp->inp_flags &= ~INP_SW_FLOWID; + if ((inp->inp_flowtype == M_HASHTYPE_NONE) && + (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) && + ((inp->inp_socket == NULL) || + (inp->inp_socket->so_options & SO_ACCEPTCONN) == 0)) { inp->inp_flowid = m->m_pkthdr.flowid; inp->inp_flowtype = M_HASHTYPE_GET(m); } @@ -1855,7 +1853,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, newsize, so, NULL)) so->so_rcv.sb_flags &= ~SB_AUTOSIZE; m_adj(m, drop_hdrlen); /* delayed header drop */ - sbappendstream_locked(&so->so_rcv, m); + sbappendstream_locked(&so->so_rcv, m, 0); } /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); @@ -2882,7 +2880,7 @@ dodata: /* XXX */ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) m_freem(m); else - sbappendstream_locked(&so->so_rcv, m); + sbappendstream_locked(&so->so_rcv, m, 0); /* NB: sorwakeup_locked() does an implicit unlock. */ sorwakeup_locked(so); } else { diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index dffee00f9b18..17d9a79eb50d 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -262,7 +262,7 @@ present: m_freem(mq); else { mq->m_nextpkt = NULL; - sbappendstream_locked(&so->so_rcv, mq); + sbappendstream_locked(&so->so_rcv, mq, 0); wakeup = 1; } } diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 05c50769531b..c7570e2a26d7 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -713,9 +713,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) * If there's an mbuf and it has a flowid, then let's initialise the * inp with that particular flowid. */ - if (m != NULL && m->m_flags & M_FLOWID) { - inp->inp_flags |= INP_HW_FLOWID; - inp->inp_flags &= ~INP_SW_FLOWID; + if (m != NULL && M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) { inp->inp_flowid = m->m_pkthdr.flowid; inp->inp_flowtype = M_HASHTYPE_GET(m); } diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 2820ffba70ed..dee1c33186ab 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -821,7 +821,11 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m, if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { if (control) m_freem(control); - if (m) + /* + * In case of PRUS_NOTREADY, tcp_usr_ready() is responsible + * for freeing memory. + */ + if (m && (flags & PRUS_NOTREADY) == 0) m_freem(m); error = ECONNRESET; goto out; @@ -843,7 +847,7 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m, m_freem(control); /* empty control, just free it */ } if (!(flags & PRUS_OOB)) { - sbappendstream(&so->so_snd, m); + sbappendstream(&so->so_snd, m, flags); if (nam && tp->t_state < TCPS_SYN_SENT) { /* * Do implied connect if not yet connected, @@ -875,7 +879,8 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m, socantsendmore(so); tcp_usrclosed(tp); } - if (!(inp->inp_flags & INP_DROPPED)) { + if (!(inp->inp_flags & INP_DROPPED) && + !(flags & PRUS_NOTREADY)) { if (flags & PRUS_MORETOCOME) tp->t_flags |= TF_MORETOCOME; error = tcp_output(tp); @@ -901,7 +906,7 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m, * of data past the urgent section. * Otherwise, snd_up should be one lower. */ - sbappendstream_locked(&so->so_snd, m); + sbappendstream_locked(&so->so_snd, m, flags); SOCKBUF_UNLOCK(&so->so_snd); if (nam && tp->t_state < TCPS_SYN_SENT) { /* @@ -925,10 +930,12 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m, tp->snd_wnd = TTCP_CLIENT_SND_WND; tcp_mss(tp, -1); } - tp->snd_up = tp->snd_una + so->so_snd.sb_cc; - tp->t_flags |= TF_FORCEDATA; - error = tcp_output(tp); - tp->t_flags &= ~TF_FORCEDATA; + tp->snd_up = tp->snd_una + sbavail(&so->so_snd); + if (!(flags & PRUS_NOTREADY)) { + tp->t_flags |= TF_FORCEDATA; + error = tcp_output(tp); + tp->t_flags &= ~TF_FORCEDATA; + } } out: TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB : @@ -939,6 +946,33 @@ out: return (error); } +static int +tcp_usr_ready(struct socket *so, struct mbuf *m, int count) +{ + struct inpcb *inp; + struct tcpcb *tp; + int error; + + inp = sotoinpcb(so); + INP_WLOCK(inp); + if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { + INP_WUNLOCK(inp); + for (int i = 0; i < count; i++) + m = m_free(m); + return (ECONNRESET); + } + tp = intotcpcb(inp); + + SOCKBUF_LOCK(&so->so_snd); + error = sbready(&so->so_snd, m, count); + SOCKBUF_UNLOCK(&so->so_snd); + if (error == 0) + error = tcp_output(tp); + INP_WUNLOCK(inp); + + return (error); +} + /* * Abort the TCP. Drop the connection abruptly. */ @@ -1073,6 +1107,7 @@ struct pr_usrreqs tcp_usrreqs = { .pru_rcvd = tcp_usr_rcvd, .pru_rcvoob = tcp_usr_rcvoob, .pru_send = tcp_usr_send, + .pru_ready = tcp_usr_ready, .pru_shutdown = tcp_usr_shutdown, .pru_sockaddr = in_getsockaddr, .pru_sosetlabel = in_pcbsosetlabel, @@ -1095,6 +1130,7 @@ struct pr_usrreqs tcp6_usrreqs = { .pru_rcvd = tcp_usr_rcvd, .pru_rcvoob = tcp_usr_rcvoob, .pru_send = tcp_usr_send, + .pru_ready = tcp_usr_ready, .pru_shutdown = tcp_usr_shutdown, .pru_sockaddr = in6_mapped_sockaddr, .pru_sosetlabel = in_pcbsosetlabel, diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index c4ef9f07f708..5fd93b3bcff9 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1106,8 +1106,7 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, uint8_t pr; uint16_t cscov = 0; uint32_t flowid = 0; - int flowid_type = 0; - int use_flowid = 0; + uint8_t flowtype = M_HASHTYPE_NONE; /* * udp_output() may need to temporarily bind or connect the current @@ -1184,8 +1183,7 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, error = EINVAL; break; } - flowid_type = *(uint32_t *) CMSG_DATA(cm); - use_flowid = 1; + flowtype = *(uint32_t *) CMSG_DATA(cm); break; #ifdef RSS @@ -1451,10 +1449,9 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, * Once the UDP code decides to set a flowid some other way, * this allows the flowid to be overridden by userland. */ - if (use_flowid) { - m->m_flags |= M_FLOWID; + if (flowtype != M_HASHTYPE_NONE) { m->m_pkthdr.flowid = flowid; - M_HASHTYPE_SET(m, flowid_type); + M_HASHTYPE_SET(m, flowtype); #ifdef RSS } else { uint32_t hash_val, hash_type; @@ -1477,7 +1474,6 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, if (rss_proto_software_hash_v4(faddr, laddr, fport, lport, pr, &hash_val, &hash_type) == 0) { m->m_pkthdr.flowid = hash_val; - m->m_flags |= M_FLOWID; M_HASHTYPE_SET(m, hash_type); } #endif diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 2a7b9dcf40f5..3b61849d4187 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -1252,7 +1252,7 @@ in6_pcblookup_mbuf(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, * XXXRW: As above, that policy belongs in the pcbgroup code. */ if (in_pcbgroup_enabled(pcbinfo) && - !(M_HASHTYPE_TEST(m, M_HASHTYPE_NONE))) { + M_HASHTYPE_TEST(m, M_HASHTYPE_NONE) == 0) { pcbgroup = in6_pcbgroup_byhash(pcbinfo, M_HASHTYPE_GET(m), m->m_pkthdr.flowid); if (pcbgroup != NULL) diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 4245a9fdb9e0..74d7483aa947 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -267,10 +267,10 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, if (inp != NULL) { M_SETFIB(m, inp->inp_inc.inc_fibnum); - if (((flags & IP_NODEFAULTFLOWID) == 0) && - (inp->inp_flags & (INP_HW_FLOWID|INP_SW_FLOWID))) { + if ((flags & IP_NODEFAULTFLOWID) == 0) { + /* unconditionally set flowid */ m->m_pkthdr.flowid = inp->inp_flowid; - m->m_flags |= M_FLOWID; + M_HASHTYPE_SET(m, inp->inp_flowtype); } } diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 6c6f27a6e5d3..2b07b8e63fd9 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -843,7 +843,6 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6, */ #ifdef RSS m->m_pkthdr.flowid = rss_hash_ip6_2tuple(*faddr, *laddr); - m->m_flags |= M_FLOWID; M_HASHTYPE_SET(m, M_HASHTYPE_RSS_IPV6); #endif flags = 0; diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c index a6eba64e1622..2e91d8529434 100644 --- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c +++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c @@ -889,7 +889,7 @@ sdp_append(struct sdp_sock *ssk, struct sockbuf *sb, struct mbuf *mb, int cnt) m_adj(mb, SDP_HEAD_SIZE); n->m_pkthdr.len += mb->m_pkthdr.len; n->m_flags |= mb->m_flags & (M_PUSH | M_URG); - m_demote(mb, 1); + m_demote(mb, 1, 0); sbcompress(sb, mb, sb->sb_mbtail); return; } diff --git a/sys/ofed/drivers/net/mlx4/en_rx.c b/sys/ofed/drivers/net/mlx4/en_rx.c index 320462ec02ad..fa263266d67d 100644 --- a/sys/ofed/drivers/net/mlx4/en_rx.c +++ b/sys/ofed/drivers/net/mlx4/en_rx.c @@ -604,7 +604,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud } mb->m_pkthdr.flowid = cq->ring; - mb->m_flags |= M_FLOWID; + M_HASHTYPE_SET(mb, M_HASHTYPE_OPAQUE); mb->m_pkthdr.rcvif = dev; if (be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_VLAN_PRESENT_MASK) { diff --git a/sys/ofed/drivers/net/mlx4/en_tx.c b/sys/ofed/drivers/net/mlx4/en_tx.c index d1931558bcc9..d92677fa5ce3 100644 --- a/sys/ofed/drivers/net/mlx4/en_tx.c +++ b/sys/ofed/drivers/net/mlx4/en_tx.c @@ -720,8 +720,11 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct mbuf *mb) up = (vlan_tag >> 13); } - /* hash mbuf */ - queue_index = mlx4_en_hashmbuf(MLX4_F_HASHL3 | MLX4_F_HASHL4, mb, hashrandom); + /* check if flowid is set */ + if (M_HASHTYPE_GET(mb) != M_HASHTYPE_NONE) + queue_index = mb->m_pkthdr.flowid; + else + queue_index = mlx4_en_hashmbuf(MLX4_F_HASHL3 | MLX4_F_HASHL4, mb, hashrandom); return ((queue_index % rings_p_up) + (up * rings_p_up)); } @@ -1066,15 +1069,11 @@ mlx4_en_transmit(struct ifnet *dev, struct mbuf *m) struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_tx_ring *ring; struct mlx4_en_cq *cq; - int i = 0, err = 0; + int i, err = 0; + + /* Compute which queue to use */ + i = mlx4_en_select_queue(dev, m); - /* Which queue to use */ - if ((m->m_flags & (M_FLOWID | M_VLANTAG)) == M_FLOWID) { - i = m->m_pkthdr.flowid % (priv->tx_ring_num - 1); - } - else { - i = mlx4_en_select_queue(dev, m); - } ring = priv->tx_ring[i]; if (spin_trylock(&ring->tx_lock)) { diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index 5864a02c4694..d1413a2c4aba 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -757,6 +757,10 @@ db_trap_glue(struct trapframe *frame) || frame->exc == EXC_BPT || frame->exc == EXC_DSI)) { int type = frame->exc; + + /* Ignore DTrace traps. */ + if (*(uint32_t *)frame->srr0 == EXC_DTRACE) + return (0); if (type == EXC_PGM && (frame->srr1 & 0x20000)) { type = T_BREAKPOINT; } diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c index cc54e593c00f..8276e96f1936 100644 --- a/sys/powerpc/aim/trap.c +++ b/sys/powerpc/aim/trap.c @@ -258,7 +258,8 @@ trap(struct trapframe *frame) if (frame->srr1 & EXC_PGM_TRAP) { #ifdef KDTRACE_HOOKS inst = fuword32((const void *)frame->srr0); - if (inst == 0x0FFFDDDD && dtrace_pid_probe_ptr != NULL) { + if (inst == 0x0FFFDDDD && + dtrace_pid_probe_ptr != NULL) { struct reg regs; fill_regs(td, ®s); (*dtrace_pid_probe_ptr)(®s); @@ -301,7 +302,7 @@ trap(struct trapframe *frame) #ifdef KDTRACE_HOOKS case EXC_PGM: if (frame->srr1 & EXC_PGM_TRAP) { - if (*(uint32_t *)frame->srr0 == 0x7c810808) { + if (*(uint32_t *)frame->srr0 == EXC_DTRACE) { if (dtrace_invop_jump_addr != NULL) { dtrace_invop_jump_addr(frame); return; diff --git a/sys/powerpc/aim/trap_subr32.S b/sys/powerpc/aim/trap_subr32.S index 56ca7155ddd0..2aae2a00abbc 100644 --- a/sys/powerpc/aim/trap_subr32.S +++ b/sys/powerpc/aim/trap_subr32.S @@ -890,8 +890,7 @@ CNAME(dblow): mfcr %r29 /* save CR in r29 */ mfsrr1 %r1 mtcr %r1 - bf 17,2f /* branch if privileged */ -1: + bf 17,1f /* branch if privileged */ /* Unprivileged case */ mtcr %r29 /* put the condition register back */ mfsprg2 %r29 /* ... and r29 */ @@ -900,19 +899,7 @@ CNAME(dblow): li %r1, 0 /* How to get the vector from LR */ bla generictrap /* and we look like a generic trap */ -2: -#ifdef KDTRACE_HOOKS - /* Privileged, so drop to KDB */ - mfsrr0 %r1 - mtsprg3 %r3 - lwz %r1,0(%r1) - /* Check if it's a DTrace trap. */ - li %r3,0x0808 - addis %r3,%r3,0x7c81 - cmplw %cr0,%r3,%r1 - mfsprg3 %r3 - beq %cr0,1b -#endif +1: /* Privileged, so drop to KDB */ GET_CPUINFO(%r1) stw %r28,(PC_DBSAVE+CPUSAVE_R28)(%r1) /* free r28 */ diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S index bedf1f1962c4..0dc46b34e866 100644 --- a/sys/powerpc/aim/trap_subr64.S +++ b/sys/powerpc/aim/trap_subr64.S @@ -799,9 +799,8 @@ CNAME(dblow): mfcr %r29 /* save CR in r29 */ mfsrr1 %r1 mtcr %r1 - bf 17,2f /* branch if privileged */ + bf 17,1f /* branch if privileged */ -1: /* Unprivileged case */ mtcr %r29 /* put the condition register back */ mfsprg2 %r29 /* ... and r29 */ @@ -810,19 +809,7 @@ CNAME(dblow): li %r1, 0 /* How to get the vector from LR */ bla generictrap /* and we look like a generic trap */ -2: -#ifdef KDTRACE_HOOKS - /* Privileged, so drop to KDB */ - mfsrr0 %r1 - mtsprg3 %r3 - lwz %r1,0(%r1) - /* Check if it's a DTrace trap. */ - li %r3,0x0808 - addis %r3,%r3,0x7c81 - cmplw %cr0,%r3,%r1 - mfsprg3 %r3 - beq %cr0,1b -#endif +1: GET_CPUINFO(%r1) std %r27,(PC_DBSAVE+CPUSAVE_R27)(%r1) /* free r27 */ std %r28,(PC_DBSAVE+CPUSAVE_R28)(%r1) /* free r28 */ diff --git a/sys/powerpc/include/trap.h b/sys/powerpc/include/trap.h index 89f596659cfb..211afcf78225 100644 --- a/sys/powerpc/include/trap.h +++ b/sys/powerpc/include/trap.h @@ -120,6 +120,9 @@ #define EXC_PGM_PRIV (1UL << 18) #define EXC_PGM_TRAP (1UL << 17) +/* DTrace trap opcode. */ +#define EXC_DTRACE 0x7c810808 + #ifndef LOCORE struct trapframe; struct pcb; diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 190900c43d22..ac3cfb2d0ced 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -950,7 +950,7 @@ struct mbuf *m_copypacket(struct mbuf *, int); void m_copy_pkthdr(struct mbuf *, struct mbuf *); struct mbuf *m_copyup(struct mbuf *, int, int); struct mbuf *m_defrag(struct mbuf *, int); -void m_demote(struct mbuf *, int); +void m_demote(struct mbuf *, int, int); struct mbuf *m_devget(char *, int, int, struct ifnet *, void (*)(char *, caddr_t, u_int)); struct mbuf *m_dup(struct mbuf *, int); diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index 2d98a4c25edd..55db0e339699 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -208,6 +208,8 @@ struct pr_usrreqs { #define PRUS_OOB 0x1 #define PRUS_EOF 0x2 #define PRUS_MORETOCOME 0x4 +#define PRUS_NOTREADY 0x8 + int (*pru_ready)(struct socket *so, struct mbuf *m, int count); int (*pru_sense)(struct socket *so, struct stat *sb); int (*pru_shutdown)(struct socket *so); int (*pru_flush)(struct socket *so, int direction); @@ -251,6 +253,7 @@ int pru_rcvd_notsupp(struct socket *so, int flags); int pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags); int pru_send_notsupp(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, struct mbuf *control, struct thread *td); +int pru_ready_notsupp(struct socket *so, struct mbuf *m, int count); int pru_sense_null(struct socket *so, struct stat *sb); int pru_shutdown_notsupp(struct socket *so); int pru_sockaddr_notsupp(struct socket *so, struct sockaddr **nam); diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h index f9e8da4cde0b..5bd9bb556251 100644 --- a/sys/sys/sockbuf.h +++ b/sys/sys/sockbuf.h @@ -89,8 +89,10 @@ struct sockbuf { struct mbuf *sb_lastrecord; /* (c/d) first mbuf of last * record in socket buffer */ struct mbuf *sb_sndptr; /* (c/d) pointer into mbuf chain */ + struct mbuf *sb_fnrdy; /* (c/d) pointer to first not ready buffer */ u_int sb_sndptroff; /* (c/d) byte offset of ptr into chain */ - u_int sb_cc; /* (c/d) actual chars in buffer */ + u_int sb_acc; /* (c/d) available chars in buffer */ + u_int sb_ccc; /* (c/d) claimed chars in buffer */ u_int sb_hiwat; /* (c/d) max actual char count */ u_int sb_mbcnt; /* (c/d) chars of mbufs used */ u_int sb_mcnt; /* (c/d) number of mbufs in buffer */ @@ -120,10 +122,17 @@ struct sockbuf { #define SOCKBUF_LOCK_ASSERT(_sb) mtx_assert(SOCKBUF_MTX(_sb), MA_OWNED) #define SOCKBUF_UNLOCK_ASSERT(_sb) mtx_assert(SOCKBUF_MTX(_sb), MA_NOTOWNED) +/* + * Socket buffer private mbuf(9) flags. + */ +#define M_NOTREADY M_PROTO1 /* m_data not populated yet */ +#define M_BLOCKED M_PROTO2 /* M_NOTREADY in front of m */ +#define M_NOTAVAIL (M_NOTREADY | M_BLOCKED) + void sbappend(struct sockbuf *sb, struct mbuf *m); void sbappend_locked(struct sockbuf *sb, struct mbuf *m); -void sbappendstream(struct sockbuf *sb, struct mbuf *m); -void sbappendstream_locked(struct sockbuf *sb, struct mbuf *m); +void sbappendstream(struct sockbuf *sb, struct mbuf *m, int flags); +void sbappendstream_locked(struct sockbuf *sb, struct mbuf *m, int flags); int sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa, struct mbuf *m0, struct mbuf *control); int sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa, @@ -136,7 +145,6 @@ int sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control); void sbappendrecord(struct sockbuf *sb, struct mbuf *m0); void sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0); -void sbcheck(struct sockbuf *sb); void sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n); struct mbuf * sbcreatecontrol(caddr_t p, int size, int type, int level); @@ -164,10 +172,13 @@ void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb); int sbwait(struct sockbuf *sb); int sblock(struct sockbuf *sb, int flags); void sbunlock(struct sockbuf *sb); +void sballoc(struct sockbuf *, struct mbuf *); +void sbfree(struct sockbuf *, struct mbuf *); +int sbready(struct sockbuf *, struct mbuf *, int); /* * Return how much data is available to be taken out of socket - * bufffer right now. + * buffer right now. */ static inline u_int sbavail(struct sockbuf *sb) @@ -176,7 +187,7 @@ sbavail(struct sockbuf *sb) #if 0 SOCKBUF_LOCK_ASSERT(sb); #endif - return (sb->sb_cc); + return (sb->sb_acc); } /* @@ -190,59 +201,30 @@ sbused(struct sockbuf *sb) #if 0 SOCKBUF_LOCK_ASSERT(sb); #endif - return (sb->sb_cc); + return (sb->sb_ccc); } /* * How much space is there in a socket buffer (so->so_snd or so->so_rcv)? * This is problematical if the fields are unsigned, as the space might - * still be negative (cc > hiwat or mbcnt > mbmax). Should detect - * overflow and return 0. Should use "lmin" but it doesn't exist now. + * still be negative (ccc > hiwat or mbcnt > mbmax). */ -static __inline -long +static inline long sbspace(struct sockbuf *sb) { - long bleft; - long mleft; + long bleft, mleft; + +#if 0 + SOCKBUF_LOCK_ASSERT(sb); +#endif if (sb->sb_flags & SB_STOP) return(0); - bleft = sb->sb_hiwat - sb->sb_cc; + + bleft = sb->sb_hiwat - sb->sb_ccc; mleft = sb->sb_mbmax - sb->sb_mbcnt; - return((bleft < mleft) ? bleft : mleft); -} -/* adjust counters in sb reflecting allocation of m */ -#define sballoc(sb, m) { \ - (sb)->sb_cc += (m)->m_len; \ - if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \ - (sb)->sb_ctl += (m)->m_len; \ - (sb)->sb_mbcnt += MSIZE; \ - (sb)->sb_mcnt += 1; \ - if ((m)->m_flags & M_EXT) { \ - (sb)->sb_mbcnt += (m)->m_ext.ext_size; \ - (sb)->sb_ccnt += 1; \ - } \ -} - -/* adjust counters in sb reflecting freeing of m */ -#define sbfree(sb, m) { \ - (sb)->sb_cc -= (m)->m_len; \ - if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \ - (sb)->sb_ctl -= (m)->m_len; \ - (sb)->sb_mbcnt -= MSIZE; \ - (sb)->sb_mcnt -= 1; \ - if ((m)->m_flags & M_EXT) { \ - (sb)->sb_mbcnt -= (m)->m_ext.ext_size; \ - (sb)->sb_ccnt -= 1; \ - } \ - if ((sb)->sb_sndptr == (m)) { \ - (sb)->sb_sndptr = NULL; \ - (sb)->sb_sndptroff = 0; \ - } \ - if ((sb)->sb_sndptroff != 0) \ - (sb)->sb_sndptroff -= (m)->m_len; \ + return ((bleft < mleft) ? bleft : mleft); } #define SB_EMPTY_FIXUP(sb) do { \ @@ -254,13 +236,15 @@ sbspace(struct sockbuf *sb) #ifdef SOCKBUF_DEBUG void sblastrecordchk(struct sockbuf *, const char *, int); -#define SBLASTRECORDCHK(sb) sblastrecordchk((sb), __FILE__, __LINE__) - void sblastmbufchk(struct sockbuf *, const char *, int); +void sbcheck(struct sockbuf *, const char *, int); +#define SBLASTRECORDCHK(sb) sblastrecordchk((sb), __FILE__, __LINE__) #define SBLASTMBUFCHK(sb) sblastmbufchk((sb), __FILE__, __LINE__) +#define SBCHECK(sb) sbcheck((sb), __FILE__, __LINE__) #else -#define SBLASTRECORDCHK(sb) /* nothing */ -#define SBLASTMBUFCHK(sb) /* nothing */ +#define SBLASTRECORDCHK(sb) do {} while (0) +#define SBLASTMBUFCHK(sb) do {} while (0) +#define SBCHECK(sb) do {} while (0) #endif /* SOCKBUF_DEBUG */ #endif /* _KERNEL */ diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 50e66c058268..574eba073f54 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -146,6 +146,8 @@ static LIST_HEAD(,uma_slab) uma_boot_pages = /* This mutex protects the boot time pages list */ static struct mtx_padalign uma_boot_pages_mtx; +static struct sx uma_drain_lock; + /* Is the VM done starting up? */ static int booted = 0; #define UMA_STARTUP 1 @@ -1876,6 +1878,7 @@ uma_startup2(void) { booted = UMA_STARTUP2; bucket_enable(); + sx_init(&uma_drain_lock, "umadrain"); #ifdef UMA_DEBUG printf("UMA startup2 complete.\n"); #endif @@ -1930,6 +1933,8 @@ uma_zcreate(const char *name, size_t size, uma_ctor ctor, uma_dtor dtor, { struct uma_zctor_args args; + uma_zone_t res; + bool locked; /* This stuff is essential for the zone ctor */ memset(&args, 0, sizeof(args)); @@ -1943,7 +1948,16 @@ uma_zcreate(const char *name, size_t size, uma_ctor ctor, uma_dtor dtor, args.flags = flags; args.keg = NULL; - return (zone_alloc_item(zones, &args, M_WAITOK)); + if (booted < UMA_STARTUP2) { + locked = false; + } else { + sx_slock(&uma_drain_lock); + locked = true; + } + res = zone_alloc_item(zones, &args, M_WAITOK); + if (locked) + sx_sunlock(&uma_drain_lock); + return (res); } /* See uma.h */ @@ -1953,6 +1967,8 @@ uma_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor, { struct uma_zctor_args args; uma_keg_t keg; + uma_zone_t res; + bool locked; keg = zone_first_keg(master); memset(&args, 0, sizeof(args)); @@ -1966,8 +1982,17 @@ uma_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor, args.flags = keg->uk_flags | UMA_ZONE_SECONDARY; args.keg = keg; + if (booted < UMA_STARTUP2) { + locked = false; + } else { + sx_slock(&uma_drain_lock); + locked = true; + } /* XXX Attaches only one keg of potentially many. */ - return (zone_alloc_item(zones, &args, M_WAITOK)); + res = zone_alloc_item(zones, &args, M_WAITOK); + if (locked) + sx_sunlock(&uma_drain_lock); + return (res); } /* See uma.h */ @@ -2085,7 +2110,9 @@ void uma_zdestroy(uma_zone_t zone) { + sx_slock(&uma_drain_lock); zone_free_item(zones, zone, NULL, SKIP_NONE); + sx_sunlock(&uma_drain_lock); } /* See uma.h */ @@ -3205,6 +3232,7 @@ uma_reclaim(void) #ifdef UMA_DEBUG printf("UMA: vm asked us to release pages!\n"); #endif + sx_xlock(&uma_drain_lock); bucket_enable(); zone_foreach(zone_drain); if (vm_page_count_min()) { @@ -3219,6 +3247,7 @@ uma_reclaim(void) zone_drain(slabzone); zone_drain(slabrefzone); bucket_zone_drain(); + sx_xunlock(&uma_drain_lock); } /* See uma.h */ diff --git a/tools/tools/shlib-compat/shlib-compat.py b/tools/tools/shlib-compat/shlib-compat.py index 726c53ffb967..ca6f036639d1 100755 --- a/tools/tools/shlib-compat/shlib-compat.py +++ b/tools/tools/shlib-compat/shlib-compat.py @@ -60,6 +60,14 @@ class Config(object): origfile = FileConfig() newfile = FileConfig() + exclude_sym_default = [ + '^__bss_start$', + '^_edata$', + '^_end$', + '^_fini$', + '^_init$', + ] + @classmethod def init(cls): cls.version_filter = StrFilter() @@ -338,15 +346,17 @@ class BaseTypeDef(Def): def _pp(self, pp): if self.encoding in self.inttypes: sign = '' if self.encoding == 'DW_ATE_signed' else 'u' - bits = int(self.byte_size) * 8 + bits = int(self.byte_size, 0) * 8 return '%sint%s_t' % (sign, bits) - elif self.encoding == 'DW_ATE_signed_char' and int(self.byte_size) == 1: + elif self.encoding == 'DW_ATE_signed_char' and int(self.byte_size, 0) == 1: return 'char'; + elif self.encoding == 'DW_ATE_boolean' and int(self.byte_size, 0) == 1: + return 'bool'; elif self.encoding == 'DW_ATE_float': - return self._mapval(self.byte_size, { - '16': 'long double', - '8': 'double', - '4': 'float', + return self._mapval(int(self.byte_size, 0), { + 16: 'long double', + 8: 'double', + 4: 'float', }) raise NotImplementedError('Invalid encoding: %s' % self) @@ -374,6 +384,11 @@ class VolatileTypeDef(AnonymousDef): def _pp(self, pp): return 'volatile ' + self.type._pp(pp) +class RestrictTypeDef(AnonymousDef): + _is_alias = True + def _pp(self, pp): + return 'restrict ' + self.type._pp(pp) + class ArrayDef(AnonymousDef): def _pp(self, pp): t = pp.run(self.type) @@ -411,6 +426,11 @@ class ParameterDef(Def): t = pp.run(self.type) return "%s %s" % (t, self._name_opt()) +class VariableDef(Def): + def _pp(self, pp): + t = pp.run(self.type) + return "%s %s" % (t, self._name_opt()) + # TODO class StructForwardDef(Def): pass @@ -485,6 +505,10 @@ class Dwarf(object): result = self._build_optarg_type(raw) return FunctionDef(raw.id, raw.name, params=params, result=result) + def build_variable(self, raw): + type = self._build_optarg_type(raw) + return VariableDef(raw.id, raw.optname, type=type) + def build_subroutine_type(self, raw): params = [ self.build(x) for x in raw.nested ] result = self._build_optarg_type(raw) @@ -547,6 +571,10 @@ class Dwarf(object): type = self._build_optarg_type(raw) return VolatileTypeDef(raw.id, type=type) + def build_restrict_type(self, raw): + type = self._build_optarg_type(raw) + return RestrictTypeDef(raw.id, type=type) + def build_enumeration_type(self, raw): # TODO handle DW_TAG_enumerator ??? return EnumerationTypeDef(raw.id, name=raw.optname, @@ -574,7 +602,7 @@ class Dwarf(object): return int(id) except ValueError: if (id.startswith('<') and id.endswith('>')): - return int(id[1:-1]) + return int(id[1:-1], 0) else: raise ValueError("Invalid dwarf id: %s" % id) @@ -782,7 +810,7 @@ class DwarfdumpParser(Parser): class Tag(object): def __init__(self, unit, data): self.unit = unit - self.id = int(data['id']) + self.id = int(data['id'], 0) self.level = int(data['level']) self.tag = data['tag'] self.args = {} @@ -816,7 +844,7 @@ class DwarfdumpParser(Parser): def __repr__(self): return "Tag(%d, %d, %s)" % (self.level, self.id, self.tag) - re_header = re.compile('<(?P<level>\d+)><(?P<id>\d+\+*\d*)><(?P<tag>\w+)>') + re_header = re.compile('<(?P<level>\d+)><(?P<id>[0xX0-9a-fA-F]+(?:\+(0[xX])?[0-9a-fA-F]+)?)><(?P<tag>\w+)>') re_argname = re.compile('(?P<arg>\w+)<') re_argunknown = re.compile('<Unknown AT value \w+><[^<>]+>') @@ -827,6 +855,10 @@ class DwarfdumpParser(Parser): 'DW_TAG_variable', ]) + external_tags = set([ + 'DW_TAG_variable', + ]) + def __init__(self, libfile): Parser.__init__(self, "%s -di %s" % (Config.dwarfdump, libfile)) self.current_unit = None @@ -888,9 +920,19 @@ class DwarfdumpParser(Parser): while args: args = self.parse_arg(tag, args) tag.unit.tags[tag.id] = tag - if tag.args.has_key('DW_AT_low_pc') and \ - tag.tag not in DwarfdumpParser.skip_tags: - offset = int(tag.args['DW_AT_low_pc'], 16) + def parse_offset(tag): + if tag.args.has_key('DW_AT_low_pc'): + return int(tag.args['DW_AT_low_pc'], 16) + elif tag.args.has_key('DW_AT_location'): + location = tag.args['DW_AT_location'] + if location.startswith('DW_OP_addr'): + return int(location.replace('DW_OP_addr', ''), 16) + return None + offset = parse_offset(tag) + if offset is not None and \ + (tag.tag not in DwarfdumpParser.skip_tags or \ + (tag.args.has_key('DW_AT_external') and \ + tag.tag in DwarfdumpParser.external_tags)): if self.offsetmap.has_key(offset): raise ValueError("Dwarf dump parse error: " + "symbol is aleady defined at offset 0x%x" % offset) @@ -963,10 +1005,15 @@ def cmp_symbols(commonver): names.sort() for symname in names: sym = ver.symbols[symname] - match = sym.origsym.definition == sym.newsym.definition + missing = sym.origsym.definition is None or sym.newsym.definition is None + match = not missing and sym.origsym.definition == sym.newsym.definition if not match: App.result_code = 1 if Config.verbose >= 1 or not match: + if missing: + print '%s: missing definition' % \ + (sym.origsym.name_ver,) + continue print '%s: definitions %smatch' % \ (sym.origsym.name_ver, "" if match else "mis") if Config.dump or (not match and not Config.no_dump): @@ -1035,10 +1082,16 @@ if __name__ == '__main__': help="result output file for original library", metavar="ORIGFILE") parser.add_option('--out-new', action='store', help="result output file for new library", metavar="NEWFILE") + parser.add_option('--dwarfdump', action='store', + help="path to dwarfdump executable", metavar="DWARFDUMP") + parser.add_option('--objdump', action='store', + help="path to objdump executable", metavar="OBJDUMP") parser.add_option('--exclude-ver', action='append', metavar="RE") parser.add_option('--include-ver', action='append', metavar="RE") parser.add_option('--exclude-sym', action='append', metavar="RE") parser.add_option('--include-sym', action='append', metavar="RE") + parser.add_option('--no-exclude-sym-default', action='store_true', + help="don't exclude special symbols like _init, _end, __bss_start") for opt in ['alias', 'cached', 'symbol']: parser.add_option("--w-" + opt, action="store_true", dest="w_" + opt) @@ -1049,6 +1102,10 @@ if __name__ == '__main__': if len(args) != 2: parser.print_help() sys.exit(-1) + if opts.dwarfdump: + Config.dwarfdump = opts.dwarfdump + if opts.objdump: + Config.objdump = opts.objdump if opts.out_orig: Config.origfile.init(opts.out_orig) if opts.out_new: @@ -1071,6 +1128,8 @@ if __name__ == '__main__': opt = getattr(opts, a + k) if opt: getattr(v, a).extend(opt) + if not opts.no_exclude_sym_default: + Config.symbol_filter.exclude.extend(Config.exclude_sym_default) Config.version_filter.compile() Config.symbol_filter.compile() for w in ['w_alias', 'w_cached', 'w_symbol']: diff --git a/tools/tools/shlib-compat/test/Makefile.inc b/tools/tools/shlib-compat/test/Makefile.inc index 14aaef6ea956..e1a0719a89f4 100644 --- a/tools/tools/shlib-compat/test/Makefile.inc +++ b/tools/tools/shlib-compat/test/Makefile.inc @@ -11,3 +11,5 @@ DEBUG_FLAGS?= -g VERSION_DEF= ${.CURDIR}/../Versions.def SYMBOL_MAPS= ${.CURDIR}/Symbol.map + +MK_DEBUG_FILES= yes diff --git a/tools/tools/shlib-compat/test/regress.sh b/tools/tools/shlib-compat/test/regress.sh index e113cce87b63..0789fa8b3cf7 100755 --- a/tools/tools/shlib-compat/test/regress.sh +++ b/tools/tools/shlib-compat/test/regress.sh @@ -1,7 +1,7 @@ #!/bin/sh # $FreeBSD$ -run() { ../shlib-compat.py --no-dump -vv libtest$1/libtest$1.so.0.debug libtest$2/libtest$2.so.0.debug; } +run() { ../shlib-compat.py --no-dump -vv libtest$1/libtest$1.so.0.full libtest$2/libtest$2.so.0.full; } echo 1..9 REGRESSION_START($1) REGRESSION_TEST(`1-1', `run 1 1') diff --git a/tools/tools/sysbuild/sysbuild.sh b/tools/tools/sysbuild/sysbuild.sh index 1a32c60e027e..bb22a697453a 100644 --- a/tools/tools/sysbuild/sysbuild.sh +++ b/tools/tools/sysbuild/sysbuild.sh @@ -226,8 +226,7 @@ ports_build() ( t=`echo $p | sed 's,/usr/ports/,,'` pn=`cd $p && make package-name` - if [ "x$p" == "x/usr/ports/ports-mgmt/pkg" -o \ - "x$p" == "x/freebsd/ports/ports-mgmt/pkg" ] ; then + if [ "x`basename $p`" == "xpkg" ] ; then log_it "Very Special: $t ($pn)" ( diff --git a/usr.bin/bluetooth/btsockstat/btsockstat.c b/usr.bin/bluetooth/btsockstat/btsockstat.c index f63ee1fe5f7a..20f4de8076c8 100644 --- a/usr.bin/bluetooth/btsockstat/btsockstat.c +++ b/usr.bin/bluetooth/btsockstat/btsockstat.c @@ -255,8 +255,8 @@ hcirawpr(kvm_t *kvmd, u_long addr) (unsigned long) pcb.so, (unsigned long) this, pcb.flags, - so.so_rcv.sb_cc, - so.so_snd.sb_cc, + so.so_rcv.sb_ccc, + so.so_snd.sb_ccc, pcb.addr.hci_node); } } /* hcirawpr */ @@ -303,8 +303,8 @@ l2caprawpr(kvm_t *kvmd, u_long addr) "%-8lx %-8lx %6d %6d %-17.17s\n", (unsigned long) pcb.so, (unsigned long) this, - so.so_rcv.sb_cc, - so.so_snd.sb_cc, + so.so_rcv.sb_ccc, + so.so_snd.sb_ccc, bdaddrpr(&pcb.src, NULL, 0)); } } /* l2caprawpr */ @@ -361,8 +361,8 @@ l2cappr(kvm_t *kvmd, u_long addr) fprintf(stdout, "%-8lx %6d %6d %-17.17s/%-5d %-17.17s %-5d %s\n", (unsigned long) this, - so.so_rcv.sb_cc, - so.so_snd.sb_cc, + so.so_rcv.sb_ccc, + so.so_snd.sb_ccc, bdaddrpr(&pcb.src, local, sizeof(local)), pcb.psm, bdaddrpr(&pcb.dst, remote, sizeof(remote)), @@ -467,8 +467,8 @@ rfcommpr(kvm_t *kvmd, u_long addr) fprintf(stdout, "%-8lx %6d %6d %-17.17s %-17.17s %-4d %-4d %s\n", (unsigned long) this, - so.so_rcv.sb_cc, - so.so_snd.sb_cc, + so.so_rcv.sb_ccc, + so.so_snd.sb_ccc, bdaddrpr(&pcb.src, local, sizeof(local)), bdaddrpr(&pcb.dst, remote, sizeof(remote)), pcb.channel, diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index 10d0698e6beb..c22e49f62405 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -137,7 +137,7 @@ pcblist_sysctl(int proto, const char *name, char **bufp, int istcp __unused) static void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb) { - xsb->sb_cc = sb->sb_cc; + xsb->sb_cc = sb->sb_ccc; xsb->sb_hiwat = sb->sb_hiwat; xsb->sb_mbcnt = sb->sb_mbcnt; xsb->sb_mcnt = sb->sb_mcnt; @@ -479,7 +479,8 @@ protopr(u_long off, const char *name, int af1, int proto) printf("%6u %6u %6u ", tp->t_sndrexmitpack, tp->t_rcvoopack, tp->t_sndzerowin); } else { - printf("%6u %6u ", so->so_rcv.sb_cc, so->so_snd.sb_cc); + printf("%6u %6u ", + so->so_rcv.sb_cc, so->so_snd.sb_cc); } if (numeric_port) { if (inp->inp_vflag & INP_IPV4) { diff --git a/usr.bin/netstat/netgraph.c b/usr.bin/netstat/netgraph.c index 95578af739fa..9a08b6d282c8 100644 --- a/usr.bin/netstat/netgraph.c +++ b/usr.bin/netstat/netgraph.c @@ -119,7 +119,7 @@ netgraphprotopr(u_long off, const char *name, int af1 __unused, if (Aflag) printf("%8lx ", (u_long) this); printf("%-5.5s %6u %6u ", - name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); + name, sockb.so_rcv.sb_ccc, sockb.so_snd.sb_ccc); /* Get info on associated node */ if (ngpcb.node_id == 0 || csock == -1) diff --git a/usr.bin/netstat/unix.c b/usr.bin/netstat/unix.c index 027e812cf7cd..a5cc037840be 100644 --- a/usr.bin/netstat/unix.c +++ b/usr.bin/netstat/unix.c @@ -287,7 +287,8 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so) } else { printf("%8lx %-6.6s %6u %6u %8lx %8lx %8lx %8lx", (long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc, - so->so_snd.sb_cc, (long)unp->unp_vnode, (long)unp->unp_conn, + so->so_snd.sb_cc, (long)unp->unp_vnode, + (long)unp->unp_conn, (long)LIST_FIRST(&unp->unp_refs), (long)LIST_NEXT(unp, unp_reflink)); } diff --git a/usr.bin/systat/netstat.c b/usr.bin/systat/netstat.c index bb1318da37c8..b5938eb9d911 100644 --- a/usr.bin/systat/netstat.c +++ b/usr.bin/systat/netstat.c @@ -333,8 +333,8 @@ enter_kvm(struct inpcb *inp, struct socket *so, int state, const char *proto) struct netinfo *p; if ((p = enter(inp, state, proto)) != NULL) { - p->ni_rcvcc = so->so_rcv.sb_cc; - p->ni_sndcc = so->so_snd.sb_cc; + p->ni_rcvcc = so->so_rcv.sb_ccc; + p->ni_sndcc = so->so_snd.sb_ccc; } }