summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorngie <ngie@FreeBSD.org>2015-12-10 07:38:56 +0000
committerngie <ngie@FreeBSD.org>2015-12-10 07:38:56 +0000
commitc85e616e29482200cd0a47fa6c85165a98a4caaf (patch)
tree968c93f62ac9ce060c59926d75ff4e4946b771c6
parentdcd31244e8ecc492a511e48ed4c631615e092491 (diff)
downloadFreeBSD-src-c85e616e29482200cd0a47fa6c85165a98a4caaf.zip
FreeBSD-src-c85e616e29482200cd0a47fa6c85165a98a4caaf.tar.gz
MFhead @ r292053
-rw-r--r--MAINTAINERS3
-rw-r--r--contrib/ofed/usr.bin/ibaddr/Makefile2
-rw-r--r--contrib/ofed/usr.bin/ibnetdiscover/Makefile4
-rw-r--r--contrib/ofed/usr.bin/ibping/Makefile2
-rw-r--r--contrib/ofed/usr.bin/ibportstate/Makefile2
-rw-r--r--contrib/ofed/usr.bin/ibroute/Makefile4
-rw-r--r--contrib/ofed/usr.bin/ibsendtrap/Makefile2
-rw-r--r--contrib/ofed/usr.bin/ibstat/Makefile2
-rw-r--r--contrib/ofed/usr.bin/ibsysstat/Makefile2
-rw-r--r--contrib/ofed/usr.bin/ibtracert/Makefile4
-rw-r--r--contrib/ofed/usr.bin/opensm/Makefile3
-rw-r--r--contrib/ofed/usr.bin/osmtest/Makefile9
-rw-r--r--contrib/ofed/usr.bin/perfquery/Makefile2
-rw-r--r--contrib/ofed/usr.bin/saquery/Makefile3
-rw-r--r--contrib/ofed/usr.bin/sminfo/Makefile2
-rw-r--r--contrib/ofed/usr.bin/smpdump/Makefile2
-rw-r--r--contrib/ofed/usr.bin/smpquery/Makefile4
-rw-r--r--contrib/ofed/usr.bin/vendstat/Makefile2
-rw-r--r--lib/libc/rpc/svc_vc.c18
-rw-r--r--lib/libc/stdio/open_memstream.c4
-rw-r--r--lib/libc/stdio/open_wmemstream.c4
-rw-r--r--lib/libopenbsd/Makefile1
-rw-r--r--lib/libopenbsd/imsg.c15
-rw-r--r--sbin/devd/devd.cc23
-rw-r--r--sbin/geom/class/multipath/geom_multipath.c11
-rw-r--r--sbin/sysctl/sysctl.88
-rw-r--r--sbin/sysctl/sysctl.c34
-rw-r--r--share/man/man4/ioat.415
-rw-r--r--share/man/man4/isp.414
-rw-r--r--share/man/man9/BUS_DESCRIBE_INTR.94
-rw-r--r--share/mk/bsd.libnames.mk31
-rw-r--r--share/mk/src.libnames.mk35
-rw-r--r--sys/dev/hwpmc/hwpmc_logging.c6
-rw-r--r--sys/dev/ioat/ioat.c56
-rw-r--r--sys/dev/ioat/ioat.h13
-rw-r--r--sys/dev/ioat/ioat_internal.h4
-rw-r--r--sys/dev/ioat/ioat_test.c53
-rw-r--r--sys/dev/ioat/ioat_test.h2
-rw-r--r--sys/dev/isp/isp.c4
-rw-r--r--sys/dev/isp/isp_pci.c11
-rw-r--r--sys/dev/sfxge/common/efx.h3
-rw-r--r--sys/dev/sfxge/common/efx_impl.h1
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.c244
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.h36
-rw-r--r--sys/dev/sfxge/common/efx_types.h2
-rw-r--r--sys/dev/sfxge/common/hunt_ev.c14
-rw-r--r--sys/dev/sfxge/common/hunt_impl.h6
-rw-r--r--sys/dev/sfxge/common/hunt_mcdi.c137
-rw-r--r--sys/dev/sfxge/common/siena_mcdi.c76
-rw-r--r--sys/dev/usb/wlan/if_urtwn.c74
-rw-r--r--sys/dev/usb/wlan/if_urtwnreg.h7
-rw-r--r--sys/dev/usb/wlan/if_urtwnvar.h1
-rw-r--r--sys/netinet/cc/cc_cubic.c13
-rw-r--r--sys/netinet/cc/cc_newreno.c14
-rw-r--r--sys/netinet/if_ether.c26
-rw-r--r--sys/netinet/in_mcast.c17
-rw-r--r--sys/netinet/ip_icmp.c8
-rw-r--r--sys/netinet/ip_input.c27
-rw-r--r--sys/netinet/ip_options.c14
-rw-r--r--sys/netinet/ip_var.h2
-rw-r--r--sys/netinet/tcp_var.h1
-rw-r--r--sys/netinet6/icmp6.c29
-rw-r--r--sys/netinet6/in6.c23
-rw-r--r--sys/netinet6/in6_fib.c8
-rw-r--r--sys/netinet6/in6_gif.c4
-rw-r--r--sys/netinet6/in6_mcast.c23
-rw-r--r--sys/netinet6/in6_src.c24
-rw-r--r--tools/tools/ioat/ioatcontrol.88
-rw-r--r--tools/tools/ioat/ioatcontrol.c29
-rw-r--r--usr.bin/clang/lldb/Makefile4
-rw-r--r--usr.sbin/iostat/iostat.c59
-rw-r--r--usr.sbin/pmcstudy/pmcstudy.88
-rw-r--r--usr.sbin/pmcstudy/pmcstudy.c712
73 files changed, 1528 insertions, 546 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index b22accb..62ab287 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -70,6 +70,9 @@ sys/dev/ixgbe erj Pre-commit phabricator review requested.
sys/dev/ixl erj Pre-commit phabricator review requested.
sys/netinet/ip_carp.c glebius Pre-commit review recommended.
sys/netpfil/pf kp,glebius Pre-commit review recommended.
+sctp rrs,tuexen Pre-commit review requested (changes need to be backported to github).
+pmcstudy(8) rrs Pre-commit review requested.
+callout_*(9) rrs Pre-commit review requested -- becareful its tricksy code :o.
usr.sbin/pkg pkg@ Please coordinate behavior or flag changes with pkg team.
lpr gad Pre-commit review requested, particularly for
lpd/recvjob.c and lpd/printjob.c.
diff --git a/contrib/ofed/usr.bin/ibaddr/Makefile b/contrib/ofed/usr.bin/ibaddr/Makefile
index b0af500..2270900 100644
--- a/contrib/ofed/usr.bin/ibaddr/Makefile
+++ b/contrib/ofed/usr.bin/ibaddr/Makefile
@@ -5,7 +5,7 @@
PROG= ibaddr
SRCS= ibaddr.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad
+LIBADD= ibumad ibcommon ibmad
CFLAGS+= -I${DIAGPATH}/include
MAN= ibaddr.8
diff --git a/contrib/ofed/usr.bin/ibnetdiscover/Makefile b/contrib/ofed/usr.bin/ibnetdiscover/Makefile
index 1e6bc0e..f77c6ec 100644
--- a/contrib/ofed/usr.bin/ibnetdiscover/Makefile
+++ b/contrib/ofed/usr.bin/ibnetdiscover/Makefile
@@ -5,8 +5,8 @@
PROG= ibnetdiscover
SRCS= ibnetdiscover.c grouping.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad -losmcomp
-CFLAGS+= -pthread -I${DIAGPATH}/include
+LIBADD= ibumad ibcommon ibmad osmcomp pthread
+CFLAGS+= -I${DIAGPATH}/include
MAN= ibnetdiscover.8
WARNS?= 1
diff --git a/contrib/ofed/usr.bin/ibping/Makefile b/contrib/ofed/usr.bin/ibping/Makefile
index f152855..55ceca8 100644
--- a/contrib/ofed/usr.bin/ibping/Makefile
+++ b/contrib/ofed/usr.bin/ibping/Makefile
@@ -5,7 +5,7 @@
PROG= ibping
SRCS= ibping.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad
+LIBADD= ibumad ibcommon ibmad
CFLAGS+= -I${DIAGPATH}/include
MAN= ibping.8
diff --git a/contrib/ofed/usr.bin/ibportstate/Makefile b/contrib/ofed/usr.bin/ibportstate/Makefile
index e6af8bc..feaced2 100644
--- a/contrib/ofed/usr.bin/ibportstate/Makefile
+++ b/contrib/ofed/usr.bin/ibportstate/Makefile
@@ -5,7 +5,7 @@
PROG= ibportstate
SRCS= ibportstate.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad
+LIBADD= ibumad ibcommon ibmad
CFLAGS+= -I${DIAGPATH}/include
MAN= ibportstate.8
diff --git a/contrib/ofed/usr.bin/ibroute/Makefile b/contrib/ofed/usr.bin/ibroute/Makefile
index bbbbda3..ab73621 100644
--- a/contrib/ofed/usr.bin/ibroute/Makefile
+++ b/contrib/ofed/usr.bin/ibroute/Makefile
@@ -5,8 +5,8 @@
PROG= ibroute
SRCS= ibroute.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad -losmcomp
-CFLAGS+= -pthread -I${DIAGPATH}/include
+LIBADD= ibumad ibcommon ibmad osmcomp pthread
+CFLAGS+= -I${DIAGPATH}/include
MAN= ibroute.8
WARNS?= 1
diff --git a/contrib/ofed/usr.bin/ibsendtrap/Makefile b/contrib/ofed/usr.bin/ibsendtrap/Makefile
index 8548838..33ac49a 100644
--- a/contrib/ofed/usr.bin/ibsendtrap/Makefile
+++ b/contrib/ofed/usr.bin/ibsendtrap/Makefile
@@ -5,7 +5,7 @@
PROG= ibsendtrap
SRCS= ibsendtrap.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad
+LIBADD= ibumad ibcommon ibmad
CFLAGS+= -I${DIAGPATH}/include
MAN=
diff --git a/contrib/ofed/usr.bin/ibstat/Makefile b/contrib/ofed/usr.bin/ibstat/Makefile
index 6c2c23c..652cc68 100644
--- a/contrib/ofed/usr.bin/ibstat/Makefile
+++ b/contrib/ofed/usr.bin/ibstat/Makefile
@@ -5,7 +5,7 @@
PROG= ibstat
SRCS= ibstat.c
-LDADD= -libumad -libcommon
+LIBADD= ibumad ibcommon
CFLAGS+= -I${DIAGPATH}/include
MAN= ibstat.8
diff --git a/contrib/ofed/usr.bin/ibsysstat/Makefile b/contrib/ofed/usr.bin/ibsysstat/Makefile
index 974e015..52fec8d 100644
--- a/contrib/ofed/usr.bin/ibsysstat/Makefile
+++ b/contrib/ofed/usr.bin/ibsysstat/Makefile
@@ -5,7 +5,7 @@
PROG= ibsysstat
SRCS= ibsysstat.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad
+LIBADD= ibumad ibcommon ibmad
CFLAGS+= -I${DIAGPATH}/include
MAN= ibsysstat.8
diff --git a/contrib/ofed/usr.bin/ibtracert/Makefile b/contrib/ofed/usr.bin/ibtracert/Makefile
index cbfae3e..9c4a494 100644
--- a/contrib/ofed/usr.bin/ibtracert/Makefile
+++ b/contrib/ofed/usr.bin/ibtracert/Makefile
@@ -5,8 +5,8 @@
PROG= ibtracert
SRCS= ibtracert.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad -losmcomp
-CFLAGS+= -pthread -I${DIAGPATH}/include
+LIBADD= ibumad ibcommon ibmad osmcomp pthread
+CFLAGS+= -I${DIAGPATH}/include
MAN= ibtracert.8
WARNS?= 1
diff --git a/contrib/ofed/usr.bin/opensm/Makefile b/contrib/ofed/usr.bin/opensm/Makefile
index ae45eaa..4dd1b06 100644
--- a/contrib/ofed/usr.bin/opensm/Makefile
+++ b/contrib/ofed/usr.bin/opensm/Makefile
@@ -29,8 +29,7 @@ SRCS+= osm_vl_arb_rcv.c st.c osm_perfmgr.c osm_perfmgr_db.c osm_event_plugin.c
SRCS+= osm_dump.c osm_ucast_cache.c osm_qos_parser_y.y osm_qos_parser_l.l
SRCS+= osm_qos_policy.c
-LDADD= -lopensm -losmvendor -losmcomp -libmad -libumad -libcommon
-CFLAGS+= -pthread
+LIBADD= opensm osmvendor osmcomp ibmad ibumad ibcommon pthread
CFLAGS+= -DVENDOR_RMPP_SUPPORT -DDUAL_SIDED_RMPP
MAN= opensm.8
diff --git a/contrib/ofed/usr.bin/osmtest/Makefile b/contrib/ofed/usr.bin/osmtest/Makefile
index 038d1db1..0330b2e 100644
--- a/contrib/ofed/usr.bin/osmtest/Makefile
+++ b/contrib/ofed/usr.bin/osmtest/Makefile
@@ -16,14 +16,7 @@ SRCS= main.c \
osmt_slvl_vl_arb.c \
osmtest.c
-LDADD= -libcommon \
- -libmad \
- -libumad \
- -losmvendor \
- -losmcomp \
- -lopensm \
-
-LIBADD+= pthread
+LIBADD= ibcommon ibmad ibumad osmvendor osmcomp opensm pthread
CFLAGS= -DVENDOR_RMPP_SUPPORT -DDUAL_SIDED_RMPP \
-I${OPENSM}/osmtest/include
diff --git a/contrib/ofed/usr.bin/perfquery/Makefile b/contrib/ofed/usr.bin/perfquery/Makefile
index 792d575..ba337e1 100644
--- a/contrib/ofed/usr.bin/perfquery/Makefile
+++ b/contrib/ofed/usr.bin/perfquery/Makefile
@@ -5,7 +5,7 @@
PROG= perfquery
SRCS= perfquery.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad
+LIBADD= ibumad ibcommon ibmad
CFLAGS+= -I${DIAGPATH}/include
MAN= perfquery.8
diff --git a/contrib/ofed/usr.bin/saquery/Makefile b/contrib/ofed/usr.bin/saquery/Makefile
index efb6036..210224a 100644
--- a/contrib/ofed/usr.bin/saquery/Makefile
+++ b/contrib/ofed/usr.bin/saquery/Makefile
@@ -5,10 +5,9 @@
PROG= saquery
SRCS= saquery.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad -losmcomp -losmvendor -lopensm
+LIBADD= ibumad ibcommon ibmad osmcomp osmvendor opensm pthread
CFLAGS+= -I${DIAGPATH}/include
CFLAGS+= -DOSM_VENDOR_INTF_OPENIB -DVENDOR_RMPP_SUPPORT -DDUAL_SIDED_RMPP
-CFLAGS+= -pthread
MAN= saquery.8
WARNS?= 1
diff --git a/contrib/ofed/usr.bin/sminfo/Makefile b/contrib/ofed/usr.bin/sminfo/Makefile
index 90f9887..0ec6656 100644
--- a/contrib/ofed/usr.bin/sminfo/Makefile
+++ b/contrib/ofed/usr.bin/sminfo/Makefile
@@ -5,7 +5,7 @@
PROG= sminfo
SRCS= sminfo.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad
+LIBADD= ibumad ibcommon ibmad
CFLAGS+= -I${DIAGPATH}/include
MAN= sminfo.8
diff --git a/contrib/ofed/usr.bin/smpdump/Makefile b/contrib/ofed/usr.bin/smpdump/Makefile
index 4db68be..e9258a5 100644
--- a/contrib/ofed/usr.bin/smpdump/Makefile
+++ b/contrib/ofed/usr.bin/smpdump/Makefile
@@ -5,7 +5,7 @@
PROG= smpdump
SRCS= smpdump.c
-LDADD= -libumad -libcommon -libmad
+LIBADD= ibumad ibcommon ibmad
CFLAGS+= -I${DIAGPATH}/include
MAN= smpdump.8
diff --git a/contrib/ofed/usr.bin/smpquery/Makefile b/contrib/ofed/usr.bin/smpquery/Makefile
index edfedd1..f08df7d 100644
--- a/contrib/ofed/usr.bin/smpquery/Makefile
+++ b/contrib/ofed/usr.bin/smpquery/Makefile
@@ -5,8 +5,8 @@
PROG= smpquery
SRCS= smpquery.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad -losmcomp
-CFLAGS+= -pthread -I${DIAGPATH}/include
+LIBADD= ibumad ibcommon ibmad osmcomp pthread
+CFLAGS+= -I${DIAGPATH}/include
MAN= smpquery.8
WARNS?= 1
diff --git a/contrib/ofed/usr.bin/vendstat/Makefile b/contrib/ofed/usr.bin/vendstat/Makefile
index bfca2c8..df18313 100644
--- a/contrib/ofed/usr.bin/vendstat/Makefile
+++ b/contrib/ofed/usr.bin/vendstat/Makefile
@@ -5,7 +5,7 @@
PROG= vendstat
SRCS= vendstat.c ibdiag_common.c
-LDADD= -libumad -libcommon -libmad
+LIBADD= ibumad ibcommon ibmad
CFLAGS+= -I${DIAGPATH}/include
MAN= vendstat.8
diff --git a/lib/libc/rpc/svc_vc.c b/lib/libc/rpc/svc_vc.c
index bafb725..e81a839 100644
--- a/lib/libc/rpc/svc_vc.c
+++ b/lib/libc/rpc/svc_vc.c
@@ -281,8 +281,8 @@ rendezvous_request(SVCXPRT *xprt, struct rpc_msg *msg)
int sock, flags;
struct cf_rendezvous *r;
struct cf_conn *cd;
- struct sockaddr_storage addr;
- socklen_t len;
+ struct sockaddr_storage addr, sslocal;
+ socklen_t len, slen;
struct __rpc_sockinfo si;
SVCXPRT *newxprt;
fd_set cleanfds;
@@ -347,6 +347,20 @@ again:
__xdrrec_setnonblock(&cd->xdrs, cd->maxrec);
} else
cd->nonblock = FALSE;
+ slen = sizeof(struct sockaddr_storage);
+ if(_getsockname(sock, (struct sockaddr *)(void *)&sslocal, &slen) < 0) {
+ warnx("svc_vc_create: could not retrieve local addr");
+ newxprt->xp_ltaddr.maxlen = newxprt->xp_ltaddr.len = 0;
+ } else {
+ newxprt->xp_ltaddr.maxlen = newxprt->xp_ltaddr.len = sslocal.ss_len;
+ newxprt->xp_ltaddr.buf = mem_alloc((size_t)sslocal.ss_len);
+ if (newxprt->xp_ltaddr.buf == NULL) {
+ warnx("svc_vc_create: no mem for local addr");
+ newxprt->xp_ltaddr.maxlen = newxprt->xp_ltaddr.len = 0;
+ } else {
+ memcpy(newxprt->xp_ltaddr.buf, &sslocal, (size_t)sslocal.ss_len);
+ }
+ }
gettimeofday(&cd->last_recv_time, NULL);
diff --git a/lib/libc/stdio/open_memstream.c b/lib/libc/stdio/open_memstream.c
index f3d1ee5..a7e0bae 100644
--- a/lib/libc/stdio/open_memstream.c
+++ b/lib/libc/stdio/open_memstream.c
@@ -31,10 +31,10 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <assert.h>
#include <errno.h>
+#include <limits.h>
#ifdef DEBUG
-#include <inttypes.h>
+#include <stdint.h>
#endif
-#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/lib/libc/stdio/open_wmemstream.c b/lib/libc/stdio/open_wmemstream.c
index 4585531..3e8713f 100644
--- a/lib/libc/stdio/open_wmemstream.c
+++ b/lib/libc/stdio/open_wmemstream.c
@@ -31,10 +31,10 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <assert.h>
#include <errno.h>
+#include <limits.h>
#ifdef DEBUG
-#include <inttypes.h>
+#include <stdint.h>
#endif
-#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/lib/libopenbsd/Makefile b/lib/libopenbsd/Makefile
index 3f16bff..3eb6b74 100644
--- a/lib/libopenbsd/Makefile
+++ b/lib/libopenbsd/Makefile
@@ -11,5 +11,4 @@ CFLAGS+= -I${.CURDIR}
WARNS= 3
-NO_WERROR=
.include <bsd.lib.mk>
diff --git a/lib/libopenbsd/imsg.c b/lib/libopenbsd/imsg.c
index cb16bd7..279ab63 100644
--- a/lib/libopenbsd/imsg.c
+++ b/lib/libopenbsd/imsg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg.c,v 1.10 2015/07/19 07:18:59 nicm Exp $ */
+/* $OpenBSD: imsg.c,v 1.13 2015/12/09 11:54:12 tb Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -74,7 +74,7 @@ imsg_read(struct imsgbuf *ibuf)
again:
if (getdtablecount() + imsg_fd_overhead +
- (CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int)
+ (int)((CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))
>= getdtablesize()) {
errno = EAGAIN;
free(ifd);
@@ -82,11 +82,9 @@ again:
}
if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
- if (errno == EMSGSIZE)
- goto fail;
- if (errno != EINTR && errno != EAGAIN)
- goto fail;
- goto again;
+ if (errno == EINTR)
+ goto again;
+ goto fail;
}
ibuf->r.wpos += n;
@@ -120,8 +118,7 @@ again:
}
fail:
- if (ifd)
- free(ifd);
+ free(ifd);
return (n);
}
diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc
index 5580f6c..203d750 100644
--- a/sbin/devd/devd.cc
+++ b/sbin/devd/devd.cc
@@ -108,15 +108,26 @@ __FBSDID("$FreeBSD$");
/*
* Since the client socket is nonblocking, we must increase its send buffer to
* handle brief event storms. On FreeBSD, AF_UNIX sockets don't have a receive
- * buffer, so the client can't increate the buffersize by itself.
+ * buffer, so the client can't increase the buffersize by itself.
*
* For example, when creating a ZFS pool, devd emits one 165 character
- * resource.fs.zfs.statechange message for each vdev in the pool. A 64k
- * buffer has enough space for almost 400 drives, which would be very large but
- * not impossibly large pool. A 128k buffer has enough space for 794 drives,
- * which is more than can fit in a rack with modern technology.
+ * resource.fs.zfs.statechange message for each vdev in the pool. The kernel
+ * allocates a 4608B mbuf for each message. Modern technology places a limit of
+ * roughly 450 drives/rack, and it's unlikely that a zpool will ever be larger
+ * than that.
+ *
+ * 450 drives * 165 bytes / drive = 74250B of data in the sockbuf
+ * 450 drives * 4608B / drive = 2073600B of mbufs in the sockbuf
+ *
+ * We can't directly set the sockbuf's mbuf limit, but we can do it indirectly.
+ * The kernel sets it to the minimum of a hard-coded maximum value and sbcc *
+ * kern.ipc.sockbuf_waste_factor, where sbcc is the socket buffer size set by
+ * the user. The default value of kern.ipc.sockbuf_waste_factor is 8. If we
+ * set the bufsize to 256k and use the kern.ipc.sockbuf_waste_factor, then the
+ * kernel will set the mbuf limit to 2MB, which is just large enough for 450
+ * drives. It also happens to be the same as the hardcoded maximum value.
*/
-#define CLIENT_BUFSIZE 131072
+#define CLIENT_BUFSIZE 262144
using namespace std;
diff --git a/sbin/geom/class/multipath/geom_multipath.c b/sbin/geom/class/multipath/geom_multipath.c
index cdf35d0..5743911 100644
--- a/sbin/geom/class/multipath/geom_multipath.c
+++ b/sbin/geom/class/multipath/geom_multipath.c
@@ -221,17 +221,15 @@ mp_label(struct gctl_req *req)
/*
* Allocate a sector to write as metadata.
*/
- sector = malloc(secsize);
+ sector = calloc(1, secsize);
if (sector == NULL) {
gctl_error(req, "unable to allocate metadata buffer");
return;
}
- memset(sector, 0, secsize);
rsector = malloc(secsize);
if (rsector == NULL) {
- free(sector);
gctl_error(req, "unable to allocate metadata buffer");
- return;
+ goto done;
}
/*
@@ -246,7 +244,7 @@ mp_label(struct gctl_req *req)
error = g_metadata_store(name, sector, secsize);
if (error != 0) {
gctl_error(req, "cannot store metadata on %s: %s.", name, strerror(error));
- return;
+ goto done;
}
/*
@@ -274,6 +272,9 @@ mp_label(struct gctl_req *req)
name2, name);
}
}
+done:
+ free(rsector);
+ free(sector);
}
diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8
index cb8145e..8d2d316 100644
--- a/sbin/sysctl/sysctl.8
+++ b/sbin/sysctl/sysctl.8
@@ -28,7 +28,7 @@
.\" From: @(#)sysctl.8 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
-.Dd February 12, 2015
+.Dd December 10, 2015
.Dt SYSCTL 8
.Os
.Sh NAME
@@ -36,13 +36,13 @@
.Nd get or set kernel state
.Sh SYNOPSIS
.Nm
-.Op Fl bdehiNnoRTqx
+.Op Fl bdehiNnoRTtqx
.Op Fl B Ar bufsize
.Op Fl f Ar filename
.Ar name Ns Op = Ns Ar value
.Ar ...
.Nm
-.Op Fl bdehNnoRTqx
+.Op Fl bdehNnoRTtqx
.Op Fl B Ar bufsize
.Fl a
.Sh DESCRIPTION
@@ -140,6 +140,8 @@ Suppress some warnings generated by
to standard error.
.It Fl T
Display only variables that are settable via loader (CTLFLAG_TUN).
+.It Fl t
+Print the type of the variable.
.It Fl W
Display only writable variables that are not statistical.
Useful for determining the set of runtime tunable sysctls.
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 1cd31c0..6b493c6 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -72,7 +72,7 @@ static const char rcsid[] =
static const char *conffile;
static int aflag, bflag, Bflag, dflag, eflag, hflag, iflag;
-static int Nflag, nflag, oflag, qflag, Tflag, Wflag, xflag;
+static int Nflag, nflag, oflag, qflag, tflag, Tflag, Wflag, xflag;
static int oidfmt(int *, int, char *, u_int *);
static int parsefile(const char *);
@@ -120,6 +120,9 @@ static const char *ctl_typename[CTLTYPE+1] = {
[CTLTYPE_S16] = "int16_t",
[CTLTYPE_S32] = "int32_t",
[CTLTYPE_S64] = "int64_t",
+ [CTLTYPE_NODE] = "node",
+ [CTLTYPE_STRING] = "string",
+ [CTLTYPE_OPAQUE] = "opaque",
};
static void
@@ -127,8 +130,8 @@ usage(void)
{
(void)fprintf(stderr, "%s\n%s\n",
- "usage: sysctl [-bdehiNnoqTWx] [ -B <bufsize> ] [-f filename] name[=value] ...",
- " sysctl [-bdehNnoqTWx] [ -B <bufsize> ] -a");
+ "usage: sysctl [-bdehiNnoqTtWx] [ -B <bufsize> ] [-f filename] name[=value] ...",
+ " sysctl [-bdehNnoqTtWx] [ -B <bufsize> ] -a");
exit(1);
}
@@ -142,7 +145,7 @@ main(int argc, char **argv)
setbuf(stdout,0);
setbuf(stderr,0);
- while ((ch = getopt(argc, argv, "AabB:def:hiNnoqTwWxX")) != -1) {
+ while ((ch = getopt(argc, argv, "AabB:def:hiNnoqtTwWxX")) != -1) {
switch (ch) {
case 'A':
/* compatibility */
@@ -184,6 +187,9 @@ main(int argc, char **argv)
case 'q':
qflag = 1;
break;
+ case 't':
+ tflag = 1;
+ break;
case 'T':
Tflag = 1;
break;
@@ -856,7 +862,7 @@ show_var(int *oid, int nlen)
{
u_char buf[BUFSIZ], *val, *oval, *p;
char name[BUFSIZ], fmt[BUFSIZ];
- const char *sep, *sep1;
+ const char *sep, *sep1, *prntype;
int qoid[CTL_MAXNAME+2];
uintmax_t umv;
intmax_t mv;
@@ -902,12 +908,23 @@ show_var(int *oid, int nlen)
else
sep = ": ";
- if (dflag) { /* just print description */
+ ctltype = (kind & CTLTYPE);
+ if (tflag || dflag) {
+ if (!nflag)
+ printf("%s%s", name, sep);
+ if (ctl_typename[ctltype] != NULL)
+ prntype = ctl_typename[ctltype];
+ else
+ prntype = "unknown";
+ if (tflag && dflag)
+ printf("%s%s", prntype, sep);
+ else if (tflag) {
+ printf("%s", prntype);
+ return (0);
+ }
qoid[1] = 5;
j = sizeof(buf);
i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
- if (!nflag)
- printf("%s%s", name, sep);
printf("%s", buf);
return (0);
}
@@ -925,7 +942,6 @@ show_var(int *oid, int nlen)
warnx("malloc failed");
return (1);
}
- ctltype = (kind & CTLTYPE);
len = j;
i = sysctl(oid, nlen, val, &len, 0, 0);
if (i != 0 || (len == 0 && ctltype != CTLTYPE_STRING)) {
diff --git a/share/man/man4/ioat.4 b/share/man/man4/ioat.4
index 62d85f1..add6495 100644
--- a/share/man/man4/ioat.4
+++ b/share/man/man4/ioat.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 31, 2015
+.Dd December 9, 2015
.Dt IOAT 4
.Os
.Sh NAME
@@ -78,6 +78,17 @@ In
.Fa "uint32_t flags"
.Fc
.Ft struct bus_dmadesc *
+.Fo ioat_copy_8k_aligned
+.Fa "bus_dmaengine_t dmaengine"
+.Fa "bus_addr_t dst1"
+.Fa "bus_addr_t dst2"
+.Fa "bus_addr_t src1"
+.Fa "bus_addr_t src2"
+.Fa "bus_dmaengine_callback_t callback_fn"
+.Fa "void *callback_arg"
+.Fa "uint32_t flags"
+.Fc
+.Ft struct bus_dmadesc *
.Fo ioat_blockfill
.Fa "bus_dmaengine_t dmaengine"
.Fa "bus_addr_t dst"
@@ -150,7 +161,7 @@ Then, they will submit one or more operations using
.Fn ioat_copy ,
or
.Fn ioat_null .
-After queueing one or more individual DMA operations, they will
+After queuing one or more individual DMA operations, they will
.Fn ioat_release
the
.Ar bus_dmaengine_t
diff --git a/share/man/man4/isp.4 b/share/man/man4/isp.4
index 71050a2..da6b776 100644
--- a/share/man/man4/isp.4
+++ b/share/man/man4/isp.4
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 22, 2015
+.Dd December 9, 2015
.Dt ISP 4
.Os
.Sh NAME
@@ -107,10 +107,12 @@ Optical 2Gb Fibre Channel PCIe cards.
Dell branded version of the QLogic 2312.
.It Qlogic 2422
Optical 4Gb Fibre Channel PCI cards.
-.It Qlogic 2432
+.It Qlogic 246x (aka 2432)
Optical 4Gb Fibre Channel PCIe cards.
-.It Qlogic 2532
+.It Qlogic 256x (aka 2532)
Optical 8Gb Fibre Channel PCIe cards.
+.It Qlogic 267x/836x (aka 2031/8031)
+Optical 16Gb FC/FCoE PCIe cards.
.El
.Sh CONFIGURATION OPTIONS
Target mode support for Fibre Channel adapters may be enabled with the
@@ -127,12 +129,6 @@ They are:
.It Va hint.isp.0.fwload_disable
A hint value to disable loading of firmware
.Xr ispfw 4 .
-.It Va hint.isp.0.prefer_memmap
-A hint value to use PCI memory space instead of I/O space
-access for.
-.It Va hint.isp.0.prefer_iomap
-A hint value to use PCI I/O space instead of Memory space
-access for.
.It Va hint.isp.0.ignore_nvram
A hint value to ignore board NVRAM settings for.
Otherwise use NVRAM settings.
diff --git a/share/man/man9/BUS_DESCRIBE_INTR.9 b/share/man/man9/BUS_DESCRIBE_INTR.9
index c340bb2..8603417 100644
--- a/share/man/man9/BUS_DESCRIBE_INTR.9
+++ b/share/man/man9/BUS_DESCRIBE_INTR.9
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 14, 2009
+.Dd December 9, 2015
.Dt BUS_DESCRIBE_INTR 9
.Os
.Sh NAME
@@ -38,7 +38,7 @@
.In sys/param.h
.In sys/bus.h
.Ft int
-.Fo BUS_BIND_INTR
+.Fo BUS_DESCRIBE_INTR
.Fa "device_t dev" "device_t child" "struct resource *irq" "void *cookie"
.Fa "const char *descr"
.Fc
diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk
index 58df94e..596aa0a 100644
--- a/share/mk/bsd.libnames.mk
+++ b/share/mk/bsd.libnames.mk
@@ -27,22 +27,23 @@ LIBBSDXML?= ${DESTDIR}${LIBDIR}/libbsdxml.a
LIBBSM?= ${DESTDIR}${LIBDIR}/libbsm.a
LIBBSNMP?= ${DESTDIR}${LIBDIR}/libbsnmp.a
LIBBZ2?= ${DESTDIR}${LIBDIR}/libbz2.a
-LIBCXXRT?= ${DESTDIR}${LIBDIR}/libcxxrt.a
-LIBCPLUSPLUS?= ${DESTDIR}${LIBDIR}/libc++.a
LIBC?= ${DESTDIR}${LIBDIR}/libc.a
-LIBC_PIC?= ${DESTDIR}${LIBDIR}/libc_pic.a
LIBCALENDAR?= ${DESTDIR}${LIBDIR}/libcalendar.a
LIBCAM?= ${DESTDIR}${LIBDIR}/libcam.a
LIBCAPSICUM?= ${DESTDIR}${LIBDIR}/libcapsicum.a
LIBCASPER?= ${DESTDIR}${LIBDIR}/libcasper.a
-LIBCOM_ERR?= ${DESTDIR}${LIBDIR}/libcom_err.a
LIBCOMPAT?= ${DESTDIR}${LIBDIR}/libcompat.a
LIBCOMPILER_RT?=${DESTDIR}${LIBDIR}/libcompiler_rt.a
+LIBCOM_ERR?= ${DESTDIR}${LIBDIR}/libcom_err.a
+LIBCPLUSPLUS?= ${DESTDIR}${LIBDIR}/libc++.a
LIBCRYPT?= ${DESTDIR}${LIBDIR}/libcrypt.a
LIBCRYPTO?= ${DESTDIR}${LIBDIR}/libcrypto.a
LIBCTF?= ${DESTDIR}${LIBDIR}/libctf.a
LIBCURSES?= ${DESTDIR}${LIBDIR}/libcurses.a
LIBCUSE?= ${DESTDIR}${LIBDIR}/libcuse.a
+LIBCXGB4?= ${DESTDIR}${LIBDIR}/libcxgb4.a
+LIBCXXRT?= ${DESTDIR}${LIBDIR}/libcxxrt.a
+LIBC_PIC?= ${DESTDIR}${LIBDIR}/libc_pic.a
LIBDEVCTL?= ${DESTDIR}${LIBDIR}/libdevctl.a
LIBDEVINFO?= ${DESTDIR}${LIBDIR}/libdevinfo.a
LIBDEVSTAT?= ${DESTDIR}${LIBDIR}/libdevstat.a
@@ -59,9 +60,9 @@ LIBFIGPAR?= ${DESTDIR}${LIBDIR}/libfigpar.a
LIBFL?= "don't use LIBFL, use LIBL"
LIBFORM?= ${DESTDIR}${LIBDIR}/libform.a
LIBG2C?= ${DESTDIR}${LIBDIR}/libg2c.a
-LIBGPIO?= ${DESTDIR}${LIBDIR}/libgpio.a
LIBGEOM?= ${DESTDIR}${LIBDIR}/libgeom.a
LIBGNUREGEX?= ${DESTDIR}${LIBDIR}/libgnuregex.a
+LIBGPIO?= ${DESTDIR}${LIBDIR}/libgpio.a
LIBGSSAPI?= ${DESTDIR}${LIBDIR}/libgssapi.a
LIBGSSAPI_KRB5?= ${DESTDIR}${LIBDIR}/libgssapi_krb5.a
LIBHDB?= ${DESTDIR}${LIBDIR}/libhdb.a
@@ -69,6 +70,12 @@ LIBHEIMBASE?= ${DESTDIR}${LIBDIR}/libheimbase.a
LIBHEIMNTLM?= ${DESTDIR}${LIBDIR}/libheimntlm.a
LIBHEIMSQLITE?= ${DESTDIR}${LIBDIR}/libheimsqlite.a
LIBHX509?= ${DESTDIR}${LIBDIR}/libhx509.a
+LIBIBCM?= ${DESTDIR}${LIBDIR}/libibcm.a
+LIBIBCOMMON?= ${DESTDIR}${LIBDIR}/libibcommon.a
+LIBIBMAD?= ${DESTDIR}${LIBDIR}/libibmad.a
+LIBIBSDP?= ${DESTDIR}${LIBDIR}/libibsdp.a
+LIBIBUMAD?= ${DESTDIR}${LIBDIR}/libibumad.a
+LIBIBVERBS?= ${DESTDIR}${LIBDIR}/libibverbs.a
LIBIPSEC?= ${DESTDIR}${LIBDIR}/libipsec.a
LIBJAIL?= ${DESTDIR}${LIBDIR}/libjail.a
LIBKADM5CLNT?= ${DESTDIR}${LIBDIR}/libkadm5clnt.a
@@ -88,8 +95,10 @@ LIBMD?= ${DESTDIR}${LIBDIR}/libmd.a
LIBMEMSTAT?= ${DESTDIR}${LIBDIR}/libmemstat.a
LIBMENU?= ${DESTDIR}${LIBDIR}/libmenu.a
LIBMILTER?= ${DESTDIR}${LIBDIR}/libmilter.a
+LIBMLX4?= ${DESTDIR}${LIBDIR}/libmlx4.a
LIBMP?= ${DESTDIR}${LIBDIR}/libmp.a
LIBMT?= ${DESTDIR}${LIBDIR}/libmt.a
+LIBMTHCA?= ${DESTDIR}${LIBDIR}/libmthca.a
LIBNANDFS?= ${DESTDIR}${LIBDIR}/libnandfs.a
LIBNCURSES?= ${DESTDIR}${LIBDIR}/libncurses.a
LIBNCURSESW?= ${DESTDIR}${LIBDIR}/libncursesw.a
@@ -97,7 +106,10 @@ LIBNETGRAPH?= ${DESTDIR}${LIBDIR}/libnetgraph.a
LIBNGATM?= ${DESTDIR}${LIBDIR}/libngatm.a
LIBNV?= ${DESTDIR}${LIBDIR}/libnv.a
LIBNVPAIR?= ${DESTDIR}${LIBDIR}/libnvpair.a
+LIBOPENSM?= ${DESTDIR}${LIBDIR}/libopensm.a
LIBOPIE?= ${DESTDIR}${LIBDIR}/libopie.a
+LIBOSMCOMP?= ${DESTDIR}${LIBDIR}/libosmcomp.a
+LIBOSMVENDOR?= ${DESTDIR}${LIBDIR}/libosmvendor.a
LIBPAM?= ${DESTDIR}${LIBDIR}/libpam.a
LIBPANEL?= ${DESTDIR}${LIBDIR}/libpanel.a
LIBPANELW?= ${DESTDIR}${LIBDIR}/libpanelw.a
@@ -108,9 +120,10 @@ LIBPROC?= ${DESTDIR}${LIBDIR}/libproc.a
LIBPROCSTAT?= ${DESTDIR}${LIBDIR}/libprocstat.a
LIBPTHREAD?= ${DESTDIR}${LIBDIR}/libpthread.a
LIBRADIUS?= ${DESTDIR}${LIBDIR}/libradius.a
+LIBRDMACM?= ${DESTDIR}${LIBDIR}/librdmacm.a
LIBROKEN?= ${DESTDIR}${LIBDIR}/libroken.a
-LIBRPCSVC?= ${DESTDIR}${LIBDIR}/librpcsvc.a
LIBRPCSEC_GSS?= ${DESTDIR}${LIBDIR}/librpcsec_gss.a
+LIBRPCSVC?= ${DESTDIR}${LIBDIR}/librpcsvc.a
LIBRT?= ${DESTDIR}${LIBDIR}/librt.a
LIBRTLD_DB?= ${DESTDIR}${LIBDIR}/librtld_db.a
LIBSBUF?= ${DESTDIR}${LIBDIR}/libsbuf.a
@@ -128,18 +141,18 @@ LIBTERMLIB?= "don't use LIBTERMLIB, use LIBTERMCAP"
LIBTINFO?= "don't use LIBTINFO, use LIBNCURSES"
LIBUFS?= ${DESTDIR}${LIBDIR}/libufs.a
LIBUGIDFW?= ${DESTDIR}${LIBDIR}/libugidfw.a
+LIBULOG?= ${DESTDIR}${LIBDIR}/libulog.a
LIBUMEM?= ${DESTDIR}${LIBDIR}/libumem.a
-LIBUSBHID?= ${DESTDIR}${LIBDIR}/libusbhid.a
LIBUSB?= ${DESTDIR}${LIBDIR}/libusb.a
-LIBULOG?= ${DESTDIR}${LIBDIR}/libulog.a
+LIBUSBHID?= ${DESTDIR}${LIBDIR}/libusbhid.a
LIBUTIL?= ${DESTDIR}${LIBDIR}/libutil.a
LIBUUTIL?= ${DESTDIR}${LIBDIR}/libuutil.a
LIBVGL?= ${DESTDIR}${LIBDIR}/libvgl.a
LIBVMMAPI?= ${DESTDIR}${LIBDIR}/libvmmapi.a
LIBWIND?= ${DESTDIR}${LIBDIR}/libwind.a
LIBWRAP?= ${DESTDIR}${LIBDIR}/libwrap.a
-LIBXPG4?= ${DESTDIR}${LIBDIR}/libxpg4.a
LIBXO?= ${DESTDIR}${LIBDIR}/libxo.a
+LIBXPG4?= ${DESTDIR}${LIBDIR}/libxpg4.a
LIBY?= ${DESTDIR}${LIBDIR}/liby.a
LIBYPCLNT?= ${DESTDIR}${LIBDIR}/libypclnt.a
LIBZ?= ${DESTDIR}${LIBDIR}/libz.a
diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk
index 15d30cc..c77cefa 100644
--- a/share/mk/src.libnames.mk
+++ b/share/mk/src.libnames.mk
@@ -169,6 +169,23 @@ _LIBRARIES= \
zfs \
zpool \
+.if ${MK_OFED} != "no"
+_LIBRARIES+= \
+ cxgb4 \
+ ibcm \
+ ibcommon \
+ ibmad \
+ ibsdp \
+ ibumad \
+ ibverbs \
+ mlx4 \
+ mthca \
+ opensm \
+ osmcomp \
+ osmvendor \
+ rdmacm \
+
+.endif
# Each library's LIBADD needs to be duplicated here for static linkage of
# 2nd+ order consumers. Auto-generating this would be better.
@@ -416,6 +433,19 @@ LIBUUTILDIR= ${OBJTOP}/cddl/lib/libuutil
LIBZFSDIR= ${OBJTOP}/cddl/lib/libzfs
LIBZFS_COREDIR= ${OBJTOP}/cddl/lib/libzfs_core
LIBZPOOLDIR= ${OBJTOP}/cddl/lib/libzpool
+LIBCXGB4DIR= ${OBJTOP}/contrib/ofed/usr.lib/libcxgb4
+LIBIBCMDIR= ${OBJTOP}/contrib/ofed/usr.lib/libibcm
+LIBIBCOMMONDIR= ${OBJTOP}/contrib/ofed/usr.lib/libibcommon
+LIBIBMADDIR= ${OBJTOP}/contrib/ofed/usr.lib/libibmad
+LIBIBUMADDIR= ${OBJTOP}/contrib/ofed/usr.lib/libibumad
+LIBIBVERBSDIR= ${OBJTOP}/contrib/ofed/usr.lib/libibverbs
+LIBMLX4DIR= ${OBJTOP}/contrib/ofed/usr.lib/libmlx4
+LIBMTHCADIR= ${OBJTOP}/contrib/ofed/usr.lib/libmthca
+LIBOPENSMDIR= ${OBJTOP}/contrib/ofed/usr.lib/libopensm
+LIBOSMCOMPDIR= ${OBJTOP}/contrib/ofed/usr.lib/libosmcomp
+LIBOSMVENDORDIR= ${OBJTOP}/contrib/ofed/usr.lib/libosmvendor
+LIBRDMACMDIR= ${OBJTOP}/contrib/ofed/usr.lib/librdmacm
+LIBIBSDPDIR= ${OBJTOP}/contrib/ofed/usr.lib/libsdp
LIBDIALOGDIR= ${OBJTOP}/gnu/lib/libdialog
LIBGCOVDIR= ${OBJTOP}/gnu/lib/libgcov
LIBGOMPDIR= ${OBJTOP}/gnu/lib/libgomp
@@ -453,8 +483,6 @@ LIBMENUDIR= ${OBJTOP}/lib/ncurses/menu
LIBMENULIBWDIR= ${OBJTOP}/lib/ncurses/menuw
LIBNCURSESDIR= ${OBJTOP}/lib/ncurses/ncurses
LIBNCURSESWDIR= ${OBJTOP}/lib/ncurses/ncursesw
-LIBTERMCAPDIR= ${LIBNCURSESDIR}
-LIBTERMCAPWDIR= ${LIBNCURSESWDIR}
LIBPANELDIR= ${OBJTOP}/lib/ncurses/panel
LIBPANELWDIR= ${OBJTOP}/lib/ncurses/panelw
LIBCRYPTODIR= ${OBJTOP}/secure/lib/libcrypto
@@ -464,6 +492,9 @@ LIBTEKENDIR= ${OBJTOP}/sys/teken/libteken
LIBEGACYDIR= ${OBJTOP}/tools/build
LIBLNDIR= ${OBJTOP}/usr.bin/lex/lib
+LIBTERMCAPDIR= ${LIBNCURSESDIR}
+LIBTERMCAPWDIR= ${LIBNCURSESWDIR}
+
# Default other library directories to lib/libNAME.
.for lib in ${_LIBRARIES}
LIB${lib:tu}DIR?= ${OBJTOP}/lib/lib${lib}
diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c
index cc85481..231fbb9 100644
--- a/sys/dev/hwpmc/hwpmc_logging.c
+++ b/sys/dev/hwpmc/hwpmc_logging.c
@@ -70,6 +70,9 @@ SYSCTL_DECL(_kern_hwpmc);
*/
static int pmclog_buffer_size = PMC_LOG_BUFFER_SIZE;
+#if (__FreeBSD_version < 1100000)
+TUNABLE_INT(PMC_SYSCTL_NAME_PREFIX "logbuffersize", &pmclog_buffer_size);
+#endif
SYSCTL_INT(_kern_hwpmc, OID_AUTO, logbuffersize, CTLFLAG_RDTUN,
&pmclog_buffer_size, 0, "size of log buffers in kilobytes");
@@ -78,6 +81,9 @@ SYSCTL_INT(_kern_hwpmc, OID_AUTO, logbuffersize, CTLFLAG_RDTUN,
*/
static int pmc_nlogbuffers = PMC_NLOGBUFFERS;
+#if (__FreeBSD_version < 1100000)
+TUNABLE_INT(PMC_SYSCTL_NAME_PREFIX "nbuffers", &pmc_nlogbuffers);
+#endif
SYSCTL_INT(_kern_hwpmc, OID_AUTO, nbuffers, CTLFLAG_RDTUN,
&pmc_nlogbuffers, 0, "number of global log buffers");
diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c
index 00cf337..c5ad746 100644
--- a/sys/dev/ioat/ioat.c
+++ b/sys/dev/ioat/ioat.c
@@ -219,6 +219,17 @@ static struct _pcsid
{ 0x6f528086, "BDXDE IOAT Ch2" },
{ 0x6f538086, "BDXDE IOAT Ch3" },
+ { 0x6f208086, "BDX IOAT Ch0" },
+ { 0x6f218086, "BDX IOAT Ch1" },
+ { 0x6f228086, "BDX IOAT Ch2" },
+ { 0x6f238086, "BDX IOAT Ch3" },
+ { 0x6f248086, "BDX IOAT Ch4" },
+ { 0x6f258086, "BDX IOAT Ch5" },
+ { 0x6f268086, "BDX IOAT Ch6" },
+ { 0x6f278086, "BDX IOAT Ch7" },
+ { 0x6f2e8086, "BDX IOAT Ch0 (RAID)" },
+ { 0x6f2f8086, "BDX IOAT Ch1 (RAID)" },
+
{ 0x00000000, NULL }
};
@@ -833,6 +844,51 @@ ioat_copy(bus_dmaengine_t dmaengine, bus_addr_t dst,
}
struct bus_dmadesc *
+ioat_copy_8k_aligned(bus_dmaengine_t dmaengine, bus_addr_t dst1,
+ bus_addr_t dst2, bus_addr_t src1, bus_addr_t src2,
+ bus_dmaengine_callback_t callback_fn, void *callback_arg, uint32_t flags)
+{
+ struct ioat_dma_hw_descriptor *hw_desc;
+ struct ioat_descriptor *desc;
+ struct ioat_softc *ioat;
+
+ CTR0(KTR_IOAT, __func__);
+ ioat = to_ioat_softc(dmaengine);
+
+ if (((src1 | src2 | dst1 | dst2) & (0xffffull << 48)) != 0) {
+ ioat_log_message(0, "%s: High 16 bits of src/dst invalid\n",
+ __func__);
+ return (NULL);
+ }
+ if (((src1 | src2 | dst1 | dst2) & PAGE_MASK) != 0) {
+ ioat_log_message(0, "%s: Addresses must be page-aligned\n",
+ __func__);
+ return (NULL);
+ }
+
+ desc = ioat_op_generic(ioat, IOAT_OP_COPY, 2 * PAGE_SIZE, src1, dst1,
+ callback_fn, callback_arg, flags);
+ if (desc == NULL)
+ return (NULL);
+
+ hw_desc = desc->u.dma;
+ if (src2 != src1 + PAGE_SIZE) {
+ hw_desc->u.control.src_page_break = 1;
+ hw_desc->next_src_addr = src2;
+ }
+ if (dst2 != dst1 + PAGE_SIZE) {
+ hw_desc->u.control.dest_page_break = 1;
+ hw_desc->next_dest_addr = dst2;
+ }
+
+ if (g_ioat_debug_level >= 3)
+ dump_descriptor(hw_desc);
+
+ ioat_submit_single(ioat);
+ return (&desc->bus_dmadesc);
+}
+
+struct bus_dmadesc *
ioat_blockfill(bus_dmaengine_t dmaengine, bus_addr_t dst, uint64_t fillpattern,
bus_size_t len, bus_dmaengine_callback_t callback_fn, void *callback_arg,
uint32_t flags)
diff --git a/sys/dev/ioat/ioat.h b/sys/dev/ioat/ioat.h
index c5a4855..8174ce8 100644
--- a/sys/dev/ioat/ioat.h
+++ b/sys/dev/ioat/ioat.h
@@ -84,6 +84,19 @@ struct bus_dmadesc *ioat_copy(bus_dmaengine_t dmaengine, bus_addr_t dst,
void *callback_arg, uint32_t flags);
/*
+ * Issue a copy data operation, with constraints:
+ * - src1, src2, dst1, dst2 are all page-aligned addresses
+ * - The quantity to copy is exactly 2 pages;
+ * - src1 -> dst1, src2 -> dst2
+ *
+ * Why use this instead of normal _copy()? You can copy two non-contiguous
+ * pages (src, dst, or both) with one descriptor.
+ */
+struct bus_dmadesc *ioat_copy_8k_aligned(bus_dmaengine_t dmaengine,
+ bus_addr_t dst1, bus_addr_t dst2, bus_addr_t src1, bus_addr_t src2,
+ bus_dmaengine_callback_t callback_fn, void *callback_arg, uint32_t flags);
+
+/*
* Issues a null operation. This issues the operation to the hardware, but the
* hardware doesn't do anything with it.
*/
diff --git a/sys/dev/ioat/ioat_internal.h b/sys/dev/ioat/ioat_internal.h
index 4ec738e..9a00877 100644
--- a/sys/dev/ioat/ioat_internal.h
+++ b/sys/dev/ioat/ioat_internal.h
@@ -175,8 +175,8 @@ struct ioat_dma_hw_descriptor {
uint64_t src_addr;
uint64_t dest_addr;
uint64_t next;
- uint64_t reserved;
- uint64_t reserved2;
+ uint64_t next_src_addr;
+ uint64_t next_dest_addr;
uint64_t user1;
uint64_t user2;
};
diff --git a/sys/dev/ioat/ioat_test.c b/sys/dev/ioat/ioat_test.c
index a8311ab..f39786e 100644
--- a/sys/dev/ioat/ioat_test.c
+++ b/sys/dev/ioat/ioat_test.c
@@ -84,11 +84,17 @@ static inline void _ioat_test_log(int verbosity, const char *fmt, ...);
static void
ioat_test_transaction_destroy(struct test_transaction *tx)
{
+ struct ioat_test *test;
int i;
+ test = tx->test;
+
for (i = 0; i < IOAT_MAX_BUFS; i++) {
if (tx->buf[i] != NULL) {
- contigfree(tx->buf[i], tx->length, M_IOAT_TEST);
+ if (test->testkind == IOAT_TEST_DMA_8K)
+ free(tx->buf[i], M_IOAT_TEST);
+ else
+ contigfree(tx->buf[i], tx->length, M_IOAT_TEST);
tx->buf[i] = NULL;
}
}
@@ -97,8 +103,8 @@ ioat_test_transaction_destroy(struct test_transaction *tx)
}
static struct
-test_transaction *ioat_test_transaction_create(unsigned num_buffers,
- uint32_t buffer_size)
+test_transaction *ioat_test_transaction_create(struct ioat_test *test,
+ unsigned num_buffers)
{
struct test_transaction *tx;
unsigned i;
@@ -107,11 +113,16 @@ test_transaction *ioat_test_transaction_create(unsigned num_buffers,
if (tx == NULL)
return (NULL);
- tx->length = buffer_size;
+ tx->length = test->buffer_size;
for (i = 0; i < num_buffers; i++) {
- tx->buf[i] = contigmalloc(buffer_size, M_IOAT_TEST, M_NOWAIT,
- 0, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
+ if (test->testkind == IOAT_TEST_DMA_8K)
+ tx->buf[i] = malloc(test->buffer_size, M_IOAT_TEST,
+ M_NOWAIT);
+ else
+ tx->buf[i] = contigmalloc(test->buffer_size,
+ M_IOAT_TEST, M_NOWAIT, 0, BUS_SPACE_MAXADDR,
+ PAGE_SIZE, 0);
if (tx->buf[i] == NULL) {
ioat_test_transaction_destroy(tx);
@@ -197,8 +208,7 @@ ioat_test_prealloc_memory(struct ioat_test *test, int index)
struct test_transaction *tx;
for (i = 0; i < test->transactions; i++) {
- tx = ioat_test_transaction_create(test->chain_depth * 2,
- test->buffer_size);
+ tx = ioat_test_transaction_create(test, test->chain_depth * 2);
if (tx == NULL) {
ioat_test_log(0, "tx == NULL - memory exhausted\n");
test->status[IOAT_TEST_NO_MEMORY]++;
@@ -258,8 +268,16 @@ ioat_test_submit_1_tx(struct ioat_test *test, bus_dmaengine_t dma)
TAILQ_INSERT_HEAD(&test->pend_q, tx, entry);
IT_UNLOCK();
- ioat_acquire(dma);
+ if (test->testkind != IOAT_TEST_MEMCPY)
+ ioat_acquire(dma);
for (i = 0; i < tx->depth; i++) {
+ if (test->testkind == IOAT_TEST_MEMCPY) {
+ memcpy(tx->buf[2 * i + 1], tx->buf[2 * i], tx->length);
+ if (i == tx->depth - 1)
+ ioat_dma_test_callback(tx, 0);
+ continue;
+ }
+
src = vtophys((vm_offset_t)tx->buf[2*i]);
dest = vtophys((vm_offset_t)tx->buf[2*i+1]);
@@ -286,10 +304,20 @@ ioat_test_submit_1_tx(struct ioat_test *test, bus_dmaengine_t dma)
fillpattern = *(uint64_t *)tx->buf[2*i];
desc = ioat_blockfill(dma, dest, fillpattern,
tx->length, cb, tx, flags);
+ } else if (test->testkind == IOAT_TEST_DMA_8K) {
+ bus_addr_t src2, dst2;
+
+ src2 = vtophys((vm_offset_t)tx->buf[2*i] + PAGE_SIZE);
+ dst2 = vtophys((vm_offset_t)tx->buf[2*i+1] + PAGE_SIZE);
+
+ desc = ioat_copy_8k_aligned(dma, dest, dst2, src, src2,
+ cb, tx, flags);
}
if (desc == NULL)
break;
}
+ if (test->testkind == IOAT_TEST_MEMCPY)
+ return;
ioat_release(dma);
/*
@@ -317,6 +345,13 @@ ioat_dma_test(void *arg)
test = arg;
memset(__DEVOLATILE(void *, test->status), 0, sizeof(test->status));
+ if (test->testkind == IOAT_TEST_DMA_8K &&
+ test->buffer_size != 2 * PAGE_SIZE) {
+ ioat_test_log(0, "Asked for 8k test and buffer size isn't 8k\n");
+ test->status[IOAT_TEST_INVALID_INPUT]++;
+ return;
+ }
+
if (test->buffer_size > 1024 * 1024) {
ioat_test_log(0, "Buffer size too large >1MB\n");
test->status[IOAT_TEST_NO_MEMORY]++;
diff --git a/sys/dev/ioat/ioat_test.h b/sys/dev/ioat/ioat_test.h
index b6e6a15..4306b3b 100644
--- a/sys/dev/ioat/ioat_test.h
+++ b/sys/dev/ioat/ioat_test.h
@@ -42,6 +42,8 @@ enum ioat_test_kind {
IOAT_TEST_FILL = 0,
IOAT_TEST_DMA,
IOAT_TEST_RAW_DMA,
+ IOAT_TEST_DMA_8K,
+ IOAT_TEST_MEMCPY,
IOAT_NUM_TESTKINDS
};
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index a140ddb..d394011 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -7920,7 +7920,9 @@ isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
uint32_t base = 0x7ffe0000;
uint32_t tmp = 0;
- if (IS_25XX(isp)) {
+ if (IS_26XX(isp)) {
+ base = 0x7fe7c000; /* XXX: Observation, may be wrong. */
+ } else if (IS_25XX(isp)) {
base = 0x7ff00000 | 0x48000;
}
ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index bd0ceea..9bc9653 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -294,6 +294,10 @@ static struct ispmdvec mdvec_2600 = {
#define PCI_PRODUCT_QLOGIC_ISP2031 0x2031
#endif
+#ifndef PCI_PRODUCT_QLOGIC_ISP8031
+#define PCI_PRODUCT_QLOGIC_ISP8031 0x8031
+#endif
+
#define PCI_QLOGIC_ISP5432 \
((PCI_PRODUCT_QLOGIC_ISP5432 << 16) | PCI_VENDOR_QLOGIC)
@@ -348,6 +352,9 @@ static struct ispmdvec mdvec_2600 = {
#define PCI_QLOGIC_ISP2031 \
((PCI_PRODUCT_QLOGIC_ISP2031 << 16) | PCI_VENDOR_QLOGIC)
+#define PCI_QLOGIC_ISP8031 \
+ ((PCI_PRODUCT_QLOGIC_ISP8031 << 16) | PCI_VENDOR_QLOGIC)
+
/*
* Odd case for some AMI raid cards... We need to *not* attach to this.
*/
@@ -458,6 +465,9 @@ isp_pci_probe(device_t dev)
case PCI_QLOGIC_ISP2031:
device_set_desc(dev, "Qlogic ISP 2031 PCI FC-AL Adapter");
break;
+ case PCI_QLOGIC_ISP8031:
+ device_set_desc(dev, "Qlogic ISP 8031 PCI FCoE Adapter");
+ break;
default:
return (ENXIO);
}
@@ -800,6 +810,7 @@ isp_pci_attach(device_t dev)
pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2400_OFF;
break;
case PCI_QLOGIC_ISP2031:
+ case PCI_QLOGIC_ISP8031:
did = 0x2600;
isp->isp_nchan += isp_nvports;
isp->isp_mdvec = &mdvec_2600;
diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h
index 531b6c9..a84454d 100644
--- a/sys/dev/sfxge/common/efx.h
+++ b/sys/dev/sfxge/common/efx.h
@@ -218,6 +218,9 @@ typedef struct efx_mcdi_transport_s {
void (*emt_logger)(void *, efx_log_msg_t,
void *, size_t, void *, size_t);
#endif /* EFSYS_OPT_MCDI_LOGGING */
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+ void (*emt_ev_proxy_response)(void *, uint32_t, efx_rc_t);
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
} efx_mcdi_transport_t;
extern __checkReturn efx_rc_t
diff --git a/sys/dev/sfxge/common/efx_impl.h b/sys/dev/sfxge/common/efx_impl.h
index 27ea406..239d9c8 100644
--- a/sys/dev/sfxge/common/efx_impl.h
+++ b/sys/dev/sfxge/common/efx_impl.h
@@ -463,6 +463,7 @@ typedef struct efx_mcdi_ops_s {
efx_rc_t (*emco_fw_update_supported)(efx_nic_t *, boolean_t *);
efx_rc_t (*emco_macaddr_change_supported)(efx_nic_t *, boolean_t *);
efx_rc_t (*emco_link_control_supported)(efx_nic_t *, boolean_t *);
+ efx_rc_t (*emco_mac_spoofing_supported)(efx_nic_t *, boolean_t *);
void (*emco_read_response)(efx_nic_t *, void *, size_t, size_t);
} efx_mcdi_ops_t;
diff --git a/sys/dev/sfxge/common/efx_mcdi.c b/sys/dev/sfxge/common/efx_mcdi.c
index 25c879e..e6ca1e8 100644
--- a/sys/dev/sfxge/common/efx_mcdi.c
+++ b/sys/dev/sfxge/common/efx_mcdi.c
@@ -55,6 +55,7 @@ static efx_mcdi_ops_t __efx_mcdi_siena_ops = {
/* emco_macaddr_change_supported */
siena_mcdi_link_control_supported,
/* emco_link_control_supported */
+ NULL, /* emco_mac_spoofing_supported */
siena_mcdi_read_response, /* emco_read_response */
};
@@ -74,6 +75,8 @@ static efx_mcdi_ops_t __efx_mcdi_hunt_ops = {
/* emco_macaddr_change_supported */
hunt_mcdi_link_control_supported,
/* emco_link_control_supported */
+ hunt_mcdi_mac_spoofing_supported,
+ /* emco_mac_spoofing_supported */
hunt_mcdi_read_response, /* emco_read_response */
};
@@ -228,6 +231,132 @@ efx_mcdi_request_start(
emcop->emco_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
}
+
+ void
+efx_mcdi_read_response_header(
+ __in efx_nic_t *enp,
+ __inout efx_mcdi_req_t *emrp)
+{
+#if EFSYS_OPT_MCDI_LOGGING
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ efx_dword_t hdr[2];
+ unsigned int hdr_len;
+ unsigned int data_len;
+ unsigned int seq;
+ unsigned int cmd;
+ unsigned int error;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(emrp != NULL);
+
+ emcop->emco_read_response(enp, &hdr[0], 0, sizeof (hdr[0]));
+ hdr_len = sizeof (hdr[0]);
+
+ cmd = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE);
+ seq = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_SEQ);
+ error = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR);
+
+ if (cmd != MC_CMD_V2_EXTN) {
+ data_len = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_DATALEN);
+ } else {
+ emcop->emco_read_response(enp, &hdr[1], hdr_len,
+ sizeof (hdr[1]));
+ hdr_len += sizeof (hdr[1]);
+
+ cmd = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_EXTENDED_CMD);
+ data_len =
+ EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
+ }
+
+ if (error && (data_len == 0)) {
+ /* The MC has rebooted since the request was sent. */
+ EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
+ emcop->emco_poll_reboot(enp);
+ rc = EIO;
+ goto fail1;
+ }
+ if ((cmd != emrp->emr_cmd) ||
+ (seq != ((emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ)))) {
+ /* Response is for a different request */
+ rc = EIO;
+ goto fail2;
+ }
+ if (error) {
+ efx_dword_t err[2];
+ unsigned int err_len = MIN(data_len, sizeof (err));
+ int err_code = MC_CMD_ERR_EPROTO;
+ int err_arg = 0;
+
+ /* Read error code (and arg num for MCDI v2 commands) */
+ emcop->emco_read_response(enp, &err, hdr_len, err_len);
+
+ if (err_len >= (MC_CMD_ERR_CODE_OFST + sizeof (efx_dword_t)))
+ err_code = EFX_DWORD_FIELD(err[0], EFX_DWORD_0);
+#ifdef WITH_MCDI_V2
+ if (err_len >= (MC_CMD_ERR_ARG_OFST + sizeof (efx_dword_t)))
+ err_arg = EFX_DWORD_FIELD(err[1], EFX_DWORD_0);
+#endif
+ emrp->emr_err_code = err_code;
+ emrp->emr_err_arg = err_arg;
+
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+ if ((err_code == MC_CMD_ERR_PROXY_PENDING) &&
+ (err_len == sizeof (err))) {
+ /*
+ * The MCDI request would normally fail with EPERM, but
+ * firmware has forwarded it to an authorization agent
+ * attached to a privileged PF.
+ *
+ * Save the authorization request handle. The client
+ * must wait for a PROXY_RESPONSE event, or timeout.
+ */
+ emrp->emr_proxy_handle = err_arg;
+ }
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+
+#if EFSYS_OPT_MCDI_LOGGING
+ if (emtp->emt_logger != NULL) {
+ emtp->emt_logger(emtp->emt_context,
+ EFX_LOG_MCDI_RESPONSE,
+ &hdr, hdr_len,
+ &err, err_len);
+ }
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+
+ if (!emrp->emr_quiet) {
+ EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd,
+ int, err_code, int, err_arg);
+ }
+
+ rc = efx_mcdi_request_errcode(err_code);
+ goto fail3;
+ }
+
+ emrp->emr_rc = 0;
+ emrp->emr_out_length_used = data_len;
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+ emrp->emr_proxy_handle = 0;
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+ return;
+
+fail3:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail3);
+fail2:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail2);
+fail1:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ emrp->emr_rc = rc;
+ emrp->emr_out_length_used = 0;
+}
+
+
__checkReturn boolean_t
efx_mcdi_request_poll(
__in efx_nic_t *enp)
@@ -352,6 +481,9 @@ efx_mcdi_request_errcode(
case MC_CMD_ERR_MAC_EXIST:
return (EEXIST);
+ case MC_CMD_ERR_PROXY_PENDING:
+ return (EAGAIN);
+
default:
EFSYS_PROBE1(mc_pcol_error, int, err);
return (EIO);
@@ -432,6 +564,7 @@ efx_mcdi_ev_cpl(
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ efx_nic_cfg_t *encp = &enp->en_nic_cfg;
efx_mcdi_req_t *emrp;
int state;
@@ -456,27 +589,87 @@ efx_mcdi_ev_cpl(
emip->emi_pending_req = NULL;
EFSYS_UNLOCK(enp->en_eslp, state);
+ if (encp->enc_mcdi_max_payload_length > MCDI_CTL_SDU_LEN_MAX_V1) {
+ /* MCDIv2 response details do not fit into an event. */
+ efx_mcdi_read_response_header(enp, emrp);
+ } else {
+ if (errcode != 0) {
+ if (!emrp->emr_quiet) {
+ EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
+ int, errcode);
+ }
+ emrp->emr_out_length_used = 0;
+ emrp->emr_rc = efx_mcdi_request_errcode(errcode);
+ } else {
+ emrp->emr_out_length_used = outlen;
+ emrp->emr_rc = 0;
+ }
+ }
+ if (errcode == 0) {
+ emcop->emco_request_copyout(enp, emrp);
+ }
+
+ emtp->emt_ev_cpl(emtp->emt_context);
+}
+
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+
+ __checkReturn efx_rc_t
+efx_mcdi_get_proxy_handle(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __out uint32_t *handlep)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_rc_t rc;
+
/*
- * Fill out the remaining hdr fields, and copyout the payload
- * if the user supplied an output buffer.
+ * Return proxy handle from MCDI request that returned with error
+ * MC_MCD_ERR_PROXY_PENDING. This handle is used to wait for a matching
+ * PROXY_RESPONSE event.
*/
- if (errcode != 0) {
- if (!emrp->emr_quiet) {
- EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
- int, errcode);
- }
- emrp->emr_out_length_used = 0;
- emrp->emr_rc = efx_mcdi_request_errcode(errcode);
+ if ((emrp == NULL) || (handlep == NULL)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+ if ((emrp->emr_rc != 0) &&
+ (emrp->emr_err_code == MC_CMD_ERR_PROXY_PENDING)) {
+ *handlep = emrp->emr_proxy_handle;
+ rc = 0;
} else {
- emrp->emr_out_length_used = outlen;
- emrp->emr_rc = 0;
+ *handlep = 0;
+ rc = ENOENT;
}
- emcop->emco_request_copyout(enp, emrp);
+ return (rc);
- emtp->emt_ev_cpl(emtp->emt_context);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+ return (rc);
}
void
+efx_mcdi_ev_proxy_response(
+ __in efx_nic_t *enp,
+ __in unsigned int handle,
+ __in unsigned int status)
+{
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+ efx_rc_t rc;
+
+ /*
+ * Handle results of an authorization request for a privileged MCDI
+ * command. If authorization was granted then we must re-issue the
+ * original MCDI request. If authorization failed or timed out,
+ * then the original MCDI request should be completed with the
+ * result code from this event.
+ */
+ rc = (status == 0) ? 0 : efx_mcdi_request_errcode(status);
+
+ emtp->emt_ev_proxy_response(emtp->emt_context, handle, rc);
+}
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+
+ void
efx_mcdi_ev_death(
__in efx_nic_t *enp,
__in int rc)
@@ -1199,6 +1392,31 @@ fail1:
return (rc);
}
+ __checkReturn efx_rc_t
+efx_mcdi_mac_spoofing_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ efx_rc_t rc;
+
+ if (emcop != NULL && emcop->emco_mac_spoofing_supported != NULL) {
+ if ((rc = emcop->emco_mac_spoofing_supported(enp, supportedp))
+ != 0)
+ goto fail1;
+ } else {
+ /* Earlier devices always supported MAC spoofing */
+ *supportedp = B_TRUE;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
#if EFSYS_OPT_BIST
#if EFSYS_OPT_HUNTINGTON
diff --git a/sys/dev/sfxge/common/efx_mcdi.h b/sys/dev/sfxge/common/efx_mcdi.h
index 9129e11..f25fb4e 100644
--- a/sys/dev/sfxge/common/efx_mcdi.h
+++ b/sys/dev/sfxge/common/efx_mcdi.h
@@ -59,6 +59,12 @@ struct efx_mcdi_req_s {
uint8_t *emr_out_buf;
size_t emr_out_length;
size_t emr_out_length_used;
+ /* Internals: low level transport details */
+ unsigned int emr_err_code;
+ unsigned int emr_err_arg;
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+ uint32_t emr_proxy_handle;
+#endif
};
typedef struct efx_mcdi_iface_s {
@@ -82,6 +88,11 @@ efx_mcdi_execute_quiet(
__in efx_nic_t *enp,
__inout efx_mcdi_req_t *emrp);
+ extern void
+efx_mcdi_read_response_header(
+ __in efx_nic_t *enp,
+ __inout efx_mcdi_req_t *emrp);
+
extern void
efx_mcdi_ev_cpl(
__in efx_nic_t *enp,
@@ -89,6 +100,20 @@ efx_mcdi_ev_cpl(
__in unsigned int outlen,
__in int errcode);
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+extern __checkReturn efx_rc_t
+efx_mcdi_get_proxy_handle(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __out uint32_t *handlep);
+
+extern void
+efx_mcdi_ev_proxy_response(
+ __in efx_nic_t *enp,
+ __in unsigned int handle,
+ __in unsigned int status);
+#endif
+
extern void
efx_mcdi_ev_death(
__in efx_nic_t *enp,
@@ -156,6 +181,12 @@ efx_mcdi_link_control_supported(
__in efx_nic_t *enp,
__out boolean_t *supportedp);
+extern __checkReturn efx_rc_t
+efx_mcdi_mac_spoofing_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+
#if EFSYS_OPT_BIST
#if EFSYS_OPT_HUNTINGTON
extern __checkReturn efx_rc_t
@@ -355,6 +386,11 @@ efx_mcdi_get_loopback_modes(
#define MCDI_CMD_DWORD_FIELD(_edp, _field) \
EFX_DWORD_FIELD(*_edp, MC_CMD_ ## _field)
+#define EFX_MCDI_HAVE_PRIVILEGE(mask, priv) \
+ (((mask) & \
+ (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) == \
+ (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv))
+
#ifdef __cplusplus
}
#endif
diff --git a/sys/dev/sfxge/common/efx_types.h b/sys/dev/sfxge/common/efx_types.h
index ee357b1..f112a4c 100644
--- a/sys/dev/sfxge/common/efx_types.h
+++ b/sys/dev/sfxge/common/efx_types.h
@@ -1584,7 +1584,7 @@ extern int fix_lint;
#define EFX_OR_BYTE(_byte1, _byte2) \
do { \
- (_byte1).eb_u8[0] &= (_byte2).eb_u8[0]; \
+ (_byte1).eb_u8[0] |= (_byte2).eb_u8[0]; \
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
diff --git a/sys/dev/sfxge/common/hunt_ev.c b/sys/dev/sfxge/common/hunt_ev.c
index b5585bb..5e6ccab 100644
--- a/sys/dev/sfxge/common/hunt_ev.c
+++ b/sys/dev/sfxge/common/hunt_ev.c
@@ -829,6 +829,20 @@ hunt_ev_mcdi(
MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
break;
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+ case MCDI_EVENT_CODE_PROXY_RESPONSE:
+ /*
+ * This event notifies a function that an authorization request
+ * has been processed. If the request was authorized then the
+ * function can now re-send the original MCDI request.
+ * See SF-113652-SW "SR-IOV Proxied Network Access Control".
+ */
+ efx_mcdi_ev_proxy_response(enp,
+ MCDI_EV_FIELD(eqp, PROXY_RESPONSE_HANDLE),
+ MCDI_EV_FIELD(eqp, PROXY_RESPONSE_RC));
+ break;
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+
case MCDI_EVENT_CODE_LINKCHANGE: {
efx_link_mode_t link_mode;
diff --git a/sys/dev/sfxge/common/hunt_impl.h b/sys/dev/sfxge/common/hunt_impl.h
index 313912b..1a57596 100644
--- a/sys/dev/sfxge/common/hunt_impl.h
+++ b/sys/dev/sfxge/common/hunt_impl.h
@@ -298,6 +298,12 @@ hunt_mcdi_link_control_supported(
__in efx_nic_t *enp,
__out boolean_t *supportedp);
+extern __checkReturn efx_rc_t
+hunt_mcdi_mac_spoofing_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+
#endif /* EFSYS_OPT_MCDI */
/* NVRAM */
diff --git a/sys/dev/sfxge/common/hunt_mcdi.c b/sys/dev/sfxge/common/hunt_mcdi.c
index 592406f..11ad231 100644
--- a/sys/dev/sfxge/common/hunt_mcdi.c
+++ b/sys/dev/sfxge/common/hunt_mcdi.c
@@ -303,16 +303,8 @@ hunt_mcdi_read_response(
hunt_mcdi_request_poll(
__in efx_nic_t *enp)
{
-#if EFSYS_OPT_MCDI_LOGGING
- const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
-#endif /* EFSYS_OPT_MCDI_LOGGING */
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
efx_mcdi_req_t *emrp;
- efx_dword_t hdr[2];
- unsigned int hdr_len;
- unsigned int data_len;
- unsigned int seq;
- unsigned int cmd;
int state;
efx_rc_t rc;
@@ -332,101 +324,26 @@ hunt_mcdi_request_poll(
}
/* Read the response header */
- hdr_len = sizeof (hdr[0]);
- hunt_mcdi_read_response(enp, &hdr[0], 0, hdr_len);
-
- if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) {
- hunt_mcdi_read_response(enp, &hdr[1], hdr_len, sizeof (hdr[1]));
- hdr_len += sizeof (hdr[1]);
-
- cmd = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_EXTENDED_CMD);
- data_len =
- EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
- } else {
- cmd = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE);
- data_len = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_DATALEN);
- }
+ efx_mcdi_read_response_header(enp, emrp);
/* Request complete */
emip->emi_pending_req = NULL;
- seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ);
-
- /* Check for synchronous reboot */
- if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR) != 0 && data_len == 0) {
- /* The MC has rebooted since the request was sent. */
- EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
- hunt_mcdi_poll_reboot(enp);
-
- EFSYS_UNLOCK(enp->en_eslp, state);
- rc = EIO;
- goto fail1;
- }
/* Ensure stale MCDI requests fail after an MC reboot. */
emip->emi_new_epoch = B_FALSE;
EFSYS_UNLOCK(enp->en_eslp, state);
- /* Check that the returned data is consistent */
- if (cmd != emrp->emr_cmd ||
- EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_SEQ) != seq) {
- /* Response is for a different request */
- rc = EIO;
- goto fail2;
- }
- if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR)) {
- efx_dword_t err[2];
- unsigned int err_len = MIN(data_len, sizeof (err));
- int err_code = MC_CMD_ERR_EPROTO;
- int err_arg = 0;
-
- /* Read error code (and arg num for MCDI v2 commands) */
- hunt_mcdi_read_response(enp, &err[0], hdr_len, err_len);
-
- if (err_len >= MC_CMD_ERR_CODE_OFST + sizeof (efx_dword_t))
- err_code = EFX_DWORD_FIELD(err[0], EFX_DWORD_0);
-
- if (err_len >= MC_CMD_ERR_ARG_OFST + sizeof (efx_dword_t))
- err_arg = EFX_DWORD_FIELD(err[1], EFX_DWORD_0);
-
-#if EFSYS_OPT_MCDI_LOGGING
- if (emtp->emt_logger != NULL) {
- emtp->emt_logger(emtp->emt_context,
- EFX_LOG_MCDI_RESPONSE,
- &hdr, hdr_len,
- &err, err_len);
- }
-#endif /* EFSYS_OPT_MCDI_LOGGING */
-
- rc = efx_mcdi_request_errcode(err_code);
- if (!emrp->emr_quiet) {
- EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd,
- int, err_code, int, err_arg);
- }
- goto fail3;
-
- } else {
- emrp->emr_out_length_used = data_len;
- emrp->emr_rc = 0;
- hunt_mcdi_request_copyout(enp, emrp);
- }
+ if ((rc = emrp->emr_rc) != 0)
+ goto fail1;
+ hunt_mcdi_request_copyout(enp, emrp);
goto out;
-fail3:
- if (!emrp->emr_quiet)
- EFSYS_PROBE(fail3);
-fail2:
- if (!emrp->emr_quiet)
- EFSYS_PROBE(fail2);
fail1:
if (!emrp->emr_quiet)
EFSYS_PROBE1(fail1, efx_rc_t, rc);
- /* Fill out error state */
- emrp->emr_rc = rc;
- emrp->emr_out_length_used = 0;
-
/* Reboot/Assertion */
if (rc == EIO || rc == EINTR)
efx_mcdi_raise_exception(enp, emrp, rc);
@@ -495,9 +412,8 @@ hunt_mcdi_fw_update_supported(
* Admin privilege must be used prior to introduction of
* specific flag.
*/
- *supportedp = (encp->enc_privilege_mask &
- MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN)
- == MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN;
+ *supportedp =
+ EFX_MCDI_HAVE_PRIVILEGE(encp->enc_privilege_mask, ADMIN);
return (0);
}
@@ -515,18 +431,43 @@ hunt_mcdi_macaddr_change_supported(
/*
* Use privilege mask state at MCDI attach.
* Admin privilege must be used prior to introduction of
- * specific flag (at v4.6).
+ * mac spoofing privilege (at v4.6), which is used up to
+ * introduction of change mac spoofing privilege (at v4.7)
*/
*supportedp =
- ((privilege_mask & MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING) ==
- MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING) ||
- ((privilege_mask & MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN) ==
- MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN);
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, CHANGE_MAC) ||
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, MAC_SPOOFING) ||
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, ADMIN);
return (0);
}
__checkReturn efx_rc_t
+hunt_mcdi_mac_spoofing_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint32_t privilege_mask = encp->enc_privilege_mask;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /*
+ * Use privilege mask state at MCDI attach.
+ * Admin privilege must be used prior to introduction of
+ * mac spoofing privilege (at v4.6), which is used up to
+ * introduction of mac spoofing TX privilege (at v4.7)
+ */
+ *supportedp =
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, MAC_SPOOFING_TX) ||
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, MAC_SPOOFING) ||
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, ADMIN);
+
+ return (0);
+}
+
+
+ __checkReturn efx_rc_t
hunt_mcdi_link_control_supported(
__in efx_nic_t *enp,
__out boolean_t *supportedp)
@@ -542,10 +483,8 @@ hunt_mcdi_link_control_supported(
* specific flag.
*/
*supportedp =
- ((privilege_mask & MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK) ==
- MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK) ||
- ((privilege_mask & MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN) ==
- MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN);
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, LINK) ||
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, ADMIN);
return (0);
}
diff --git a/sys/dev/sfxge/common/siena_mcdi.c b/sys/dev/sfxge/common/siena_mcdi.c
index 64707ab..557bd54 100644
--- a/sys/dev/sfxge/common/siena_mcdi.c
+++ b/sys/dev/sfxge/common/siena_mcdi.c
@@ -222,15 +222,8 @@ siena_mcdi_read_response(
siena_mcdi_request_poll(
__in efx_nic_t *enp)
{
-#if EFSYS_OPT_MCDI_LOGGING
- const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
-#endif
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
efx_mcdi_req_t *emrp;
- efx_dword_t hdr;
- unsigned int hdr_len;
- unsigned int data_len;
- unsigned int seq;
int state;
efx_rc_t rc;
@@ -260,76 +253,19 @@ siena_mcdi_request_poll(
}
/* Read the response header */
- hdr_len = sizeof (hdr);
- siena_mcdi_read_response(enp, &hdr, 0, hdr_len);
+ efx_mcdi_read_response_header(enp, emrp);
/* Request complete */
emip->emi_pending_req = NULL;
- seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ);
-
- /* Check for synchronous reboot */
- if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_ERROR) != 0 &&
- EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN) == 0) {
- /* Consume status word */
- EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
- siena_mcdi_poll_reboot(enp);
- EFSYS_UNLOCK(enp->en_eslp, state);
- rc = EIO;
- goto fail2;
- }
EFSYS_UNLOCK(enp->en_eslp, state);
- /* Check that the returned data is consistent */
- if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_CODE) != emrp->emr_cmd ||
- EFX_DWORD_FIELD(hdr, MCDI_HEADER_SEQ) != seq) {
- /* Response is for a different request */
- rc = EIO;
- goto fail3;
- }
-
- data_len = EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN);
- if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_ERROR)) {
- efx_dword_t err;
- int err_code = MC_CMD_ERR_EPROTO;
- unsigned int err_len = MIN(data_len, sizeof (err));
-
- /* Read error code */
- siena_mcdi_read_response(enp, &err, hdr_len, err_len);
-
- if (err_len >= MC_CMD_ERR_CODE_OFST + sizeof (efx_dword_t))
- err_code = EFX_DWORD_FIELD(err, EFX_DWORD_0);
-
-#if EFSYS_OPT_MCDI_LOGGING
- if (emtp->emt_logger != NULL) {
- emtp->emt_logger(emtp->emt_context,
- EFX_LOG_MCDI_RESPONSE,
- &hdr, hdr_len,
- &err, err_len);
- }
-#endif /* EFSYS_OPT_MCDI_LOGGING */
-
- rc = efx_mcdi_request_errcode(err_code);
- if (!emrp->emr_quiet) {
- EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
- int, err_code);
- }
- goto fail4;
-
- } else {
- emrp->emr_out_length_used = data_len;
- emrp->emr_rc = 0;
- siena_mcdi_request_copyout(enp, emrp);
- }
+ if ((rc = emrp->emr_rc) != 0)
+ goto fail2;
+ siena_mcdi_request_copyout(enp, emrp);
goto out;
-fail4:
- if (!emrp->emr_quiet)
- EFSYS_PROBE(fail4);
-fail3:
- if (!emrp->emr_quiet)
- EFSYS_PROBE(fail3);
fail2:
if (!emrp->emr_quiet)
EFSYS_PROBE(fail2);
@@ -337,10 +273,6 @@ fail1:
if (!emrp->emr_quiet)
EFSYS_PROBE1(fail1, efx_rc_t, rc);
- /* Fill out error state */
- emrp->emr_rc = rc;
- emrp->emr_out_length_used = 0;
-
/* Reboot/Assertion */
if (rc == EIO || rc == EINTR)
efx_mcdi_raise_exception(enp, emrp, rc);
diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c
index d705267..78ead15 100644
--- a/sys/dev/usb/wlan/if_urtwn.c
+++ b/sys/dev/usb/wlan/if_urtwn.c
@@ -291,6 +291,7 @@ static void urtwn_set_gain(struct urtwn_softc *, uint8_t);
static void urtwn_scan_start(struct ieee80211com *);
static void urtwn_scan_end(struct ieee80211com *);
static void urtwn_set_channel(struct ieee80211com *);
+static int urtwn_wme_update(struct ieee80211com *);
static void urtwn_set_promisc(struct urtwn_softc *);
static void urtwn_update_promisc(struct ieee80211com *);
static void urtwn_update_mcast(struct ieee80211com *);
@@ -376,6 +377,16 @@ static const struct usb_config urtwn_config[URTWN_N_TRANSFER] = {
},
};
+static const struct wme_to_queue {
+ uint16_t reg;
+ uint8_t qid;
+} wme2queue[WME_NUM_AC] = {
+ { R92C_EDCA_BE_PARAM, URTWN_BULK_TX_BE},
+ { R92C_EDCA_BK_PARAM, URTWN_BULK_TX_BK},
+ { R92C_EDCA_VI_PARAM, URTWN_BULK_TX_VI},
+ { R92C_EDCA_VO_PARAM, URTWN_BULK_TX_VO}
+};
+
static int
urtwn_match(device_t self)
{
@@ -473,6 +484,7 @@ urtwn_attach(device_t self)
| IEEE80211_C_SHSLOT /* short slot time supported */
| IEEE80211_C_BGSCAN /* capable of bg scanning */
| IEEE80211_C_WPA /* 802.11i */
+ | IEEE80211_C_WME /* 802.11e */
;
bands = 0;
@@ -489,6 +501,7 @@ urtwn_attach(device_t self)
ic->ic_parent = urtwn_parent;
ic->ic_vap_create = urtwn_vap_create;
ic->ic_vap_delete = urtwn_vap_delete;
+ ic->ic_wme.wme_update = urtwn_wme_update;
ic->ic_update_promisc = urtwn_update_promisc;
ic->ic_update_mcast = urtwn_update_mcast;
@@ -2158,8 +2171,8 @@ urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct r92c_tx_desc *txd;
- uint8_t macid, raid, ridx, subtype, type, qsel;
- int ismcast;
+ uint8_t macid, raid, ridx, subtype, type, tid, qsel;
+ int hasqos, ismcast;
URTWN_ASSERT_LOCKED(sc);
@@ -2169,8 +2182,16 @@ urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
wh = mtod(m, struct ieee80211_frame *);
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+ hasqos = IEEE80211_QOS_HAS_SEQ(wh);
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
+ /* Select TX ring for this frame. */
+ if (hasqos) {
+ tid = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
+ tid &= IEEE80211_QOS_TID;
+ } else
+ tid = 0;
+
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
k = ieee80211_crypto_encap(ni, m);
if (k == NULL) {
@@ -2199,7 +2220,7 @@ urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
macid = URTWN_MACID_BSS;
if (type == IEEE80211_FC0_TYPE_DATA) {
- qsel = R92C_TXDW1_QSEL_BE;
+ qsel = tid % URTWN_MAX_TID;
if (!(m->m_flags & M_EAPOL)) {
if (ic->ic_curmode != IEEE80211_MODE_11B) {
@@ -2255,7 +2276,7 @@ urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
(m->m_flags & M_EAPOL))
txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
- if (!IEEE80211_QOS_HAS_SEQ(wh)) {
+ if (!hasqos) {
/* Use HW sequence numbering for non-QoS frames. */
if (sc->chip & URTWN_CHIP_88E)
txd->txdseq = htole16(R88E_TXDSEQ_HWSEQ_EN);
@@ -2292,12 +2313,6 @@ urtwn_tx_start(struct urtwn_softc *sc, struct mbuf *m, uint8_t type,
struct r92c_tx_desc *txd;
uint16_t ac, sum;
int i, xferlen;
- struct usb_xfer *urtwn_pipes[WME_NUM_AC] = {
- sc->sc_xfer[URTWN_BULK_TX_BE],
- sc->sc_xfer[URTWN_BULK_TX_BK],
- sc->sc_xfer[URTWN_BULK_TX_VI],
- sc->sc_xfer[URTWN_BULK_TX_VO]
- };
URTWN_ASSERT_LOCKED(sc);
@@ -2309,7 +2324,7 @@ urtwn_tx_start(struct urtwn_softc *sc, struct mbuf *m, uint8_t type,
xfer = sc->sc_xfer[URTWN_BULK_TX_VO];
break;
default:
- xfer = urtwn_pipes[ac];
+ xfer = sc->sc_xfer[wme2queue[ac].qid];
break;
}
@@ -3598,6 +3613,43 @@ urtwn_set_channel(struct ieee80211com *ic)
URTWN_UNLOCK(sc);
}
+static int
+urtwn_wme_update(struct ieee80211com *ic)
+{
+ const struct wmeParams *wmep =
+ ic->ic_wme.wme_chanParams.cap_wmeParams;
+ struct urtwn_softc *sc = ic->ic_softc;
+ uint8_t aifs, acm, slottime;
+ int ac;
+
+ acm = 0;
+ slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ?
+ IEEE80211_DUR_SHSLOT : IEEE80211_DUR_SLOT;
+
+ URTWN_LOCK(sc);
+ for (ac = WME_AC_BE; ac < WME_NUM_AC; ac++) {
+ /* AIFS[AC] = AIFSN[AC] * aSlotTime + aSIFSTime. */
+ aifs = wmep[ac].wmep_aifsn * slottime + IEEE80211_DUR_SIFS;
+ urtwn_write_4(sc, wme2queue[ac].reg,
+ SM(R92C_EDCA_PARAM_TXOP, wmep[ac].wmep_txopLimit) |
+ SM(R92C_EDCA_PARAM_ECWMIN, wmep[ac].wmep_logcwmin) |
+ SM(R92C_EDCA_PARAM_ECWMAX, wmep[ac].wmep_logcwmax) |
+ SM(R92C_EDCA_PARAM_AIFS, aifs));
+ if (ac != WME_AC_BE)
+ acm |= wmep[ac].wmep_acm << ac;
+ }
+
+ if (acm != 0)
+ acm |= R92C_ACMHWCTRL_EN;
+ urtwn_write_1(sc, R92C_ACMHWCTRL,
+ (urtwn_read_1(sc, R92C_ACMHWCTRL) & ~R92C_ACMHWCTRL_ACM_MASK) |
+ acm);
+
+ URTWN_UNLOCK(sc);
+
+ return 0;
+}
+
static void
urtwn_set_promisc(struct urtwn_softc *sc)
{
diff --git a/sys/dev/usb/wlan/if_urtwnreg.h b/sys/dev/usb/wlan/if_urtwnreg.h
index 75a65f7..993a00b 100644
--- a/sys/dev/usb/wlan/if_urtwnreg.h
+++ b/sys/dev/usb/wlan/if_urtwnreg.h
@@ -503,6 +503,13 @@
#define R92C_DUAL_TSF_RST0 0x01
#define R92C_DUAL_TSF_RST1 0x02
+/* Bits for R92C_ACMHWCTRL. */
+#define R92C_ACMHWCTRL_EN 0x01
+#define R92C_ACMHWCTRL_BE 0x02
+#define R92C_ACMHWCTRL_VI 0x04
+#define R92C_ACMHWCTRL_VO 0x08
+#define R92C_ACMHWCTRL_ACM_MASK 0x0f
+
/* Bits for R92C_APSD_CTRL. */
#define R92C_APSD_CTRL_OFF 0x40
#define R92C_APSD_CTRL_OFF_STATUS 0x80
diff --git a/sys/dev/usb/wlan/if_urtwnvar.h b/sys/dev/usb/wlan/if_urtwnvar.h
index 6e0b149..8901c75 100644
--- a/sys/dev/usb/wlan/if_urtwnvar.h
+++ b/sys/dev/usb/wlan/if_urtwnvar.h
@@ -140,7 +140,6 @@ struct urtwn_softc {
struct usb_device *sc_udev;
uint8_t sc_iface_index;
- int ac2idx[WME_NUM_AC];
u_int sc_flags;
#define URTWN_FLAG_CCK_HIPWR 0x01
#define URTWN_DETACHED 0x02
diff --git a/sys/netinet/cc/cc_cubic.c b/sys/netinet/cc/cc_cubic.c
index 17a6985..339ee6f 100644
--- a/sys/netinet/cc/cc_cubic.c
+++ b/sys/netinet/cc/cc_cubic.c
@@ -299,8 +299,10 @@ static void
cubic_post_recovery(struct cc_var *ccv)
{
struct cubic *cubic_data;
+ int pipe;
cubic_data = ccv->cc_data;
+ pipe = 0;
/* Fast convergence heuristic. */
if (cubic_data->max_cwnd < cubic_data->prev_max_cwnd)
@@ -315,10 +317,13 @@ cubic_post_recovery(struct cc_var *ccv)
*
* XXXLAS: Find a way to do this without needing curack
*/
- if (SEQ_GT(ccv->curack + CCV(ccv, snd_ssthresh),
- CCV(ccv, snd_max)))
- CCV(ccv, snd_cwnd) = CCV(ccv, snd_max) - ccv->curack +
- CCV(ccv, t_maxseg);
+ if (V_tcp_do_rfc6675_pipe)
+ pipe = tcp_compute_pipe(ccv->ccvc.tcp);
+ else
+ pipe = CCV(ccv, snd_max) - ccv->curack;
+
+ if (pipe < CCV(ccv, snd_ssthresh))
+ CCV(ccv, snd_cwnd) = pipe + CCV(ccv, t_maxseg);
else
/* Update cwnd based on beta and adjusted max_cwnd. */
CCV(ccv, snd_cwnd) = max(1, ((CUBIC_BETA *
diff --git a/sys/netinet/cc/cc_newreno.c b/sys/netinet/cc/cc_newreno.c
index 96d64fe..31b70cc 100644
--- a/sys/netinet/cc/cc_newreno.c
+++ b/sys/netinet/cc/cc_newreno.c
@@ -214,6 +214,9 @@ newreno_cong_signal(struct cc_var *ccv, uint32_t type)
static void
newreno_post_recovery(struct cc_var *ccv)
{
+ int pipe;
+ pipe = 0;
+
if (IN_FASTRECOVERY(CCV(ccv, t_flags))) {
/*
* Fast recovery will conclude after returning from this
@@ -224,10 +227,13 @@ newreno_post_recovery(struct cc_var *ccv)
*
* XXXLAS: Find a way to do this without needing curack
*/
- if (SEQ_GT(ccv->curack + CCV(ccv, snd_ssthresh),
- CCV(ccv, snd_max)))
- CCV(ccv, snd_cwnd) = CCV(ccv, snd_max) -
- ccv->curack + CCV(ccv, t_maxseg);
+ if (V_tcp_do_rfc6675_pipe)
+ pipe = tcp_compute_pipe(ccv->ccvc.tcp);
+ else
+ pipe = CCV(ccv, snd_max) - ccv->curack;
+
+ if (pipe < CCV(ccv, snd_ssthresh))
+ CCV(ccv, snd_cwnd) = pipe + CCV(ccv, t_maxseg);
else
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
}
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 1dfa244..72c2a60 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <net/vnet.h>
#include <netinet/in.h>
+#include <netinet/in_fib.h>
#include <netinet/in_var.h>
#include <net/if_llatbl.h>
#include <netinet/if_ether.h>
@@ -671,7 +672,6 @@ in_arpinput(struct mbuf *m)
struct arphdr *ah;
struct ifnet *ifp = m->m_pkthdr.rcvif;
struct llentry *la = NULL, *la_tmp;
- struct rtentry *rt;
struct ifaddr *ifa;
struct in_ifaddr *ia;
struct sockaddr sa;
@@ -682,6 +682,8 @@ in_arpinput(struct mbuf *m)
int carped;
struct sockaddr_in sin;
struct sockaddr *dst;
+ struct nhop4_basic nh4;
+
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = 0;
@@ -921,10 +923,8 @@ reply:
if (!V_arp_proxyall)
goto drop;
- sin.sin_addr = itaddr;
/* XXX MRT use table 0 for arp reply */
- rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
- if (!rt)
+ if (fib4_lookup_nh_basic(0, itaddr, 0, 0, &nh4) != 0)
goto drop;
/*
@@ -932,11 +932,8 @@ reply:
* as this one came out of, or we'll get into a fight
* over who claims what Ether address.
*/
- if (!rt->rt_ifp || rt->rt_ifp == ifp) {
- RTFREE_LOCKED(rt);
+ if (nh4.nh_ifp == ifp)
goto drop;
- }
- RTFREE_LOCKED(rt);
(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
(void)memcpy(ar_sha(ah), enaddr, ah->ar_hln);
@@ -947,21 +944,16 @@ reply:
* avoids ARP chaos if an interface is connected to the
* wrong network.
*/
- sin.sin_addr = isaddr;
/* XXX MRT use table 0 for arp checks */
- rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, 0);
- if (!rt)
+ if (fib4_lookup_nh_basic(0, isaddr, 0, 0, &nh4) != 0)
goto drop;
- if (rt->rt_ifp != ifp) {
+ if (nh4.nh_ifp != ifp) {
ARP_LOG(LOG_INFO, "proxy: ignoring request"
- " from %s via %s, expecting %s\n",
- inet_ntoa(isaddr), ifp->if_xname,
- rt->rt_ifp->if_xname);
- RTFREE_LOCKED(rt);
+ " from %s via %s\n",
+ inet_ntoa(isaddr), ifp->if_xname);
goto drop;
}
- RTFREE_LOCKED(rt);
#ifdef DEBUG_PROXY
printf("arp: proxying for %s\n", inet_ntoa(itaddr));
diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c
index 5c65ce0..f2a985b 100644
--- a/sys/netinet/in_mcast.c
+++ b/sys/netinet/in_mcast.c
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#include <netinet/in_fib.h>
#include <netinet/in_pcb.h>
#include <netinet/in_var.h>
#include <netinet/ip_var.h>
@@ -1883,6 +1884,8 @@ inp_lookup_mcast_ifp(const struct inpcb *inp,
{
struct rm_priotracker in_ifa_tracker;
struct ifnet *ifp;
+ struct nhop4_basic nh4;
+ uint32_t fibnum;
KASSERT(gsin->sin_family == AF_INET, ("%s: not AF_INET", __func__));
KASSERT(IN_MULTICAST(ntohl(gsin->sin_addr.s_addr)),
@@ -1892,16 +1895,10 @@ inp_lookup_mcast_ifp(const struct inpcb *inp,
if (!in_nullhost(ina)) {
INADDR_TO_IFP(ina, ifp);
} else {
- struct route ro;
-
- ro.ro_rt = NULL;
- memcpy(&ro.ro_dst, gsin, sizeof(struct sockaddr_in));
- in_rtalloc_ign(&ro, 0, inp ? inp->inp_inc.inc_fibnum : 0);
- if (ro.ro_rt != NULL) {
- ifp = ro.ro_rt->rt_ifp;
- KASSERT(ifp != NULL, ("%s: null ifp", __func__));
- RTFREE(ro.ro_rt);
- } else {
+ fibnum = inp ? inp->inp_inc.inc_fibnum : 0;
+ if (fib4_lookup_nh_basic(fibnum, gsin->sin_addr, 0, 0, &nh4)==0)
+ ifp = nh4.nh_ifp;
+ else {
struct in_ifaddr *ia;
struct ifnet *mifp;
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 57553f5..6e6202a 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <net/vnet.h>
#include <netinet/in.h>
+#include <netinet/in_fib.h>
#include <netinet/in_pcb.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
@@ -655,6 +656,7 @@ icmp_reflect(struct mbuf *m)
struct ifnet *ifp;
struct in_ifaddr *ia;
struct in_addr t;
+ struct nhop4_extended nh_ext;
struct mbuf *opts = 0;
int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
@@ -748,14 +750,12 @@ icmp_reflect(struct mbuf *m)
* When we don't have a route back to the packet source, stop here
* and drop the packet.
*/
- ia = ip_rtaddr(ip->ip_dst, M_GETFIB(m));
- if (ia == NULL) {
+ if (fib4_lookup_nh_ext(M_GETFIB(m), ip->ip_dst, 0, 0, &nh_ext) != 0) {
m_freem(m);
ICMPSTAT_INC(icps_noroute);
goto done;
}
- t = IA_SIN(ia)->sin_addr;
- ifa_free(&ia->ia_ifa);
+ t = nh_ext.nh_src;
match:
#ifdef MAC
mac_netinet_icmp_replyinplace(m);
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index edcafd5..6f25e08 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -878,33 +878,6 @@ ipproto_unregister(short ipproto)
return (0);
}
-/*
- * Given address of next destination (final or next hop), return (referenced)
- * internet address info of interface to be used to get there.
- */
-struct in_ifaddr *
-ip_rtaddr(struct in_addr dst, u_int fibnum)
-{
- struct route sro;
- struct sockaddr_in *sin;
- struct in_ifaddr *ia;
-
- bzero(&sro, sizeof(sro));
- sin = (struct sockaddr_in *)&sro.ro_dst;
- sin->sin_family = AF_INET;
- sin->sin_len = sizeof(*sin);
- sin->sin_addr = dst;
- in_rtalloc_ign(&sro, 0, fibnum);
-
- if (sro.ro_rt == NULL)
- return (NULL);
-
- ia = ifatoia(sro.ro_rt->rt_ifa);
- ifa_ref(&ia->ia_ifa);
- RTFREE(sro.ro_rt);
- return (ia);
-}
-
u_char inetctlerrmap[PRC_NCMDS] = {
0, 0, 0, 0,
0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH,
diff --git a/sys/netinet/ip_options.c b/sys/netinet/ip_options.c
index 6db9c91..5daf653 100644
--- a/sys/netinet/ip_options.c
+++ b/sys/netinet/ip_options.c
@@ -290,15 +290,19 @@ dropit:
* destination, use the incoming interface (should be
* same).
*/
- if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == NULL &&
- (ia = ip_rtaddr(ipaddr.sin_addr, M_GETFIB(m))) == NULL) {
+ if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) != NULL) {
+ memcpy(cp + off, &(IA_SIN(ia)->sin_addr),
+ sizeof(struct in_addr));
+ ifa_free(&ia->ia_ifa);
+ } else if (fib4_lookup_nh_ext(M_GETFIB(m),
+ ipaddr.sin_addr, 0, 0, &nh_ext) == 0) {
+ memcpy(cp + off, &nh_ext.nh_src,
+ sizeof(struct in_addr));
+ } else {
type = ICMP_UNREACH;
code = ICMP_UNREACH_HOST;
goto bad;
}
- (void)memcpy(cp + off, &(IA_SIN(ia)->sin_addr),
- sizeof(struct in_addr));
- ifa_free(&ia->ia_ifa);
cp[IPOPT_OFFSET] += sizeof(struct in_addr);
break;
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 3416805..f4ad4ff 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -222,8 +222,6 @@ int ipproto_register(short);
int ipproto_unregister(short);
struct mbuf *
ip_reass(struct mbuf *);
-struct in_ifaddr *
- ip_rtaddr(struct in_addr, u_int fibnum);
void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
struct mbuf *);
void ip_slowtimo(void);
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 652ca07..a298edf 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -78,6 +78,7 @@ struct sackhint {
* Total sacked bytes reported by the
* receiver via sack option
*/
+ uint32_t _pad1[1]; /* TBD */
uint64_t _pad[1]; /* TBD */
};
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index c918e69..f0c5371 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -100,6 +100,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/icmp6.h>
#include <netinet/tcp_var.h>
+#include <netinet6/in6_fib.h>
#include <netinet6/in6_ifattach.h>
#include <netinet6/in6_pcb.h>
#include <netinet6/ip6protosw.h>
@@ -2289,7 +2290,6 @@ icmp6_redirect_input(struct mbuf *m, int off)
int icmp6len = ntohs(ip6->ip6_plen);
char *lladdr = NULL;
int lladdrlen = 0;
- struct rtentry *rt = NULL;
int is_router;
int is_onlink;
struct in6_addr src6 = ip6->ip6_src;
@@ -2344,18 +2344,13 @@ icmp6_redirect_input(struct mbuf *m, int off)
}
{
/* ip6->ip6_src must be equal to gw for icmp6->icmp6_reddst */
- struct sockaddr_in6 sin6;
- struct in6_addr *gw6;
-
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- bcopy(&reddst6, &sin6.sin6_addr, sizeof(reddst6));
- rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, 0UL, RT_DEFAULT_FIB);
- if (rt) {
- if (rt->rt_gateway == NULL ||
- rt->rt_gateway->sa_family != AF_INET6) {
- RTFREE_LOCKED(rt);
+ struct nhop6_basic nh6;
+ struct in6_addr kdst;
+ uint32_t scopeid;
+
+ in6_splitscope(&reddst6, &kdst, &scopeid);
+ if (fib6_lookup_nh_basic(RT_DEFAULT_FIB, &kdst, scopeid, 0, 0,&nh6)==0){
+ if ((nh6.nh_flags & NHF_GATEWAY) == 0) {
nd6log((LOG_ERR,
"ICMP6 redirect rejected; no route "
"with inet6 gateway found for redirect dst: %s\n",
@@ -2363,14 +2358,12 @@ icmp6_redirect_input(struct mbuf *m, int off)
goto bad;
}
- gw6 = &(((struct sockaddr_in6 *)rt->rt_gateway)->sin6_addr);
- if (bcmp(&src6, gw6, sizeof(struct in6_addr)) != 0) {
- RTFREE_LOCKED(rt);
+ if (IN6_ARE_ADDR_EQUAL(&src6, &nh6.nh_addr) == 0) {
nd6log((LOG_ERR,
"ICMP6 redirect rejected; "
"not equal to gw-for-src=%s (must be same): "
"%s\n",
- ip6_sprintf(ip6buf, gw6),
+ ip6_sprintf(ip6buf, &nh6.nh_addr),
icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
goto bad;
}
@@ -2381,8 +2374,6 @@ icmp6_redirect_input(struct mbuf *m, int off)
icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
goto bad;
}
- RTFREE_LOCKED(rt);
- rt = NULL;
}
if (IN6_IS_ADDR_MULTICAST(&reddst6)) {
nd6log((LOG_ERR,
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index cae186d..b168a53 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -107,6 +107,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/ip6_mroute.h>
#include <netinet6/in6_ifattach.h>
#include <netinet6/scope6_var.h>
+#include <netinet6/in6_fib.h>
#include <netinet6/in6_pcb.h>
VNET_DECLARE(int, icmp6_nodeinfo_oldmcprefix);
@@ -2144,17 +2145,22 @@ in6_lltable_rtcheck(struct ifnet *ifp,
u_int flags,
const struct sockaddr *l3addr)
{
- struct rtentry *rt;
+ const struct sockaddr_in6 *sin6;
+ struct nhop6_basic nh6;
+ struct in6_addr dst;
+ uint32_t scopeid;
+ int error;
char ip6buf[INET6_ADDRSTRLEN];
KASSERT(l3addr->sa_family == AF_INET6,
("sin_family %d", l3addr->sa_family));
/* Our local addresses are always only installed on the default FIB. */
- /* XXX rtalloc1 should take a const param */
- rt = in6_rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0,
- RT_DEFAULT_FIB);
- if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) || rt->rt_ifp != ifp) {
+
+ sin6 = (const struct sockaddr_in6 *)l3addr;
+ in6_splitscope(&sin6->sin6_addr, &dst, &scopeid);
+ error = fib6_lookup_nh_basic(RT_DEFAULT_FIB, &dst, scopeid, 0, 0, &nh6);
+ if (error != 0 || (nh6.nh_flags & NHF_GATEWAY) || nh6.nh_ifp != ifp) {
struct ifaddr *ifa;
/*
* Create an ND6 cache for an IPv6 neighbor
@@ -2163,17 +2169,12 @@ in6_lltable_rtcheck(struct ifnet *ifp,
ifa = ifaof_ifpforaddr(l3addr, ifp);
if (ifa != NULL) {
ifa_free(ifa);
- if (rt != NULL)
- RTFREE_LOCKED(rt);
return 0;
}
log(LOG_INFO, "IPv6 address: \"%s\" is not on the network\n",
- ip6_sprintf(ip6buf, &((const struct sockaddr_in6 *)l3addr)->sin6_addr));
- if (rt != NULL)
- RTFREE_LOCKED(rt);
+ ip6_sprintf(ip6buf, &sin6->sin6_addr));
return EINVAL;
}
- RTFREE_LOCKED(rt);
return 0;
}
diff --git a/sys/netinet6/in6_fib.c b/sys/netinet6/in6_fib.c
index 70bd1772..eba5b7c 100644
--- a/sys/netinet6/in6_fib.c
+++ b/sys/netinet6/in6_fib.c
@@ -164,6 +164,7 @@ fib6_rte_to_nh_extended(struct rtentry *rte, const struct in6_addr *dst,
* interface "ix0" pointer to "ix0" interface will be returned instead
* of "lo0")
* - howewer mtu from "transmit" interface will be returned.
+ * - scope will be embedded in nh_addr
*/
int
fib6_lookup_nh_basic(uint32_t fibnum, const struct in6_addr *dst, uint32_t scopeid,
@@ -182,6 +183,7 @@ fib6_lookup_nh_basic(uint32_t fibnum, const struct in6_addr *dst, uint32_t scope
/* Prepare lookup key */
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_addr = *dst;
+ sin6.sin6_len = sizeof(struct sockaddr_in6);
/* Assume scopeid is valid and embed it directly */
if (IN6_IS_SCOPE_LINKLOCAL(dst))
sin6.sin6_addr.s6_addr16[1] = htons(scopeid & 0xffff);
@@ -192,7 +194,7 @@ fib6_lookup_nh_basic(uint32_t fibnum, const struct in6_addr *dst, uint32_t scope
rte = RNTORT(rn);
/* Ensure route & ifp is UP */
if (RT_LINK_IS_UP(rte->rt_ifp)) {
- fib6_rte_to_nh_basic(rte, dst, flags, pnh6);
+ fib6_rte_to_nh_basic(rte, &sin6.sin6_addr, flags, pnh6);
RADIX_NODE_HEAD_RUNLOCK(rh);
return (0);
}
@@ -211,6 +213,7 @@ fib6_lookup_nh_basic(uint32_t fibnum, const struct in6_addr *dst, uint32_t scope
* - nh_ifp represents logical transmit interface (rt_ifp) by default
* - nh_ifp represents "address" interface if NHR_IFAIF flag is passed
* - mtu from logical transmit interface will be returned.
+ * - scope will be embedded in nh_addr
*/
int
fib6_lookup_nh_ext(uint32_t fibnum, const struct in6_addr *dst,uint32_t scopeid,
@@ -240,7 +243,8 @@ fib6_lookup_nh_ext(uint32_t fibnum, const struct in6_addr *dst,uint32_t scopeid,
rte = RNTORT(rn);
/* Ensure route & ifp is UP */
if (RT_LINK_IS_UP(rte->rt_ifp)) {
- fib6_rte_to_nh_extended(rte, dst, flags, pnh6);
+ fib6_rte_to_nh_extended(rte, &sin6.sin6_addr, flags,
+ pnh6);
if ((flags & NHR_REF) != 0) {
/* TODO: Do lwref on egress ifp's */
}
diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c
index 76ab400..e6901ba 100644
--- a/sys/netinet6/in6_gif.c
+++ b/sys/netinet6/in6_gif.c
@@ -205,10 +205,10 @@ in6_gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
/* ingress filters on outer source */
if ((GIF2IFP(sc)->if_flags & IFF_LINK2) == 0) {
struct nhop6_basic nh6;
- struct in6_addr *dst;
/* XXX empty scope id */
- if (fib6_lookup_nh_basic(sc->gif_fibnum, dst, 0, 0, 0, &nh6)!=0)
+ if (fib6_lookup_nh_basic(sc->gif_fibnum, &ip6->ip6_src, 0, 0, 0,
+ &nh6) != 0)
return (0);
if (nh6.nh_ifp != m->m_pkthdr.rcvif)
diff --git a/sys/netinet6/in6_mcast.c b/sys/netinet6/in6_mcast.c
index 131130f..9d96cf5 100644
--- a/sys/netinet6/in6_mcast.c
+++ b/sys/netinet6/in6_mcast.c
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <netinet/in_var.h>
+#include <netinet6/in6_fib.h>
#include <netinet6/in6_var.h>
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
@@ -1772,26 +1773,22 @@ static struct ifnet *
in6p_lookup_mcast_ifp(const struct inpcb *in6p,
const struct sockaddr_in6 *gsin6)
{
- struct route_in6 ro6;
- struct ifnet *ifp;
+ struct nhop6_basic nh6;
+ struct in6_addr dst;
+ uint32_t scopeid;
+ uint32_t fibnum;
KASSERT(in6p->inp_vflag & INP_IPV6,
("%s: not INP_IPV6 inpcb", __func__));
KASSERT(gsin6->sin6_family == AF_INET6,
("%s: not AF_INET6 group", __func__));
- ifp = NULL;
- memset(&ro6, 0, sizeof(struct route_in6));
- memcpy(&ro6.ro_dst, gsin6, sizeof(struct sockaddr_in6));
- rtalloc_ign_fib((struct route *)&ro6, 0,
- in6p ? in6p->inp_inc.inc_fibnum : RT_DEFAULT_FIB);
- if (ro6.ro_rt != NULL) {
- ifp = ro6.ro_rt->rt_ifp;
- KASSERT(ifp != NULL, ("%s: null ifp", __func__));
- RTFREE(ro6.ro_rt);
- }
+ in6_splitscope(&gsin6->sin6_addr, &dst, &scopeid);
+ fibnum = in6p ? in6p->inp_inc.inc_fibnum : RT_DEFAULT_FIB;
+ if (fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6) != 0)
+ return (NULL);
- return (ifp);
+ return (nh6.nh_ifp);
}
/*
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index 020c5cf..c2e26f8f 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -105,6 +105,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/in6_var.h>
#include <netinet/ip6.h>
+#include <netinet6/in6_fib.h>
#include <netinet6/in6_pcb.h>
#include <netinet6/ip6_var.h>
#include <netinet6/scope6_var.h>
@@ -860,19 +861,16 @@ in6_selecthlim(struct inpcb *in6p, struct ifnet *ifp)
else if (ifp)
return (ND_IFINFO(ifp)->chlim);
else if (in6p && !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
- struct route_in6 ro6;
- struct ifnet *lifp;
-
- bzero(&ro6, sizeof(ro6));
- ro6.ro_dst.sin6_family = AF_INET6;
- ro6.ro_dst.sin6_len = sizeof(struct sockaddr_in6);
- ro6.ro_dst.sin6_addr = in6p->in6p_faddr;
- in6_rtalloc(&ro6, in6p->inp_inc.inc_fibnum);
- if (ro6.ro_rt) {
- lifp = ro6.ro_rt->rt_ifp;
- RTFREE(ro6.ro_rt);
- if (lifp)
- return (ND_IFINFO(lifp)->chlim);
+ struct nhop6_basic nh6;
+ struct in6_addr dst;
+ uint32_t fibnum, scopeid;
+ int hlim;
+
+ fibnum = in6p->inp_inc.inc_fibnum;
+ in6_splitscope(&in6p->in6p_faddr, &dst, &scopeid);
+ if (fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6)==0){
+ hlim = ND_IFINFO(nh6.nh_ifp)->chlim;
+ return (hlim);
}
}
return (V_ip6_defhlim);
diff --git a/tools/tools/ioat/ioatcontrol.8 b/tools/tools/ioat/ioatcontrol.8
index 2306d38..002759f 100644
--- a/tools/tools/ioat/ioatcontrol.8
+++ b/tools/tools/ioat/ioatcontrol.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 28, 2015
+.Dd December 9, 2015
.Dt IOATCONTROL 8
.Os
.Sh NAME
@@ -33,7 +33,9 @@
.Xr ioat 4
.Sh SYNOPSIS
.Nm
+.Op Fl E
.Op Fl f
+.Op Fl m
.Op Fl V
.Ar channel_number
.Ar num_txns
@@ -55,10 +57,14 @@ allows one to issue some number of test operations to the
driver on a specific hardware channel.
The arguments are as follows:
.Bl -tag -width Ds
+.It Fl E
+Test non-contiguous 8k copy.
.It Fl f
Test block fill (by default,
.Nm
tests copy)
+.It Fl m
+Test memcpy instead of DMA.
.It Fl V
Verify copies/fills for accuracy
.El
diff --git a/tools/tools/ioat/ioatcontrol.c b/tools/tools/ioat/ioatcontrol.c
index 90255e7..d40ae15 100644
--- a/tools/tools/ioat/ioatcontrol.c
+++ b/tools/tools/ioat/ioatcontrol.c
@@ -48,7 +48,7 @@ static void
usage(void)
{
- printf("Usage: %s [-fV] <channel #> <txns> [<bufsize> "
+ printf("Usage: %s [-E|-f|-m] [-V] <channel #> <txns> [<bufsize> "
"[<chain-len> [duration]]]\n", getprogname());
printf(" %s -r [-vV] <channel #> <addr> [<bufsize>]\n",
getprogname());
@@ -97,15 +97,29 @@ main(int argc, char **argv)
{
struct ioat_test t;
int fd, ch;
- bool fflag, rflag;
+ bool fflag, rflag, Eflag, mflag;
+ unsigned modeflags;
- while ((ch = getopt(argc, argv, "rfvVw")) != -1) {
+ fflag = rflag = Eflag = mflag = false;
+ modeflags = 0;
+
+ while ((ch = getopt(argc, argv, "EfmrvVw")) != -1) {
switch (ch) {
+ case 'E':
+ Eflag = true;
+ modeflags++;
+ break;
case 'f':
fflag = true;
+ modeflags++;
+ break;
+ case 'm':
+ mflag = true;
+ modeflags++;
break;
case 'r':
rflag = true;
+ modeflags++;
break;
case 'v':
t.raw_is_virtual = true;
@@ -126,8 +140,8 @@ main(int argc, char **argv)
if (argc < 2)
usage();
- if (rflag && fflag) {
- printf("Invalid: -r and -f\n");
+ if (modeflags > 1) {
+ printf("Invalid: Cannot use >1 mode flag (-E, -f, -m, or -r)\n");
usage();
}
@@ -139,6 +153,11 @@ main(int argc, char **argv)
if (fflag)
t.testkind = IOAT_TEST_FILL;
+ else if (Eflag) {
+ t.testkind = IOAT_TEST_DMA_8K;
+ t.buffer_size = 8 * 1024;
+ } else if (mflag)
+ t.testkind = IOAT_TEST_MEMCPY;
t.channel_index = atoi(argv[0]);
if (t.channel_index > 8) {
diff --git a/usr.bin/clang/lldb/Makefile b/usr.bin/clang/lldb/Makefile
index 7a052a7..1b014e6 100644
--- a/usr.bin/clang/lldb/Makefile
+++ b/usr.bin/clang/lldb/Makefile
@@ -161,6 +161,6 @@ LIBDEPS=\
llvmcore \
llvmsupport
-.include "../clang.prog.mk"
+LIBADD+= pthread
-LDADD+= -lpthread
+.include "../clang.prog.mk"
diff --git a/usr.sbin/iostat/iostat.c b/usr.sbin/iostat/iostat.c
index 195e59c..170ce0d 100644
--- a/usr.sbin/iostat/iostat.c
+++ b/usr.sbin/iostat/iostat.c
@@ -110,6 +110,7 @@
#include <limits.h>
#include <math.h>
#include <nlist.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -135,6 +136,8 @@ struct device_selection *dev_select;
int maxshowdevs;
volatile sig_atomic_t headercount;
volatile sig_atomic_t wresized; /* Tty resized, when non-zero. */
+volatile sig_atomic_t alarm_rang;
+volatile sig_atomic_t return_requested;
unsigned short wrows; /* Current number of tty rows. */
int dflag = 0, Iflag = 0, Cflag = 0, Tflag = 0, oflag = 0, Kflag = 0;
int xflag = 0, zflag = 0;
@@ -143,6 +146,8 @@ int xflag = 0, zflag = 0;
static void usage(void);
static void needhdr(int signo);
static void needresize(int signo);
+static void needreturn(int signo);
+static void alarm_clock(int signo);
static void doresize(void);
static void phdr(void);
static void devstats(int perf_select, long double etime, int havelast);
@@ -172,6 +177,7 @@ main(int argc, char **argv)
int count = 0, waittime = 0;
char *memf = NULL, *nlistf = NULL;
struct devstat_match *matches;
+ struct itimerval alarmspec;
int num_matches = 0;
char errbuf[_POSIX2_LINE_MAX];
kvm_t *kd = NULL;
@@ -442,10 +448,28 @@ main(int argc, char **argv)
wrows = IOSTAT_DEFAULT_ROWS;
}
+ /*
+ * Register a SIGINT handler so that we can print out final statistics
+ * when we get that signal
+ */
+ (void)signal(SIGINT, needreturn);
+
+ /*
+ * Register a SIGALRM handler to implement sleeps if the user uses the
+ * -c or -w options
+ */
+ (void)signal(SIGALRM, alarm_clock);
+ alarmspec.it_interval.tv_sec = waittime / 1000;
+ alarmspec.it_interval.tv_usec = 1000 * (waittime % 1000);
+ alarmspec.it_value.tv_sec = waittime / 1000;
+ alarmspec.it_value.tv_usec = 1000 * (waittime % 1000);
+ setitimer(ITIMER_REAL, &alarmspec, NULL);
+
for (headercount = 1;;) {
struct devinfo *tmp_dinfo;
long tmp;
long double etime;
+ sigset_t sigmask, oldsigmask;
if (Tflag > 0) {
if ((readvar(kd, "kern.tty_nin", X_TTY_NIN, &cur.tk_nin,
@@ -599,10 +623,23 @@ main(int argc, char **argv)
}
fflush(stdout);
- if (count >= 0 && --count <= 0)
+ if ((count >= 0 && --count <= 0) || return_requested)
break;
- usleep(waittime * 1000);
+ /*
+ * Use sigsuspend to safely sleep until either signal is
+ * received
+ */
+ alarm_rang = 0;
+ sigemptyset(&sigmask);
+ sigaddset(&sigmask, SIGINT);
+ sigaddset(&sigmask, SIGALRM);
+ sigprocmask(SIG_BLOCK, &sigmask, &oldsigmask);
+ while (! (alarm_rang || return_requested) ) {
+ sigsuspend(&oldsigmask);
+ }
+ sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
+
havelast = 1;
}
@@ -633,6 +670,24 @@ needresize(int signo)
}
/*
+ * Record the alarm so the main loop can break its sleep
+ */
+void
+alarm_clock(int signo)
+{
+ alarm_rang = 1;
+}
+
+/*
+ * Request that the main loop exit soon
+ */
+void
+needreturn(int signo)
+{
+ return_requested = 1;
+}
+
+/*
* Update the global `wrows' count of terminal rows.
*/
void
diff --git a/usr.sbin/pmcstudy/pmcstudy.8 b/usr.sbin/pmcstudy/pmcstudy.8
index 4ddb3e4..7c03897 100644
--- a/usr.sbin/pmcstudy/pmcstudy.8
+++ b/usr.sbin/pmcstudy/pmcstudy.8
@@ -32,7 +32,7 @@
.Nd Perform various studies on a system's overall PMCs.
.Sh SYNOPSIS
.Nm
-.Oo Fl i Ar inputfile | Fl T | Fl v | Fl m Ar max | Fl e exp | Fl Ar E | Fl h | fl H Oc
+.Oo Fl i Ar inputfile | Fl A | Fl T | Fl v | Fl m Ar max | Fl e exp | Fl Ar E | Fl h | fl H Oc
.Nm
.Fl i Ar inputfile
.Nm
@@ -59,8 +59,8 @@ PMCs and then run various formulas on the output information.
These formulas can be found in Intel documentation "Using Intel Vtune
amplifier xe on NNN Generation Intel Core Processors".
The NNN is either
-2nd, 3rd or 4th generation i.e., Sandy Bridge, Ivy Bridge and Haswell.
-Currently the program only works on these three Intel processor types.
+2nd, 3rd, 4th or 5th generation i.e., Sandy Bridge, Ivy Bridge, Haswell and Broadwell.
+Currently the program only works on these four Intel processor types.
.Sh OPTIONS
The following options are available:
.Bl -tag -width indent
@@ -128,6 +128,8 @@ test like
"UOPS_RETIRED.RETIRE_SLOTS / (4 * CPU_CLK_UNHALTED.THREAD_P)".
.It Fl L
This option will list all known PMCs and their abbreviation (%NNN).
+.It Fl A
+Run all canned tests.
.El
.Sh SEE ALSO
.Xr pmc 3 ,
diff --git a/usr.sbin/pmcstudy/pmcstudy.c b/usr.sbin/pmcstudy/pmcstudy.c
index 1a3da45..16c9f51 100644
--- a/usr.sbin/pmcstudy/pmcstudy.c
+++ b/usr.sbin/pmcstudy/pmcstudy.c
@@ -38,6 +38,9 @@
#include "eval_expr.h"
__FBSDID("$FreeBSD$");
+static int max_pmc_counters = 1;
+static int run_all = 0;
+
#define MAX_COUNTER_SLOTS 1024
#define MAX_NLEN 64
#define MAX_CPU 64
@@ -191,9 +194,9 @@ struct cpu_entry {
const char *thresh;
const char *command;
int (*func)(struct counters *, int);
+ int counters_required;
};
-
struct cpu_type {
char cputype[32];
int number;
@@ -217,10 +220,10 @@ explain_name_sb(const char *name)
printf("Examine (20 * BR_MISP_RETIRED.ALL_BRANCHES)/CPU_CLK_UNHALTED.THREAD_P\n");
mythresh = "thresh >= .2";
} else if (strcmp(name, "splitload") == 0) {
- printf("Examine MEM_UOP_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P\n");
+ printf("Examine MEM_UOPS_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P\n");
mythresh = "thresh >= .1";
} else if (strcmp(name, "splitstore") == 0) {
- printf("Examine MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES\n");
+ printf("Examine MEM_UOPS_RETIRED.SPLIT_STORES / MEM_UOPS_RETIRED.ALL_STORES\n");
mythresh = "thresh >= .01";
} else if (strcmp(name, "contested") == 0) {
printf("Examine (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60) / CPU_CLK_UNHALTED.THREAD_P\n");
@@ -323,7 +326,7 @@ explain_name_ib(const char *name)
printf(" LD_BLOCKS.NO_SR)/CPU_CLK_UNHALTED.THREAD_P\n");
mythresh = "thresh >= .1";
} else if (strcmp(name, "splitstore") == 0) {
- printf("Examine MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES\n");
+ printf("Examine MEM_UOPS_RETIRED.SPLIT_STORES / MEM_UOPS_RETIRED.ALL_STORES\n");
mythresh = "thresh >= .01";
} else if (strcmp(name, "aliasing_4k") == 0) {
printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P\n");
@@ -403,10 +406,10 @@ explain_name_has(const char *name)
printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n");
mythresh = "thresh >= .05";
} else if (strcmp(name, "splitload") == 0) {
- printf("Examine (MEM_UOP_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P\n");
+ printf("Examine (MEM_UOPS_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P\n");
mythresh = "thresh >= .1";
} else if (strcmp(name, "splitstore") == 0) {
- printf("Examine MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES\n");
+ printf("Examine MEM_UOPS_RETIRED.SPLIT_STORES / MEM_UOPS_RETIRED.ALL_STORES\n");
mythresh = "thresh >= .01";
} else if (strcmp(name, "aliasing_4k") == 0) {
printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P\n");
@@ -444,6 +447,7 @@ explain_name_has(const char *name)
}
+
static struct counters *
find_counter(struct counters *base, const char *name)
{
@@ -589,6 +593,48 @@ br_mispredictib(struct counters *cpu, int pos)
return(ret);
}
+
+static int
+br_mispredict_broad(struct counters *cpu, int pos)
+{
+ struct counters *brctr;
+ struct counters *unhalt;
+ struct counters *clear;
+ struct counters *uops;
+ struct counters *uops_ret;
+ struct counters *recv;
+ int ret;
+ double br, cl, uo, uo_r, re, con, un, res;
+
+ con = 4.0;
+
+ unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
+ brctr = find_counter(cpu, "BR_MISP_RETIRED.ALL_BRANCHES");
+ clear = find_counter(cpu, "MACHINE_CLEARS.CYCLES");
+ uops = find_counter(cpu, "UOPS_ISSUED.ANY");
+ uops_ret = find_counter(cpu, "UOPS_RETIRED.RETIRE_SLOTS");
+ recv = find_counter(cpu, "INT_MISC.RECOVERY_CYCLES");
+
+ if (pos != -1) {
+ un = unhalt->vals[pos] * 1.0;
+ br = brctr->vals[pos] * 1.0;
+ cl = clear->vals[pos] * 1.0;
+ uo = uops->vals[pos] * 1.0;
+ uo_r = uops_ret->vals[pos] * 1.0;
+ re = recv->vals[pos] * 1.0;
+ } else {
+ un = unhalt->sum * 1.0;
+ br = brctr->sum * 1.0;
+ cl = clear->sum * 1.0;
+ uo = uops->sum * 1.0;
+ uo_r = uops_ret->sum * 1.0;
+ re = recv->sum * 1.0;
+ }
+ res = br / (br + cl) * (uo - uo_r + con * re) / (un * con);
+ ret = printf("%1.3f", res);
+ return(ret);
+}
+
static int
splitloadib(struct counters *cpu, int pos)
{
@@ -622,6 +668,7 @@ splitloadib(struct counters *cpu, int pos)
return(ret);
}
+
static int
splitload(struct counters *cpu, int pos)
{
@@ -629,6 +676,31 @@ splitload(struct counters *cpu, int pos)
struct counters *mem;
struct counters *unhalt;
double con, un, memd, res;
+/* 4 - (MEM_UOPS_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .1)*/
+
+ con = 5.0;
+ unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
+ mem = find_counter(cpu, "MEM_UOPS_RETIRED.SPLIT_LOADS");
+ if (pos != -1) {
+ memd = mem->vals[pos] * 1.0;
+ un = unhalt->vals[pos] * 1.0;
+ } else {
+ memd = mem->sum * 1.0;
+ un = unhalt->sum * 1.0;
+ }
+ res = (memd * con)/un;
+ ret = printf("%1.3f", res);
+ return(ret);
+}
+
+
+static int
+splitload_sb(struct counters *cpu, int pos)
+{
+ int ret;
+ struct counters *mem;
+ struct counters *unhalt;
+ double con, un, memd, res;
/* 4 - (MEM_UOP_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .1)*/
con = 5.0;
@@ -646,8 +718,9 @@ splitload(struct counters *cpu, int pos)
return(ret);
}
+
static int
-splitstore(struct counters *cpu, int pos)
+splitstore_sb(struct counters *cpu, int pos)
{
/* 5 - MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES (thresh > 0.01) */
int ret;
@@ -669,6 +742,30 @@ splitstore(struct counters *cpu, int pos)
}
+
+static int
+splitstore(struct counters *cpu, int pos)
+{
+ /* 5 - MEM_UOPS_RETIRED.SPLIT_STORES / MEM_UOPS_RETIRED.ALL_STORES (thresh > 0.01) */
+ int ret;
+ struct counters *mem_split;
+ struct counters *mem_stores;
+ double memsplit, memstore, res;
+ mem_split = find_counter(cpu, "MEM_UOPS_RETIRED.SPLIT_STORES");
+ mem_stores = find_counter(cpu, "MEM_UOPS_RETIRED.ALL_STORES");
+ if (pos != -1) {
+ memsplit = mem_split->vals[pos] * 1.0;
+ memstore = mem_stores->vals[pos] * 1.0;
+ } else {
+ memsplit = mem_split->sum * 1.0;
+ memstore = mem_stores->sum * 1.0;
+ }
+ res = memsplit/memstore;
+ ret = printf("%1.3f", res);
+ return(ret);
+}
+
+
static int
contested(struct counters *cpu, int pos)
{
@@ -717,6 +814,35 @@ contested_has(struct counters *cpu, int pos)
return(ret);
}
+static int
+contestedbroad(struct counters *cpu, int pos)
+{
+ /* 6 - (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84) / CPU_CLK_UNHALTED.THREAD_P (thresh >.05) */
+ int ret;
+ struct counters *mem;
+ struct counters *mem2;
+ struct counters *unhalt;
+ double con, un, memd, memtoo, res;
+
+ con = 84.0;
+ unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
+ mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM");
+ mem2 = find_counter(cpu,"MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS");
+
+ if (pos != -1) {
+ memd = mem->vals[pos] * 1.0;
+ memtoo = mem2->vals[pos] * 1.0;
+ un = unhalt->vals[pos] * 1.0;
+ } else {
+ memd = mem->sum * 1.0;
+ memtoo = mem2->sum * 1.0;
+ un = unhalt->sum * 1.0;
+ }
+ res = ((memd * con) + memtoo)/un;
+ ret = printf("%1.3f", res);
+ return(ret);
+}
+
static int
blockstoreforward(struct counters *cpu, int pos)
@@ -897,6 +1023,34 @@ cache2has(struct counters *cpu, int pos)
return(ret);
}
+
+static int
+cache2broad(struct counters *cpu, int pos)
+{
+ /*
+ * (29 * MEM_LOAD_UOPS_RETIRED.LLC_HIT / CPU_CLK_UNHALTED.THREAD_P (thresh >.2)
+ */
+ int ret;
+ struct counters *mem;
+ struct counters *unhalt;
+ double con, un, me, res;
+
+ con = 36.0;
+ unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
+ mem = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.L3_HIT");
+ if (pos != -1) {
+ me = mem->vals[pos] * 1.0;
+ un = unhalt->vals[pos] * 1.0;
+ } else {
+ me = mem->sum * 1.0;
+ un = unhalt->sum * 1.0;
+ }
+ res = (con * me)/un;
+ ret = printf("%1.3f", res);
+ return(ret);
+}
+
+
static int
cache1(struct counters *cpu, int pos)
{
@@ -947,6 +1101,31 @@ cache1ib(struct counters *cpu, int pos)
static int
+cache1broad(struct counters *cpu, int pos)
+{
+ /* 9 - (MEM_LOAD_UOPS_L3_MISS_RETIRED.LCOAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .2) */
+ int ret;
+ struct counters *mem;
+ struct counters *unhalt;
+ double con, un, me, res;
+
+ con = 180.0;
+ unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
+ mem = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.L3_MISS");
+ if (pos != -1) {
+ me = mem->vals[pos] * 1.0;
+ un = unhalt->vals[pos] * 1.0;
+ } else {
+ me = mem->sum * 1.0;
+ un = unhalt->sum * 1.0;
+ }
+ res = (me * con)/un;
+ ret = printf("%1.3f", res);
+ return(ret);
+}
+
+
+static int
dtlb_missload(struct counters *cpu, int pos)
{
/* 10 - ((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION) / CPU_CLK_UNHALTED.THREAD_P (t >=.1) */
@@ -1026,6 +1205,35 @@ itlb_miss(struct counters *cpu, int pos)
return(ret);
}
+
+static int
+itlb_miss_broad(struct counters *cpu, int pos)
+{
+ /* (7 * ITLB_MISSES.STLB_HIT_4K + ITLB_MISSES.WALK_DURATION) / CPU_CLK_UNTHREAD_P */
+ int ret;
+ struct counters *itlb;
+ struct counters *unhalt;
+ struct counters *four_k;
+ double un, d1, res, k;
+
+ unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
+ itlb = find_counter(cpu, "ITLB_MISSES.WALK_DURATION");
+ four_k = find_counter(cpu, "ITLB_MISSES.STLB_HIT_4K");
+ if (pos != -1) {
+ d1 = itlb->vals[pos] * 1.0;
+ un = unhalt->vals[pos] * 1.0;
+ k = four_k->vals[pos] * 1.0;
+ } else {
+ d1 = itlb->sum * 1.0;
+ un = unhalt->sum * 1.0;
+ k = four_k->sum * 1.0;
+ }
+ res = (7.0 * k + d1)/un;
+ ret = printf("%1.3f", res);
+ return(ret);
+}
+
+
static int
icache_miss(struct counters *cpu, int pos)
{
@@ -1162,6 +1370,45 @@ clears(struct counters *cpu, int pos)
return(ret);
}
+
+
+static int
+clears_broad(struct counters *cpu, int pos)
+{
+ int ret;
+ struct counters *clr1, *clr2, *clr3, *cyc;
+ struct counters *unhalt;
+ double con, un, cl1, cl2, cl3, cy, res;
+
+ con = 100.0;
+ unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
+ clr1 = find_counter(cpu, "MACHINE_CLEARS.MEMORY_ORDERING");
+ clr2 = find_counter(cpu, "MACHINE_CLEARS.SMC");
+ clr3 = find_counter(cpu, "MACHINE_CLEARS.MASKMOV");
+ cyc = find_counter(cpu, "MACHINE_CLEARS.CYCLES");
+ if (pos != -1) {
+ cl1 = clr1->vals[pos] * 1.0;
+ cl2 = clr2->vals[pos] * 1.0;
+ cl3 = clr3->vals[pos] * 1.0;
+ cy = cyc->vals[pos] * 1.0;
+ un = unhalt->vals[pos] * 1.0;
+ } else {
+ cl1 = clr1->sum * 1.0;
+ cl2 = clr2->sum * 1.0;
+ cl3 = clr3->sum * 1.0;
+ cy = cyc->sum * 1.0;
+ un = unhalt->sum * 1.0;
+ }
+ /* Formula not listed but extrapulated to add the cy ?? */
+ res = ((cl1 + cl2 + cl3 + cy) * con)/un;
+ ret = printf("%1.3f", res);
+ return(ret);
+}
+
+
+
+
+
static int
microassist(struct counters *cpu, int pos)
{
@@ -1188,6 +1435,38 @@ microassist(struct counters *cpu, int pos)
static int
+microassist_broad(struct counters *cpu, int pos)
+{
+ int ret;
+ struct counters *idq;
+ struct counters *unhalt;
+ struct counters *uopiss;
+ struct counters *uopret;
+ double un, id, res, con, uoi, uor;
+
+ con = 4.0;
+ unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
+ idq = find_counter(cpu, "IDQ.MS_UOPS");
+ uopiss = find_counter(cpu, "UOPS_ISSUED.ANY");
+ uopret = find_counter(cpu, "UOPS_RETIRED.RETIRE_SLOTS");
+ if (pos != -1) {
+ id = idq->vals[pos] * 1.0;
+ un = unhalt->vals[pos] * 1.0;
+ uoi = uopiss->vals[pos] * 1.0;
+ uor = uopret->vals[pos] * 1.0;
+ } else {
+ id = idq->sum * 1.0;
+ un = unhalt->sum * 1.0;
+ uoi = uopiss->sum * 1.0;
+ uor = uopret->sum * 1.0;
+ }
+ res = (uor/uoi) * (id/(un * con));
+ ret = printf("%1.3f", res);
+ return(ret);
+}
+
+
+static int
aliasing(struct counters *cpu, int pos)
{
/* 15 - (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh > .1) */
@@ -1212,6 +1491,31 @@ aliasing(struct counters *cpu, int pos)
}
static int
+aliasing_broad(struct counters *cpu, int pos)
+{
+ /* 15 - (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh > .1) */
+ int ret;
+ struct counters *ld;
+ struct counters *unhalt;
+ double un, lds, con, res;
+
+ con = 7.0;
+ unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P");
+ ld = find_counter(cpu, "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS");
+ if (pos != -1) {
+ lds = ld->vals[pos] * 1.0;
+ un = unhalt->vals[pos] * 1.0;
+ } else {
+ lds = ld->sum * 1.0;
+ un = unhalt->sum * 1.0;
+ }
+ res = (lds * con)/un;
+ ret = printf("%1.3f", res);
+ return(ret);
+}
+
+
+static int
fpassists(struct counters *cpu, int pos)
{
/* 16 - FP_ASSIST.ANY/INST_RETIRED.ANY_P */
@@ -1336,64 +1640,65 @@ efficiency2(struct counters *cpu, int pos)
static struct cpu_entry sandy_bridge[SANDY_BRIDGE_COUNT] = {
/*01*/ { "allocstall1", "thresh > .05",
"pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW -w 1",
- allocstall1 },
-/*02*/ { "allocstall2", "thresh > .05",
- "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP_CYCLES -w 1",
- allocstall2 },
+ allocstall1, 2 },
+/* -- not defined for SB right (partial-rat_stalls) 02*/
+ { "allocstall2", "thresh > .05",
+ "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP -w 1",
+ allocstall2, 2 },
/*03*/ { "br_miss", "thresh >= .2",
"pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -w 1",
- br_mispredict },
+ br_mispredict, 2 },
/*04*/ { "splitload", "thresh >= .1",
"pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s MEM_UOP_RETIRED.SPLIT_LOADS -w 1",
- splitload },
-/*05*/ { "splitstore", "thresh >= .01",
+ splitload_sb, 2 },
+/* 05*/ { "splitstore", "thresh >= .01",
"pmcstat -s MEM_UOP_RETIRED.SPLIT_STORES -s MEM_UOP_RETIRED.ALL_STORES -w 1",
- splitstore },
+ splitstore_sb, 2 },
/*06*/ { "contested", "thresh >= .05",
"pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- contested },
+ contested, 2 },
/*07*/ { "blockstorefwd", "thresh >= .05",
"pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- blockstoreforward },
+ blockstoreforward, 2 },
/*08*/ { "cache2", "thresh >= .2",
"pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- cache2 },
+ cache2, 4 },
/*09*/ { "cache1", "thresh >= .2",
"pmcstat -s MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- cache1 },
+ cache1, 2 },
/*10*/ { "dtlbmissload", "thresh >= .1",
"pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- dtlb_missload },
+ dtlb_missload, 3 },
/*11*/ { "dtlbmissstore", "thresh >= .05",
"pmcstat -s DTLB_STORE_MISSES.STLB_HIT -s DTLB_STORE_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- dtlb_missstore },
+ dtlb_missstore, 3 },
/*12*/ { "frontendstall", "thresh >= .15",
"pmcstat -s IDQ_UOPS_NOT_DELIVERED.CORE -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- frontendstall },
+ frontendstall, 2 },
/*13*/ { "clears", "thresh >= .02",
"pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- clears },
+ clears, 4 },
/*14*/ { "microassist", "thresh >= .05",
"pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- microassist },
+ microassist, 2 },
/*15*/ { "aliasing_4k", "thresh >= .1",
"pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- aliasing },
+ aliasing, 2 },
/*16*/ { "fpassist", "look for a excessive value",
"pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1",
- fpassists },
+ fpassists, 2 },
/*17*/ { "otherassistavx", "look for a excessive value",
"pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- otherassistavx },
+ otherassistavx, 2},
/*18*/ { "otherassistsse", "look for a excessive value",
"pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- otherassistsse },
+ otherassistsse, 2 },
/*19*/ { "eff1", "thresh < .9",
"pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- efficiency1 },
+ efficiency1, 2 },
/*20*/ { "eff2", "thresh > 1.0",
"pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- efficiency2 },
+ efficiency2, 2 },
};
@@ -1401,131 +1706,257 @@ static struct cpu_entry sandy_bridge[SANDY_BRIDGE_COUNT] = {
static struct cpu_entry ivy_bridge[IVY_BRIDGE_COUNT] = {
/*1*/ { "eff1", "thresh < .75",
"pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- efficiency1 },
+ efficiency1, 2 },
/*2*/ { "eff2", "thresh > 1.0",
"pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- efficiency2 },
+ efficiency2, 2 },
/*3*/ { "itlbmiss", "thresh > .05",
"pmcstat -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- itlb_miss },
+ itlb_miss, 2 },
/*4*/ { "icachemiss", "thresh > .05",
"pmcstat -s ICACHE.IFETCH_STALL -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- icache_miss },
+ icache_miss, 3 },
/*5*/ { "lcpstall", "thresh > .05",
"pmcstat -s ILD_STALL.LCP -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- lcp_stall },
+ lcp_stall, 2 },
/*6*/ { "cache1", "thresh >= .2",
"pmcstat -s MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- cache1ib },
+ cache1ib, 2 },
/*7*/ { "cache2", "thresh >= .2",
"pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- cache2ib },
+ cache2ib, 2 },
/*8*/ { "contested", "thresh >= .05",
"pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- contested },
+ contested, 2 },
/*9*/ { "datashare", "thresh >= .05",
"pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- datasharing },
+ datasharing, 2 },
/*10*/ { "blockstorefwd", "thresh >= .05",
"pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- blockstoreforward },
+ blockstoreforward, 2 },
/*11*/ { "splitload", "thresh >= .1",
"pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s L1D_PEND_MISS.PENDING -s MEM_LOAD_UOPS_RETIRED.L1_MISS -s LD_BLOCKS.NO_SR -w 1",
- splitloadib },
+ splitloadib, 4 },
/*12*/ { "splitstore", "thresh >= .01",
- "pmcstat -s MEM_UOP_RETIRED.SPLIT_STORES -s MEM_UOP_RETIRED.ALL_STORES -w 1",
- splitstore },
+ "pmcstat -s MEM_UOPS_RETIRED.SPLIT_STORES -s MEM_UOPS_RETIRED.ALL_STORES -w 1",
+ splitstore, 2 },
/*13*/ { "aliasing_4k", "thresh >= .1",
"pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- aliasing },
+ aliasing, 2 },
/*14*/ { "dtlbmissload", "thresh >= .1",
"pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- dtlb_missload },
+ dtlb_missload , 3},
/*15*/ { "dtlbmissstore", "thresh >= .05",
"pmcstat -s DTLB_STORE_MISSES.STLB_HIT -s DTLB_STORE_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- dtlb_missstore },
+ dtlb_missstore, 3 },
/*16*/ { "br_miss", "thresh >= .2",
"pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s UOPS_ISSUED.ANY -s UOPS_RETIRED.RETIRE_SLOTS -s INT_MISC.RECOVERY_CYCLES -w 1",
- br_mispredictib },
+ br_mispredictib, 8 },
/*17*/ { "clears", "thresh >= .02",
"pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- clears },
+ clears, 4 },
/*18*/ { "microassist", "thresh >= .05",
"pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- microassist },
+ microassist, 2 },
/*19*/ { "fpassist", "look for a excessive value",
"pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1",
- fpassists },
+ fpassists, 2 },
/*20*/ { "otherassistavx", "look for a excessive value",
"pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- otherassistavx },
+ otherassistavx , 2},
/*21*/ { "otherassistsse", "look for a excessive value",
"pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- otherassistsse },
+ otherassistsse, 2 },
};
#define HASWELL_COUNT 20
static struct cpu_entry haswell[HASWELL_COUNT] = {
/*1*/ { "eff1", "thresh < .75",
"pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- efficiency1 },
+ efficiency1, 2 },
/*2*/ { "eff2", "thresh > 1.0",
"pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- efficiency2 },
+ efficiency2, 2 },
/*3*/ { "itlbmiss", "thresh > .05",
"pmcstat -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- itlb_miss },
+ itlb_miss, 2 },
/*4*/ { "icachemiss", "thresh > .05",
- "pmcstat -s ICACHE.MISSES --s CPU_CLK_UNHALTED.THREAD_P -w 1",
- icache_miss_has },
+ "pmcstat -s ICACHE.MISSES -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ icache_miss_has, 2 },
/*5*/ { "lcpstall", "thresh > .05",
"pmcstat -s ILD_STALL.LCP -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- lcp_stall },
+ lcp_stall, 2 },
/*6*/ { "cache1", "thresh >= .2",
"pmcstat -s MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- cache1ib },
+ cache1ib, 2 },
/*7*/ { "cache2", "thresh >= .2",
"pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- cache2has },
+ cache2has, 4 },
/*8*/ { "contested", "thresh >= .05",
"pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- contested_has },
+ contested_has, 2 },
/*9*/ { "datashare", "thresh >= .05",
"pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- datasharing_has },
+ datasharing_has, 2 },
/*10*/ { "blockstorefwd", "thresh >= .05",
"pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- blockstoreforward },
+ blockstoreforward, 2 },
/*11*/ { "splitload", "thresh >= .1",
- "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s MEM_UOP_RETIRED.SPLIT_LOADS -w 1",
- splitload },
+ "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s MEM_UOPS_RETIRED.SPLIT_LOADS -w 1",
+ splitload , 2},
/*12*/ { "splitstore", "thresh >= .01",
- "pmcstat -s MEM_UOP_RETIRED.SPLIT_STORES -s MEM_UOP_RETIRED.ALL_STORES -w 1",
- splitstore },
+ "pmcstat -s MEM_UOPS_RETIRED.SPLIT_STORES -s MEM_UOPS_RETIRED.ALL_STORES -w 1",
+ splitstore, 2 },
/*13*/ { "aliasing_4k", "thresh >= .1",
"pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- aliasing },
+ aliasing, 2 },
/*14*/ { "dtlbmissload", "thresh >= .1",
"pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- dtlb_missload },
+ dtlb_missload, 3 },
/*15*/ { "br_miss", "thresh >= .2",
"pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -w 1",
- br_mispredict },
+ br_mispredict, 2 },
/*16*/ { "clears", "thresh >= .02",
"pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- clears },
+ clears, 4 },
/*17*/ { "microassist", "thresh >= .05",
"pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- microassist },
+ microassist, 2 },
/*18*/ { "fpassist", "look for a excessive value",
"pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1",
- fpassists },
+ fpassists, 2 },
/*19*/ { "otherassistavx", "look for a excessive value",
"pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- otherassistavx },
+ otherassistavx, 2 },
/*20*/ { "otherassistsse", "look for a excessive value",
"pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1",
- otherassistsse },
+ otherassistsse, 2 },
+};
+
+
+static void
+explain_name_broad(const char *name)
+{
+ const char *mythresh;
+ if (strcmp(name, "eff1") == 0) {
+ printf("Examine (UOPS_RETIRED.RETIRE_SLOTS)/(4 *CPU_CLK_UNHALTED.THREAD_P)\n");
+ mythresh = "thresh < .75";
+ } else if (strcmp(name, "eff2") == 0) {
+ printf("Examine CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P\n");
+ mythresh = "thresh > 1.0";
+ } else if (strcmp(name, "itlbmiss") == 0) {
+ printf("Examine (7 * ITLB_MISSES_STLB_HIT_4K + ITLB_MISSES.WALK_DURATION)/ CPU_CLK_UNHALTED.THREAD_P\n");
+ mythresh = "thresh > .05";
+ } else if (strcmp(name, "icachemiss") == 0) {
+ printf("Examine ( 36.0 * ICACHE.MISSES)/ CPU_CLK_UNHALTED.THREAD_P ??? may not be right \n");
+ mythresh = "thresh > .05";
+ } else if (strcmp(name, "lcpstall") == 0) {
+ printf("Examine ILD_STALL.LCP/CPU_CLK_UNHALTED.THREAD_P\n");
+ mythresh = "thresh > .05";
+ } else if (strcmp(name, "cache1") == 0) {
+ printf("Examine (MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P\n");
+ mythresh = "thresh >= .1";
+ } else if (strcmp(name, "cache2") == 0) {
+ printf("Examine (36.0 * MEM_LOAD_UOPS_RETIRED.L3_HIT / CPU_CLK_UNHALTED.THREAD_P)\n");
+ mythresh = "thresh >= .2";
+ } else if (strcmp(name, "contested") == 0) {
+ printf("Examine ((MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84) + MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS)/ CPU_CLK_UNHALTED.THREAD_P\n");
+ mythresh = "thresh >= .05";
+ } else if (strcmp(name, "datashare") == 0) {
+ printf("Examine (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 72)/CPU_CLK_UNHALTED.THREAD_P\n");
+ mythresh = "thresh > .05";
+ } else if (strcmp(name, "blockstorefwd") == 0) {
+ printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n");
+ mythresh = "thresh >= .05";
+ } else if (strcmp(name, "aliasing_4k") == 0) {
+ printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 7) / CPU_CLK_UNHALTED.THREAD_P\n");
+ mythresh = "thresh >= .1";
+ } else if (strcmp(name, "dtlbmissload") == 0) {
+ printf("Examine (((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION)\n");
+ printf(" / CPU_CLK_UNHALTED.THREAD_P)\n");
+ mythresh = "thresh >= .1";
+
+ } else if (strcmp(name, "br_miss") == 0) {
+ printf("Examine BR_MISP_RETIRED.ALL_BRANCHS_PS / (BR_MISP_RETIED.ALL_BRANCHES_PS + MACHINE_CLEARS.COUNT) *\n");
+ printf(" (UOPS_ISSUEDF.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES) /\n");
+ printf("CPU_CLK_UNHALTED.THREAD * 4)\n");
+ mythresh = "thresh >= .2";
+ } else if (strcmp(name, "clears") == 0) {
+ printf("Examine ((MACHINE_CLEARS.MEMORY_ORDERING + \n");
+ printf(" MACHINE_CLEARS.SMC + \n");
+ printf(" MACHINE_CLEARS.MASKMOV ) * 100 ) / CPU_CLK_UNHALTED.THREAD_P\n");
+ mythresh = "thresh >= .02";
+ } else if (strcmp(name, "fpassist") == 0) {
+ printf("Examine FP_ASSIST.ANY/INST_RETIRED.ANY_P\n");
+ mythresh = "look for a excessive value";
+ } else if (strcmp(name, "otherassistavx") == 0) {
+ printf("Examine (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P\n");
+ mythresh = "look for a excessive value";
+ } else if (strcmp(name, "microassist") == 0) {
+ printf("Examine (UOPS_RETIRED.RETIRE_SLOTS/UOPS_ISSUED.ANY) * (IDQ.MS_CYCLES / (4 * CPU_CLK_UNHALTED.THREAD_P)\n");
+ printf("***We use IDQ.MS_UOPS,cmask=1 to get cycles\n");
+ mythresh = "thresh >= .05";
+ } else {
+ printf("Unknown name:%s\n", name);
+ mythresh = "unknown entry";
+ }
+ printf("If the value printed is %s we may have the ability to improve performance\n", mythresh);
+}
+
+
+#define BROADWELL_COUNT 17
+static struct cpu_entry broadwell[BROADWELL_COUNT] = {
+/*1*/ { "eff1", "thresh < .75",
+ "pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ efficiency1, 2 },
+/*2*/ { "eff2", "thresh > 1.0",
+ "pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ efficiency2, 2 },
+/*3*/ { "itlbmiss", "thresh > .05",
+ "pmcstat -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -s ITLB_MISSES.STLB_HIT_4K -w 1",
+ itlb_miss_broad, 3 },
+/*4*/ { "icachemiss", "thresh > .05",
+ "pmcstat -s ICACHE.MISSES -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ icache_miss_has, 2 },
+/*5*/ { "lcpstall", "thresh > .05",
+ "pmcstat -s ILD_STALL.LCP -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ lcp_stall, 2 },
+/*6*/ { "cache1", "thresh >= .1",
+ "pmcstat -s MEM_LOAD_UOPS_RETIRED.L3_MISS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ cache1broad, 2 },
+/*7*/ { "cache2", "thresh >= .2",
+ "pmcstat -s MEM_LOAD_UOPS_RETIRED.L3_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ cache2broad, 2 },
+/*8*/ { "contested", "thresh >= .05",
+ "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS -w 1",
+ contestedbroad, 2 },
+/*9*/ { "datashare", "thresh >= .05",
+ "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ datasharing_has, 2 },
+/*10*/ { "blockstorefwd", "thresh >= .05",
+ "pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ blockstoreforward, 2 },
+/*11*/ { "aliasing_4k", "thresh >= .1",
+ "pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ aliasing_broad, 2 },
+/*12*/ { "dtlbmissload", "thresh >= .1",
+ "pmcstat -s DTLB_LOAD_MISSES.STLB_HIT_4K -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ dtlb_missload, 3 },
+/*13*/ { "br_miss", "thresh >= .2",
+ "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -s MACHINE_CLEARS.CYCLES -s UOPS_ISSUED.ANY -s UOPS_RETIRED.RETIRE_SLOTS -s INT_MISC.RECOVERY_CYCLES -w 1",
+ br_mispredict_broad, 7 },
+/*14*/ { "clears", "thresh >= .02",
+ "pmcstat -s MACHINE_CLEARS.CYCLES -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ clears_broad, 5 },
+/*15*/ { "fpassist", "look for a excessive value",
+ "pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1",
+ fpassists, 2 },
+/*16*/ { "otherassistavx", "look for a excessive value",
+ "pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1",
+ otherassistavx, 2 },
+/*17*/ { "microassist", "thresh >= .2",
+ "pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -s UOPS_ISSUED.ANY -s UOPS_RETIRED.RETIRE_SLOTS -w 1",
+ microassist_broad, 4 },
};
@@ -1557,8 +1988,19 @@ set_haswell(void)
the_cpu.explain = explain_name_has;
}
+
static void
-set_expression(char *name)
+set_broadwell(void)
+{
+ strcpy(the_cpu.cputype, "HASWELL PMC");
+ the_cpu.number = BROADWELL_COUNT;
+ the_cpu.ents = broadwell;
+ the_cpu.explain = explain_name_broad;
+}
+
+
+static int
+set_expression(const char *name)
{
int found = 0, i;
for(i=0 ; i< the_cpu.number; i++) {
@@ -1567,6 +2009,17 @@ set_expression(char *name)
expression = the_cpu.ents[i].func;
command = the_cpu.ents[i].command;
threshold = the_cpu.ents[i].thresh;
+ if (the_cpu.ents[i].counters_required > max_pmc_counters) {
+ printf("Test %s requires that the CPU have %d counters and this CPU has only %d\n",
+ the_cpu.ents[i].name,
+ the_cpu.ents[i].counters_required, max_pmc_counters);
+ printf("Sorry this test can not be run\n");
+ if (run_all == 0) {
+ exit(-1);
+ } else {
+ return(-1);
+ }
+ }
break;
}
}
@@ -1575,6 +2028,7 @@ set_expression(char *name)
the_cpu.cputype, name);
exit(-1);
}
+ return(0);
}
@@ -1796,10 +2250,6 @@ process_file(char *filename)
if (filename == NULL) {
io = my_popen(command, "r", &pid_of_command);
- if (io == NULL) {
- printf("Can't popen the command %s\n", command);
- return;
- }
} else {
io = fopen(filename, "r");
if (io == NULL) {
@@ -1812,10 +2262,8 @@ process_file(char *filename)
if (cnts == NULL) {
/* Nothing we can do */
printf("Nothing to do -- no counters built\n");
- if (filename) {
- fclose(io);
- } else {
- my_pclose(io, pid_of_command);
+ if (io) {
+ fclose(io);
}
return;
}
@@ -1863,8 +2311,22 @@ process_file(char *filename)
#if defined(__amd64__)
#define cpuid(in,a,b,c,d)\
asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
+
+static __inline void
+do_cpuid(u_int ax, u_int cx, u_int *p)
+{
+ __asm __volatile("cpuid"
+ : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (ax), "c" (cx) );
+}
+
#else
#define cpuid(in, a, b, c, d)
+static __inline void
+do_cpuid(u_int ax, u_int cx, u_int *p)
+{
+}
+
#endif
static void
@@ -1876,6 +2338,7 @@ get_cpuid_set(void)
size_t sz, len;
FILE *io;
char linebuf[1024], *str;
+ u_int reg[4];
eax = ebx = ecx = edx = 0;
@@ -1992,6 +2455,23 @@ get_cpuid_set(void)
printf("Intel HASWELL\n");
set_haswell();
break;
+
+ case 0x4e:
+ case 0x5e:
+ printf("Intel SKY-LAKE\n");
+ goto not_supported;
+ break;
+ case 0x3D:
+ case 0x47:
+ printf("Intel BROADWELL\n");
+ set_broadwell();
+ break;
+ case 0x4f:
+ case 0x56:
+ printf("Intel BROADWEL (Xeon)\n");
+ set_broadwell();
+ break;
+
case 0x4D:
/* Per Intel document 330061-001 01/2014. */
printf("Intel ATOM_SILVERMONT\n");
@@ -2009,6 +2489,9 @@ get_cpuid_set(void)
goto not_supported;
break;
}
+ do_cpuid(0xa, 0, reg);
+ max_pmc_counters = (reg[3] & 0x0000000f) + 1;
+ printf("We have %d PMC counters to work with\n", max_pmc_counters);
/* Ok lets load the list of all known PMC's */
io = my_popen("/usr/sbin/pmccontrol -L", "r", &pid_of_command);
if (valid_pmcs == NULL) {
@@ -2320,14 +2803,18 @@ main(int argc, char **argv)
{
int i, j, cnt;
char *filename=NULL;
- char *name=NULL;
+ const char *name=NULL;
int help_only = 0;
int test_mode = 0;
+ int test_at = 0;
get_cpuid_set();
memset(glob_cpu, 0, sizeof(glob_cpu));
- while ((i = getopt(argc, argv, "LHhvm:i:?e:TE:")) != -1) {
+ while ((i = getopt(argc, argv, "ALHhvm:i:?e:TE:")) != -1) {
switch (i) {
+ case 'A':
+ run_all = 1;
+ break;
case 'L':
list_all();
return(0);
@@ -2383,23 +2870,28 @@ main(int argc, char **argv)
printf("-h -- Don't do the expression I put in -e xxx just explain what it does and exit\n");
printf("-H -- Don't run anything, just explain all canned expressions\n");
printf("-T -- Test all PMC's defined by this processor\n");
+ printf("-A -- Run all canned tests\n");
return(0);
break;
};
}
- if ((name == NULL) && (filename == NULL) && (test_mode == 0) && (master_exp == NULL)) {
+ if ((run_all == 0) && (name == NULL) && (filename == NULL) &&
+ (test_mode == 0) && (master_exp == NULL)) {
printf("Without setting an expression we cannot dynamically gather information\n");
printf("you must supply a filename (and you probably want verbosity)\n");
goto use;
}
+ if (run_all && max_to_collect > 10) {
+ max_to_collect = 3;
+ }
if (test_mode) {
run_tests();
return(0);
}
printf("*********************************\n");
- if (master_exp == NULL) {
+ if ((master_exp == NULL) && name) {
(*the_cpu.explain)(name);
- } else {
+ } else if (master_exp) {
printf("Examine your expression ");
print_exp(master_exp);
printf("User defined threshold\n");
@@ -2407,6 +2899,19 @@ main(int argc, char **argv)
if (help_only) {
return(0);
}
+ if (run_all) {
+ more:
+ name = the_cpu.ents[test_at].name;
+ printf("***Test %s (threshold %s)****\n", name, the_cpu.ents[test_at].thresh);
+ test_at++;
+ if (set_expression(name) == -1) {
+ if (test_at >= the_cpu.number) {
+ goto done;
+ } else
+ goto more;
+ }
+
+ }
process_file(filename);
if (verbose >= 2) {
for (i=0; i<ncnts; i++) {
@@ -2422,17 +2927,28 @@ main(int argc, char **argv)
if (expression == NULL) {
return(0);
}
- for(i=0, cnt=0; i<MAX_CPU; i++) {
- if (glob_cpu[i]) {
- do_expression(glob_cpu[i], -1);
- cnt++;
- if (cnt == cpu_count_out) {
- printf("\n");
- break;
- } else {
- printf("\t");
+ if (max_to_collect > 1) {
+ for(i=0, cnt=0; i<MAX_CPU; i++) {
+ if (glob_cpu[i]) {
+ do_expression(glob_cpu[i], -1);
+ cnt++;
+ if (cnt == cpu_count_out) {
+ printf("\n");
+ break;
+ } else {
+ printf("\t");
+ }
}
}
}
+ if (run_all && (test_at < the_cpu.number)) {
+ memset(glob_cpu, 0, sizeof(glob_cpu));
+ ncnts = 0;
+ printf("*********************************\n");
+ goto more;
+ } else if (run_all) {
+ done:
+ printf("*********************************\n");
+ }
return(0);
}
OpenPOWER on IntegriCloud