Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Oct 2014 02:57:30 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r273299 - in projects/bhyve_svm: sbin/ping6 sys/amd64/vmm/amd sys/amd64/vmm/intel sys/conf sys/fs/autofs sys/geom sys/modules/vmm sys/net usr.sbin/bhyve
Message-ID:  <201410200257.s9K2vUdJ032520@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Mon Oct 20 02:57:30 2014
New Revision: 273299
URL: https://svnweb.freebsd.org/changeset/base/273299

Log:
  IFC @r273214

Modified:
  projects/bhyve_svm/sbin/ping6/ping6.8
  projects/bhyve_svm/sbin/ping6/ping6.c
  projects/bhyve_svm/sys/amd64/vmm/amd/svm_support.S
  projects/bhyve_svm/sys/amd64/vmm/intel/vmx_support.S
  projects/bhyve_svm/sys/conf/files
  projects/bhyve_svm/sys/fs/autofs/autofs.c
  projects/bhyve_svm/sys/geom/geom_dump.c
  projects/bhyve_svm/sys/modules/vmm/Makefile
  projects/bhyve_svm/sys/net/if_lagg.c
  projects/bhyve_svm/usr.sbin/bhyve/block_if.c
  projects/bhyve_svm/usr.sbin/bhyve/pci_ahci.c
Directory Properties:
  projects/bhyve_svm/   (props changed)
  projects/bhyve_svm/sbin/   (props changed)
  projects/bhyve_svm/sys/   (props changed)
  projects/bhyve_svm/sys/amd64/vmm/   (props changed)
  projects/bhyve_svm/sys/conf/   (props changed)
  projects/bhyve_svm/sys/modules/vmm/   (props changed)
  projects/bhyve_svm/usr.sbin/bhyve/   (props changed)

Modified: projects/bhyve_svm/sbin/ping6/ping6.8
==============================================================================
--- projects/bhyve_svm/sbin/ping6/ping6.8	Mon Oct 20 01:52:17 2014	(r273298)
+++ projects/bhyve_svm/sbin/ping6/ping6.8	Mon Oct 20 02:57:30 2014	(r273299)
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 5, 2013
+.Dd September 22, 2014
 .Dt PING6 8
 .Os
 .Sh NAME
@@ -65,6 +65,12 @@ packets to network hosts
 .Op Fl i Ar wait
 .Ek
 .Bk -words
+.Op Fl x Ar waittime
+.Ek
+.Bk -words
+.Op Fl X Ar timeout
+.Ek
+.Bk -words
 .Op Fl l Ar preload
 .Ek
 .Bk -words
@@ -191,6 +197,15 @@ The default is to wait for one second be
 This option is incompatible with the
 .Fl f
 option.
+.It Fl x Ar waittime
+Time in milliseconds to wait for a reply for each packet sent.
+If a reply arrives later,
+the packet is not printed as replied,
+but considered as replied when calculating statistics.
+.It Fl X Ar timeout
+Specify a timeout,
+in seconds,
+before ping exits regardless of how many packets have been received.
 .It Fl l Ar preload
 If
 .Ar preload

Modified: projects/bhyve_svm/sbin/ping6/ping6.c
==============================================================================
--- projects/bhyve_svm/sbin/ping6/ping6.c	Mon Oct 20 01:52:17 2014	(r273298)
+++ projects/bhyve_svm/sbin/ping6/ping6.c	Mon Oct 20 02:57:30 2014	(r273299)
@@ -152,6 +152,8 @@ struct tv32 {
 #define	DEFDATALEN	ICMP6ECHOTMLEN
 #define MAXDATALEN	MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN
 #define	NROUTES		9		/* number of record route slots */
+#define	MAXWAIT		10000		/* max ms to wait for response */
+#define	MAXALARM	(60 * 60)	/* max seconds for alarm timeout */
 
 #define	A(bit)		rcvd_tbl[(bit)>>3]	/* identify byte in array */
 #define	B(bit)		(1 << ((bit) & 0x07))	/* identify bit in byte */
@@ -188,6 +190,7 @@ struct tv32 {
 #define F_MISSED	0x800000
 #define F_DONTFRAG	0x1000000
 #define F_NOUSERDATA	(F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
+#define	F_WAITTIME	0x2000000
 u_int options;
 
 #define IN6LEN		sizeof(struct in6_addr)
@@ -228,6 +231,8 @@ long nreceived;			/* # of packets we got
 long nrepeats;			/* number of duplicates */
 long ntransmitted;		/* sequence # for outbound packets = #sent */
 int interval = 1000;		/* interval between packets in ms */
+int waittime = MAXWAIT;		/* timeout for each packet */
+long nrcvtimeout = 0;		/* # of packets we got back after waittime */
 
 /* timing */
 int timing;			/* flag to do timing */
@@ -312,6 +317,7 @@ main(int argc, char *argv[])
 	char *policy_out = NULL;
 #endif
 	double t;
+	u_long alarmtimeout;
 	size_t rthlen;
 #ifdef IPV6_USE_MIN_MTU
 	int mflag = 0;
@@ -321,7 +327,7 @@ main(int argc, char *argv[])
 	memset(&smsghdr, 0, sizeof(smsghdr));
 	memset(&smsgiov, 0, sizeof(smsgiov));
 
-	preload = 0;
+	alarmtimeout = preload = 0;
 	datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN];
 #ifndef IPSEC
 #define ADDOPTS
@@ -333,7 +339,7 @@ main(int argc, char *argv[])
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif
 	while ((ch = getopt(argc, argv,
-	    "a:b:c:DdfHg:h:I:i:l:mnNop:qrRS:s:tvwW" ADDOPTS)) != -1) {
+	    "a:b:c:DdfHg:h:I:i:l:mnNop:qrRS:s:tvwWx:X:" ADDOPTS)) != -1) {
 #undef ADDOPTS
 		switch (ch) {
 		case 'a':
@@ -541,6 +547,24 @@ main(int argc, char *argv[])
 			options &= ~F_NOUSERDATA;
 			options |= F_FQDNOLD;
 			break;
+		case 'x':
+			t = strtod(optarg, &e);
+			if (*e || e == optarg || t > (double)INT_MAX)
+				err(EX_USAGE, "invalid timing interval: `%s'",
+				    optarg);
+			options |= F_WAITTIME;
+			waittime = (int)t;
+			break;
+		case 'X':
+			alarmtimeout = strtoul(optarg, &e, 0);
+			if ((alarmtimeout < 1) || (alarmtimeout == ULONG_MAX))
+				errx(EX_USAGE, "invalid timeout: `%s'",
+				    optarg);
+			if (alarmtimeout > MAXALARM)
+				errx(EX_USAGE, "invalid timeout: `%s' > %d",
+				    optarg, MAXALARM);
+			alarm((int)alarmtimeout);
+			break;
 #ifdef IPSEC
 #ifdef IPSEC_POLICY_IPSEC
 		case 'P':
@@ -1057,6 +1081,10 @@ main(int argc, char *argv[])
 		err(EX_OSERR, "sigaction SIGINFO");
 	seeninfo = 0;
 #endif
+	if (alarmtimeout > 0) {
+		if (sigaction(SIGALRM, &si_sa, 0) == -1)
+			err(EX_OSERR, "sigaction SIGALRM");
+	}
 	if (options & F_FLOOD) {
 		intvl.tv_sec = 0;
 		intvl.tv_usec = 10000;
@@ -1157,17 +1185,18 @@ main(int argc, char *argv[])
 			/*
 			 * If we're not transmitting any more packets,
 			 * change the timer to wait two round-trip times
-			 * if we've received any packets or ten seconds
-			 * if we haven't.
+			 * if we've received any packets or (waittime)
+			 * milliseconds if we haven't.
 			 */
-#define	MAXWAIT		10
 				intvl.tv_usec = 0;
 				if (nreceived) {
 					intvl.tv_sec = 2 * tmax / 1000;
 					if (intvl.tv_sec == 0)
 						intvl.tv_sec = 1;
-				} else
-					intvl.tv_sec = MAXWAIT;
+				} else {
+					intvl.tv_sec = waittime / 1000;
+					intvl.tv_usec = waittime % 1000 * 1000;
+				}
 			}
 			gettimeofday(&last, NULL);
 			if (ntransmitted - nreceived - 1 > nmissedmax) {
@@ -1181,6 +1210,7 @@ main(int argc, char *argv[])
 	si_sa.sa_flags = 0;
 	si_sa.sa_handler = SIG_IGN;
 	sigaction(SIGINT, &si_sa, 0);
+	sigaction(SIGALRM, &si_sa, 0);
 	summary();
 
 	if (res != NULL)
@@ -1198,6 +1228,7 @@ onsignal(int sig)
 
 	switch (sig) {
 	case SIGINT:
+	case SIGALRM:
 		seenint++;
 		break;
 #ifdef SIGINFO
@@ -1521,6 +1552,11 @@ pr_pack(u_char *buf, int cc, struct msgh
 		if (options & F_QUIET)
 			return;
 
+		if (options & F_WAITTIME && triptime > waittime) {
+			++nrcvtimeout;
+			return;
+		}
+
 		if (options & F_FLOOD)
 			(void)write(STDOUT_FILENO, &BSPACE, 1);
 		else {
@@ -2216,6 +2252,8 @@ summary(void)
 			    ((((double)ntransmitted - nreceived) * 100.0) /
 			    ntransmitted));
 	}
+	if (nrcvtimeout)
+		printf(", %ld packets out of wait time", nrcvtimeout);
 	(void)putchar('\n');
 	if (nreceived && timing) {
 		/* Only display average to microseconds */
@@ -2741,6 +2779,7 @@ usage(void)
 #endif
 	    "\n"
 	    "             [-p pattern] [-S sourceaddr] [-s packetsize] "
-	    "[hops ...] host\n");
+	    "[-x waittime]\n"
+	    "             [-X timeout] [hops ...] host\n");
 	exit(1);
 }

Modified: projects/bhyve_svm/sys/amd64/vmm/amd/svm_support.S
==============================================================================
--- projects/bhyve_svm/sys/amd64/vmm/amd/svm_support.S	Mon Oct 20 01:52:17 2014	(r273298)
+++ projects/bhyve_svm/sys/amd64/vmm/amd/svm_support.S	Mon Oct 20 02:57:30 2014	(r273299)
@@ -25,7 +25,7 @@
  */
 #include <machine/asmacros.h>
 
-#include "svm_assym.s"
+#include "svm_assym.h"
 
 /*
  * Be friendly to DTrace FBT's prologue/epilogue pattern matching.

Modified: projects/bhyve_svm/sys/amd64/vmm/intel/vmx_support.S
==============================================================================
--- projects/bhyve_svm/sys/amd64/vmm/intel/vmx_support.S	Mon Oct 20 01:52:17 2014	(r273298)
+++ projects/bhyve_svm/sys/amd64/vmm/intel/vmx_support.S	Mon Oct 20 02:57:30 2014	(r273299)
@@ -29,7 +29,7 @@
 
 #include <machine/asmacros.h>
 
-#include "vmx_assym.s"
+#include "vmx_assym.h"
 
 #ifdef SMP
 #define	LK	lock ;

Modified: projects/bhyve_svm/sys/conf/files
==============================================================================
--- projects/bhyve_svm/sys/conf/files	Mon Oct 20 01:52:17 2014	(r273298)
+++ projects/bhyve_svm/sys/conf/files	Mon Oct 20 02:57:30 2014	(r273299)
@@ -3231,7 +3231,8 @@ net/if_ethersubr.c		optional ether
 net/if_faith.c			optional faith
 net/if_fddisubr.c		optional fddi
 net/if_fwsubr.c			optional fwip
-net/if_gif.c			optional gif inet | gif inet6 | netgraph_gif
+net/if_gif.c			optional gif inet | gif inet6 | \
+					 netgraph_gif inet | netgraph_gif inet6
 net/if_gre.c			optional gre inet
 net/if_iso88025subr.c		optional token
 net/if_lagg.c			optional lagg
@@ -3357,7 +3358,7 @@ netgraph/ng_eiface.c		optional netgraph_
 netgraph/ng_ether.c		optional netgraph_ether
 netgraph/ng_ether_echo.c	optional netgraph_ether_echo
 netgraph/ng_frame_relay.c	optional netgraph_frame_relay
-netgraph/ng_gif.c		optional netgraph_gif
+netgraph/ng_gif.c		optional netgraph_gif inet6 | netgraph_gif inet
 netgraph/ng_gif_demux.c		optional netgraph_gif_demux
 netgraph/ng_hole.c		optional netgraph_hole
 netgraph/ng_iface.c		optional netgraph_iface

Modified: projects/bhyve_svm/sys/fs/autofs/autofs.c
==============================================================================
--- projects/bhyve_svm/sys/fs/autofs/autofs.c	Mon Oct 20 01:52:17 2014	(r273298)
+++ projects/bhyve_svm/sys/fs/autofs/autofs.c	Mon Oct 20 02:57:30 2014	(r273299)
@@ -550,7 +550,6 @@ autofs_ioctl_request(struct autofs_daemo
 		    &autofs_softc->sc_lock);
 		if (error != 0) {
 			sx_xunlock(&autofs_softc->sc_lock);
-			AUTOFS_DEBUG("failed with error %d", error);
 			return (error);
 		}
 	}

Modified: projects/bhyve_svm/sys/geom/geom_dump.c
==============================================================================
--- projects/bhyve_svm/sys/geom/geom_dump.c	Mon Oct 20 01:52:17 2014	(r273298)
+++ projects/bhyve_svm/sys/geom/geom_dump.c	Mon Oct 20 02:57:30 2014	(r273299)
@@ -61,8 +61,9 @@ static void
 g_confdot_provider(struct sbuf *sb, struct g_provider *pp)
 {
 
-	sbuf_printf(sb, "z%p [shape=hexagon,label=\"%s\\nr%dw%de%d\\nerr#%d\"];\n",
-	    pp, pp->name, pp->acr, pp->acw, pp->ace, pp->error);
+	sbuf_printf(sb, "z%p [shape=hexagon,label=\"%s\\nr%dw%de%d\\nerr#%d\\n"
+	    "sector=%u\\nstripe=%u\"];\n", pp, pp->name, pp->acr, pp->acw,
+	    pp->ace, pp->error, pp->sectorsize, pp->stripesize);
 }
 
 static void

Modified: projects/bhyve_svm/sys/modules/vmm/Makefile
==============================================================================
--- projects/bhyve_svm/sys/modules/vmm/Makefile	Mon Oct 20 01:52:17 2014	(r273298)
+++ projects/bhyve_svm/sys/modules/vmm/Makefile	Mon Oct 20 02:57:30 2014	(r273299)
@@ -3,6 +3,7 @@
 KMOD=	vmm
 
 SRCS=	opt_acpi.h opt_ddb.h device_if.h bus_if.h pci_if.h
+SRCS+=	vmx_assym.h svm_assym.h
 
 CFLAGS+= -DVMM_KEEP_STATS -DSMP
 CFLAGS+= -I${.CURDIR}/../../amd64/vmm
@@ -39,6 +40,7 @@ SRCS+=	iommu.c		\
 SRCS+=	ept.c		\
 	vmcs.c		\
 	vmx_msr.c	\
+	vmx_support.S	\
 	vmx.c		\
 	vtd.c
 
@@ -46,37 +48,37 @@ SRCS+=	ept.c		\
 .PATH: ${.CURDIR}/../../amd64/vmm/amd
 SRCS+=	vmcb.c		\
 	svm.c		\
+	svm_support.S	\
 	npt.c		\
 	amdv.c		\
 	svm_msr.c
 	
-OBJS=	vmx_support.o svm_support.o
+CLEANFILES=	vmx_assym.h vmx_genassym.o svm_assym.h svm_genassym.o
 
-CLEANFILES=	vmx_assym.s vmx_genassym.o svm_assym.s svm_genassym.o
-
-vmx_assym.s:    vmx_genassym.o
+vmx_assym.h:    vmx_genassym.o
 .if exists(@)
-vmx_assym.s:    @/kern/genassym.sh
+vmx_assym.h:    @/kern/genassym.sh
 .endif
 	sh @/kern/genassym.sh vmx_genassym.o > ${.TARGET}
 
-svm_assym.s:    svm_genassym.o
+svm_assym.h:    svm_genassym.o
 .if exists(@)
-svm_assym.s:    @/kern/genassym.sh
+svm_assym.h:    @/kern/genassym.sh
 .endif
 	sh @/kern/genassym.sh svm_genassym.o > ${.TARGET}
 
-vmx_support.o:	vmx_support.S vmx_assym.s
+vmx_support.o:
 	${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
 	    ${.IMPSRC} -o ${.TARGET}
 
-svm_support.o:	svm_support.S svm_assym.s
+svm_support.o:
 	${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
 	    ${.IMPSRC} -o ${.TARGET}
 
-vmx_genassym.o: vmx_genassym.c @ machine x86
+vmx_genassym.o:
 	${CC} -c ${CFLAGS:N-fno-common} ${.IMPSRC}
 
-svm_genassym.o: svm_genassym.c @ machine x86
+svm_genassym.o:
 	${CC} -c ${CFLAGS:N-fno-common} ${.IMPSRC}
+
 .include <bsd.kmod.mk>

Modified: projects/bhyve_svm/sys/net/if_lagg.c
==============================================================================
--- projects/bhyve_svm/sys/net/if_lagg.c	Mon Oct 20 01:52:17 2014	(r273298)
+++ projects/bhyve_svm/sys/net/if_lagg.c	Mon Oct 20 02:57:30 2014	(r273299)
@@ -569,9 +569,22 @@ lagg_clone_destroy(struct ifnet *ifp)
 static void
 lagg_lladdr(struct lagg_softc *sc, uint8_t *lladdr)
 {
+	struct ifnet *ifp = sc->sc_ifp;
 	struct lagg_port lp;
 
+	if (memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)
+		return;
+
 	LAGG_WLOCK_ASSERT(sc);
+	/*
+	 * Set the link layer address on the lagg interface.
+	 * lagg_proto_lladdr() notifies the MAC change to
+	 * the aggregation protocol.  iflladdr_event handler which
+	 * may trigger gratuitous ARPs for INET will be handled in
+	 * a taskqueue.
+	 */
+	bcopy(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN);
+	lagg_proto_lladdr(sc);
 
 	bzero(&lp, sizeof(lp));
 	lp.lp_ifp = sc->sc_ifp;
@@ -625,11 +638,13 @@ lagg_port_lladdr(struct lagg_port *lp, u
 	struct ifnet *ifp = lp->lp_ifp;
 	struct lagg_llq *llq;
 	int pending = 0;
+	int primary;
 
 	LAGG_WLOCK_ASSERT(sc);
 
-	if (lp->lp_detaching ||
-	    memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)
+	primary = (sc->sc_primary->lp_ifp == ifp) ? 1 : 0;
+	if (primary == 0 && (lp->lp_detaching ||
+	    memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0))
 		return;
 
 	/* Check to make sure its not already queued to be changed */
@@ -648,7 +663,7 @@ lagg_port_lladdr(struct lagg_port *lp, u
 
 	/* Update the lladdr even if pending, it may have changed */
 	llq->llq_ifp = ifp;
-	llq->llq_primary = (sc->sc_primary->lp_ifp == ifp) ? 1 : 0;
+	llq->llq_primary = primary;
 	bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN);
 
 	if (!pending)
@@ -692,23 +707,8 @@ lagg_port_setlladdr(void *arg, int pendi
 			if (error)
 				printf("%s: setlladdr failed on %s\n", __func__,
 				    ifp->if_xname);
-		} else {
-			/*
-			 * Set the link layer address on the lagg interface.
-			 * lagg_proto_lladdr() notifies the MAC change to
-			 * the aggregation protocol.  iflladdr_event handler
-			 * may trigger gratuitous ARPs for INET.
-			 */
-			if (memcmp(llq->llq_lladdr, IF_LLADDR(ifp),
-			    ETHER_ADDR_LEN) != 0) {
-				bcopy(llq->llq_lladdr, IF_LLADDR(ifp),
-				    ETHER_ADDR_LEN);
-				LAGG_WLOCK(sc);
-				lagg_proto_lladdr(sc);
-				LAGG_WUNLOCK(sc);
-				EVENTHANDLER_INVOKE(iflladdr_event, ifp);
-			}
-		}
+		} else
+			EVENTHANDLER_INVOKE(iflladdr_event, ifp);
 		CURVNET_RESTORE();
 		head = SLIST_NEXT(llq, llq_entries);
 		free(llq, M_DEVBUF);
@@ -742,34 +742,6 @@ lagg_port_create(struct lagg_softc *sc, 
 	if (ifp->if_type != IFT_ETHER)
 		return (EPROTONOSUPPORT);
 
-#ifdef INET6
-	/*
-	 * The member interface should not have inet6 address because
-	 * two interfaces with a valid link-local scope zone must not be
-	 * merged in any form.  This restriction is needed to
-	 * prevent violation of link-local scope zone.  Attempts to
-	 * add a member interface which has inet6 addresses triggers
-	 * removal of all inet6 addresses on the member interface.
-	 */
-	SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
-		if (in6ifa_llaonifp(lp->lp_ifp)) {
-			in6_ifdetach(lp->lp_ifp);
-			if_printf(sc->sc_ifp,
-			    "IPv6 addresses on %s have been removed "
-			    "before adding it as a member to prevent "
-			    "IPv6 address scope violation.\n",
-			    lp->lp_ifp->if_xname);
-		}
-	}
-	if (in6ifa_llaonifp(ifp)) {
-		in6_ifdetach(ifp);
-		if_printf(sc->sc_ifp,
-		    "IPv6 addresses on %s have been removed "
-		    "before adding it as a member to prevent "
-		    "IPv6 address scope violation.\n",
-		    ifp->if_xname);
-	}
-#endif
 	/* Allow the first Ethernet member to define the MTU */
 	if (SLIST_EMPTY(&sc->sc_ports))
 		sc->sc_ifp->if_mtu = ifp->if_mtu;
@@ -1414,6 +1386,26 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd
 			error = EINVAL;
 			break;
 		}
+#ifdef INET6
+		/*
+		 * A laggport interface should not have inet6 address
+		 * because two interfaces with a valid link-local
+		 * scope zone must not be merged in any form.  This
+		 * restriction is needed to prevent violation of
+		 * link-local scope zone.  Attempts to add a laggport
+		 * interface which has inet6 addresses triggers
+		 * removal of all inet6 addresses on the member
+		 * interface.
+		 */
+		if (in6ifa_llaonifp(tpif)) {
+			in6_ifdetach(tpif);
+				if_printf(sc->sc_ifp,
+				    "IPv6 addresses on %s have been removed "
+				    "before adding it as a member to prevent "
+				    "IPv6 address scope violation.\n",
+				    tpif->if_xname);
+		}
+#endif
 		LAGG_WLOCK(sc);
 		error = lagg_port_create(sc, tpif);
 		LAGG_WUNLOCK(sc);

Modified: projects/bhyve_svm/usr.sbin/bhyve/block_if.c
==============================================================================
--- projects/bhyve_svm/usr.sbin/bhyve/block_if.c	Mon Oct 20 01:52:17 2014	(r273298)
+++ projects/bhyve_svm/usr.sbin/bhyve/block_if.c	Mon Oct 20 02:57:30 2014	(r273299)
@@ -55,8 +55,7 @@ __FBSDID("$FreeBSD$");
 enum blockop {
 	BOP_READ,
 	BOP_WRITE,
-	BOP_FLUSH,
-	BOP_CANCEL
+	BOP_FLUSH
 };
 
 enum blockstat {
@@ -159,9 +158,6 @@ blockif_proc(struct blockif_ctxt *bc, st
 		break;
 	case BOP_FLUSH:
 		break;
-	case BOP_CANCEL:
-		err = EINTR;
-		break;
 	default:
 		err = EINVAL;
 		break;
@@ -356,9 +352,28 @@ blockif_flush(struct blockif_ctxt *bc, s
 int
 blockif_cancel(struct blockif_ctxt *bc, struct blockif_req *breq)
 {
+	struct blockif_elem *be;
 
 	assert(bc->bc_magic == BLOCKIF_SIG);
-	return (blockif_request(bc, breq, BOP_CANCEL));
+
+	pthread_mutex_lock(&bc->bc_mtx);
+	TAILQ_FOREACH(be, &bc->bc_inuseq, be_link) {
+		if (be->be_req == breq)
+			break;
+	}
+	if (be == NULL) {
+		pthread_mutex_unlock(&bc->bc_mtx);
+		return (EINVAL);
+	}
+
+	TAILQ_REMOVE(&bc->bc_inuseq, be, be_link);
+	be->be_status = BST_FREE;
+	be->be_req = NULL;
+	TAILQ_INSERT_TAIL(&bc->bc_freeq, be, be_link);
+	bc->bc_req_count--;
+	pthread_mutex_unlock(&bc->bc_mtx);
+
+	return (0);
 }
 
 int

Modified: projects/bhyve_svm/usr.sbin/bhyve/pci_ahci.c
==============================================================================
--- projects/bhyve_svm/usr.sbin/bhyve/pci_ahci.c	Mon Oct 20 01:52:17 2014	(r273298)
+++ projects/bhyve_svm/usr.sbin/bhyve/pci_ahci.c	Mon Oct 20 02:57:30 2014	(r273299)
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
 #include <unistd.h>
 #include <assert.h>
 #include <pthread.h>
+#include <pthread_np.h>
 #include <inttypes.h>
 
 #include "bhyverun.h"
@@ -115,7 +116,8 @@ static FILE *dbg;
 struct ahci_ioreq {
 	struct blockif_req io_req;
 	struct ahci_port *io_pr;
-	STAILQ_ENTRY(ahci_ioreq) io_list;
+	STAILQ_ENTRY(ahci_ioreq) io_flist;
+	TAILQ_ENTRY(ahci_ioreq) io_blist;
 	uint8_t *cfis;
 	uint32_t len;
 	uint32_t done;
@@ -160,6 +162,7 @@ struct ahci_port {
 	struct ahci_ioreq *ioreq;
 	int ioqsz;
 	STAILQ_HEAD(ahci_fhead, ahci_ioreq) iofhd;
+	TAILQ_HEAD(ahci_bhead, ahci_ioreq) iobhd;
 };
 
 struct ahci_cmd_hdr {
@@ -360,6 +363,68 @@ ahci_write_reset_fis_d2h(struct ahci_por
 }
 
 static void
+ahci_check_stopped(struct ahci_port *p)
+{
+	/*
+	 * If we are no longer processing the command list and nothing
+	 * is in-flight, clear the running bit.
+	 */
+	if (!(p->cmd & AHCI_P_CMD_ST)) {
+		if (p->pending == 0)
+			p->cmd &= ~(AHCI_P_CMD_CR | AHCI_P_CMD_CCS_MASK);
+	}
+}
+
+static void
+ahci_port_stop(struct ahci_port *p)
+{
+	struct ahci_ioreq *aior;
+	uint8_t *cfis;
+	int slot;
+	int ncq;
+	int error;
+
+	assert(pthread_mutex_isowned_np(&p->pr_sc->mtx));
+
+	TAILQ_FOREACH(aior, &p->iobhd, io_blist) {
+		/*
+		 * Try to cancel the outstanding blockif request.
+		 */
+		error = blockif_cancel(p->bctx, &aior->io_req);
+		if (error != 0)
+			continue;
+
+		slot = aior->slot;
+		cfis = aior->cfis;
+		if (cfis[2] == ATA_WRITE_FPDMA_QUEUED ||
+		    cfis[2] == ATA_READ_FPDMA_QUEUED)
+			ncq = 1;
+
+		if (ncq)
+			p->sact &= ~(1 << slot);
+		else
+			p->ci &= ~(1 << slot);
+
+		/*
+		 * This command is now done.
+		 */
+		p->pending &= ~(1 << slot);
+
+		/*
+		 * Delete the blockif request from the busy list
+		 */
+		TAILQ_REMOVE(&p->iobhd, aior, io_blist);
+
+		/*
+		 * Move the blockif request back to the free list
+		 */
+		STAILQ_INSERT_TAIL(&p->iofhd, aior, io_flist);
+	}
+
+	ahci_check_stopped(p);
+}
+
+static void
 ahci_port_reset(struct ahci_port *pr)
 {
 	pr->sctl = 0;
@@ -492,7 +557,7 @@ ahci_handle_dma(struct ahci_port *p, int
 	 */
 	aior = STAILQ_FIRST(&p->iofhd);
 	assert(aior != NULL);
-	STAILQ_REMOVE_HEAD(&p->iofhd, io_list);
+	STAILQ_REMOVE_HEAD(&p->iofhd, io_flist);
 	aior->cfis = cfis;
 	aior->slot = slot;
 	aior->len = len;
@@ -503,15 +568,21 @@ ahci_handle_dma(struct ahci_port *p, int
 	if (iovcnt > BLOCKIF_IOV_MAX) {
 		aior->prdtl = iovcnt - BLOCKIF_IOV_MAX;
 		iovcnt = BLOCKIF_IOV_MAX;
-		/*
-		 * Mark this command in-flight.
-		 */
-		p->pending |= 1 << slot;
 	} else
 		aior->prdtl = 0;
 	breq->br_iovcnt = iovcnt;
 
 	/*
+	 * Mark this command in-flight.
+	 */
+	p->pending |= 1 << slot;
+
+	/*
+	 * Stuff request onto busy list
+	 */
+	TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist);
+
+	/*
 	 * Build up the iovec based on the prdt
 	 */
 	for (i = 0; i < iovcnt; i++) {
@@ -546,7 +617,7 @@ ahci_handle_flush(struct ahci_port *p, i
 	 */
 	aior = STAILQ_FIRST(&p->iofhd);
 	assert(aior != NULL);
-	STAILQ_REMOVE_HEAD(&p->iofhd, io_list);
+	STAILQ_REMOVE_HEAD(&p->iofhd, io_flist);
 	aior->cfis = cfis;
 	aior->slot = slot;
 	aior->len = 0;
@@ -554,6 +625,16 @@ ahci_handle_flush(struct ahci_port *p, i
 	aior->prdtl = 0;
 	breq = &aior->io_req;
 
+	/*
+	 * Mark this command in-flight.
+	 */
+	p->pending |= 1 << slot;
+
+	/*
+	 * Stuff request onto busy list
+	 */
+	TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist);
+
 	err = blockif_flush(p->bctx, breq);
 	assert(err == 0);
 }
@@ -961,7 +1042,7 @@ atapi_read(struct ahci_port *p, int slot
 	 */
 	aior = STAILQ_FIRST(&p->iofhd);
 	assert(aior != NULL);
-	STAILQ_REMOVE_HEAD(&p->iofhd, io_list);
+	STAILQ_REMOVE_HEAD(&p->iofhd, io_flist);
 	aior->cfis = cfis;
 	aior->slot = slot;
 	aior->len = len;
@@ -977,6 +1058,16 @@ atapi_read(struct ahci_port *p, int slot
 	breq->br_iovcnt = iovcnt;
 
 	/*
+	 * Mark this command in-flight.
+	 */
+	p->pending |= 1 << slot;
+
+	/*
+	 * Stuff request onto busy list
+	 */
+	TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist);
+
+	/*
 	 * Build up the iovec based on the prdt
 	 */
 	for (i = 0; i < iovcnt; i++) {
@@ -1415,9 +1506,14 @@ ata_ioreq_cb(struct blockif_req *br, int
 	pthread_mutex_lock(&sc->mtx);
 
 	/*
+	 * Delete the blockif request from the busy list
+	 */
+	TAILQ_REMOVE(&p->iobhd, aior, io_blist);
+
+	/*
 	 * Move the blockif request back to the free list
 	 */
-	STAILQ_INSERT_TAIL(&p->iofhd, aior, io_list);
+	STAILQ_INSERT_TAIL(&p->iofhd, aior, io_flist);
 
 	if (pending && !err) {
 		ahci_handle_dma(p, slot, cfis, aior->done,
@@ -1438,17 +1534,18 @@ ata_ioreq_cb(struct blockif_req *br, int
 			p->serr |= (1 << slot);
 	}
 
-	/*
-	 * This command is now complete.
-	 */
-	p->pending &= ~(1 << slot);
-
 	if (ncq) {
 		p->sact &= ~(1 << slot);
 		ahci_write_fis_sdb(p, slot, tfd);
 	} else
 		ahci_write_fis_d2h(p, slot, cfis, tfd);
 
+	/*
+	 * This command is now complete.
+	 */
+	p->pending &= ~(1 << slot);
+
+	ahci_check_stopped(p);
 out:
 	pthread_mutex_unlock(&sc->mtx);
 	DPRINTF("%s exit\n", __func__);
@@ -1478,9 +1575,14 @@ atapi_ioreq_cb(struct blockif_req *br, i
 	pthread_mutex_lock(&sc->mtx);
 
 	/*
+	 * Delete the blockif request from the busy list
+	 */
+	TAILQ_REMOVE(&p->iobhd, aior, io_blist);
+
+	/*
 	 * Move the blockif request back to the free list
 	 */
-	STAILQ_INSERT_TAIL(&p->iofhd, aior, io_list);
+	STAILQ_INSERT_TAIL(&p->iofhd, aior, io_flist);
 
 	if (pending && !err) {
 		atapi_read(p, slot, cfis, aior->done, hdr->prdtl - pending);
@@ -1500,6 +1602,12 @@ atapi_ioreq_cb(struct blockif_req *br, i
 	cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN;
 	ahci_write_fis_d2h(p, slot, cfis, tfd);
 
+	/*
+	 * This command is now complete.
+	 */
+	p->pending &= ~(1 << slot);
+
+	ahci_check_stopped(p);
 out:
 	pthread_mutex_unlock(&sc->mtx);
 	DPRINTF("%s exit\n", __func__);
@@ -1526,8 +1634,10 @@ pci_ahci_ioreq_init(struct ahci_port *pr
 		else
 			vr->io_req.br_callback = atapi_ioreq_cb;
 		vr->io_req.br_param = vr;
-		STAILQ_INSERT_TAIL(&pr->iofhd, vr, io_list);
+		STAILQ_INSERT_TAIL(&pr->iofhd, vr, io_flist);
 	}
+
+	TAILQ_INIT(&pr->iobhd);
 }
 
 static void
@@ -1565,9 +1675,7 @@ pci_ahci_port_write(struct pci_ahci_soft
 		p->cmd = value;
 		
 		if (!(value & AHCI_P_CMD_ST)) {
-			p->cmd &= ~(AHCI_P_CMD_CR | AHCI_P_CMD_CCS_MASK);
-			p->ci = 0;
-			p->sact = 0;
+			ahci_port_stop(p);
 		} else {
 			uint64_t clb;
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201410200257.s9K2vUdJ032520>