Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Oct 2013 19:07:48 +0000 (UTC)
From:      Mark Murray <markm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r256162 - in projects/random_number_generator: sbin/nvmecontrol sbin/route sys/cddl/contrib/opensolaris/uts/common/dtrace sys/cddl/dev/dtrace sys/dev/ath/ath_hal/ar5212 sys/dev/nvd sys/...
Message-ID:  <201310081907.r98J7mwu003458@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markm
Date: Tue Oct  8 19:07:48 2013
New Revision: 256162
URL: http://svnweb.freebsd.org/changeset/base/256162

Log:
  MFC - tracking commit.

Modified:
  projects/random_number_generator/sbin/nvmecontrol/perftest.c
  projects/random_number_generator/sbin/route/route.c
  projects/random_number_generator/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
  projects/random_number_generator/sys/cddl/dev/dtrace/dtrace_load.c
  projects/random_number_generator/sys/cddl/dev/dtrace/dtrace_unload.c
  projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212.h
  projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c
  projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
  projects/random_number_generator/sys/dev/nvd/nvd.c
  projects/random_number_generator/sys/dev/nvme/nvme.c
  projects/random_number_generator/sys/dev/nvme/nvme.h
  projects/random_number_generator/sys/dev/nvme/nvme_ctrlr.c
  projects/random_number_generator/sys/dev/nvme/nvme_ns.c
  projects/random_number_generator/sys/dev/nvme/nvme_private.h
  projects/random_number_generator/sys/dev/nvme/nvme_test.c
  projects/random_number_generator/sys/dev/random/ivy.c
  projects/random_number_generator/usr.sbin/bhyve/bhyverun.c
  projects/random_number_generator/usr.sbin/bhyve/dbgport.h
Directory Properties:
  projects/random_number_generator/   (props changed)
  projects/random_number_generator/sbin/   (props changed)
  projects/random_number_generator/sys/   (props changed)
  projects/random_number_generator/sys/cddl/contrib/opensolaris/   (props changed)
  projects/random_number_generator/usr.sbin/bhyve/   (props changed)

Modified: projects/random_number_generator/sbin/nvmecontrol/perftest.c
==============================================================================
--- projects/random_number_generator/sbin/nvmecontrol/perftest.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sbin/nvmecontrol/perftest.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
 #include <ctype.h>
 #include <err.h>
 #include <fcntl.h>
+#include <inttypes.h>
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -45,7 +46,8 @@ __FBSDID("$FreeBSD$");
 static void
 print_perftest(struct nvme_io_test *io_test, bool perthread)
 {
-	uint32_t i, io_completed = 0, iops, mbps;
+	uint64_t	io_completed = 0, iops, mbps;
+	uint32_t	i;
 
 	for (i = 0; i < io_test->num_threads; i++)
 		io_completed += io_test->io_completed[i];
@@ -53,15 +55,15 @@ print_perftest(struct nvme_io_test *io_t
 	iops = io_completed/io_test->time;
 	mbps = iops * io_test->size / (1024*1024);
 
-	printf("Threads: %2d Size: %6d %5s Time: %3d IO/s: %7d MB/s: %4d\n",
+	printf("Threads: %2d Size: %6d %5s Time: %3d IO/s: %7ju MB/s: %4ju\n",
 	    io_test->num_threads, io_test->size,
 	    io_test->opc == NVME_OPC_READ ? "READ" : "WRITE",
-	    io_test->time, iops, mbps);
+	    io_test->time, (uintmax_t)iops, (uintmax_t)mbps);
 
 	if (perthread)
 		for (i = 0; i < io_test->num_threads; i++)
-			printf("\t%3d: %8d IO/s\n", i,
-			    io_test->io_completed[i]/io_test->time);
+			printf("\t%3d: %8ju IO/s\n", i,
+			    (uintmax_t)io_test->io_completed[i]/io_test->time);
 
 	exit(1);
 }

Modified: projects/random_number_generator/sbin/route/route.c
==============================================================================
--- projects/random_number_generator/sbin/route/route.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sbin/route/route.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -928,6 +928,11 @@ newroute(int argc, char **argv)
 		}
 	}
 
+	if (so[RTAX_DST].ss_len == 0) {
+		warnx("destination parameter required");
+		usage(NULL);
+	}
+
 	if (nrflags & F_FORCEHOST) {
 		nrflags |= F_ISHOST;
 #ifdef INET6

Modified: projects/random_number_generator/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
==============================================================================
--- projects/random_number_generator/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -15751,10 +15751,6 @@ dtrace_open(struct cdev *dev, int oflags
 #else
 	devfs_set_cdevpriv(state, dtrace_dtr);
 #endif
-	/* This code actually belongs in dtrace_attach() */
-	if (dtrace_opens == 1)
-		dtrace_taskq = taskq_create("dtrace_taskq", 1, maxclsyspri,
-		    1, INT_MAX, 0);
 #endif
 
 	mutex_exit(&cpu_lock);
@@ -15842,11 +15838,6 @@ dtrace_dtr(void *data)
 		(void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE);
 #else
 	--dtrace_opens;
-	/* This code actually belongs in dtrace_detach() */
-	if ((dtrace_opens == 0) && (dtrace_taskq != NULL)) {
-		taskq_destroy(dtrace_taskq);
-		dtrace_taskq = NULL;
-	}
 #endif
 
 	mutex_exit(&dtrace_lock);

Modified: projects/random_number_generator/sys/cddl/dev/dtrace/dtrace_load.c
==============================================================================
--- projects/random_number_generator/sys/cddl/dev/dtrace/dtrace_load.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/cddl/dev/dtrace/dtrace_load.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -56,6 +56,8 @@ dtrace_load(void *dummy)
 	/* Hang our hook for exceptions. */
 	dtrace_invop_init();
 
+	dtrace_taskq = taskq_create("dtrace_taskq", 1, maxclsyspri, 0, 0, 0);
+
 	/* Register callbacks for linker file load and unload events. */
 	dtrace_kld_load_tag = EVENTHANDLER_REGISTER(kld_load,
 	    dtrace_kld_load, NULL, EVENTHANDLER_PRI_ANY);

Modified: projects/random_number_generator/sys/cddl/dev/dtrace/dtrace_unload.c
==============================================================================
--- projects/random_number_generator/sys/cddl/dev/dtrace/dtrace_unload.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/cddl/dev/dtrace/dtrace_unload.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -127,6 +127,8 @@ dtrace_unload()
 	mutex_destroy(&dtrace_errlock);
 #endif
 
+	taskq_destroy(dtrace_taskq);
+
 	/* Reset our hook for exceptions. */
 	dtrace_invop_uninit();
 

Modified: projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212.h
==============================================================================
--- projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212.h	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212.h	Tue Oct  8 19:07:48 2013	(r256162)
@@ -335,6 +335,16 @@ struct ath_hal_5212 {
 
 	uint8_t		ah_txTrigLev;		/* current Tx trigger level */
 	uint8_t		ah_maxTxTrigLev;	/* max tx trigger level */
+
+	/*
+	 * Channel Tx, Rx, Rx Clear State
+	 */
+	uint32_t	ah_cycleCount;
+	uint32_t	ah_ctlBusy;
+	uint32_t	ah_rxBusy;
+	uint32_t	ah_txBusy;
+	uint32_t	ah_rx_chainmask;
+	uint32_t	ah_tx_chainmask;
 };
 #define	AH5212(_ah)	((struct ath_hal_5212 *)(_ah))
 

Modified: projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c
==============================================================================
--- projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_ani.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -865,16 +865,40 @@ static int32_t
 ar5212AniGetListenTime(struct ath_hal *ah)
 {
 	struct ath_hal_5212 *ahp = AH5212(ah);
-	struct ar5212AniState *aniState;
-	uint32_t txFrameCount, rxFrameCount, cycleCount;
-	int32_t listenTime;
+	struct ar5212AniState *aniState = NULL;
+	int32_t listenTime = 0;
+	int good;
+	HAL_SURVEY_SAMPLE hs;
+	HAL_CHANNEL_SURVEY *cs = AH_NULL;
+
+	/*
+	 * We shouldn't see ah_curchan be NULL, but just in case..
+	 */
+	if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) {
+		ath_hal_printf(ah, "%s: ah_curchan = NULL?\n", __func__);
+		return (0);
+	}
 
-	txFrameCount = OS_REG_READ(ah, AR_TFCNT);
-	rxFrameCount = OS_REG_READ(ah, AR_RFCNT);
-	cycleCount = OS_REG_READ(ah, AR_CCCNT);
+	cs = &ahp->ah_chansurvey;
+
+	/*
+	 * Fetch the current statistics, squirrel away the current
+	 * sample, bump the sequence/sample counter.
+	 */
+	OS_MEMZERO(&hs, sizeof(hs));
+	good = ar5212GetMibCycleCounts(ah, &hs);
+	if (cs != AH_NULL) {
+		OS_MEMCPY(&cs->samples[cs->cur_sample], &hs, sizeof(hs));
+		cs->samples[cs->cur_sample].seq_num = cs->cur_seq;
+		cs->cur_sample =
+		    (cs->cur_sample + 1) % CHANNEL_SURVEY_SAMPLE_COUNT;
+		cs->cur_seq++;
+	}
 
-	aniState = ahp->ah_curani;
-	if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
+	if (ANI_ENA(ah))
+		aniState = ahp->ah_curani;
+
+	if (good == AH_FALSE) {
 		/*
 		 * Cycle counter wrap (or initial call); it's not possible
 		 * to accurately calculate a value because the registers
@@ -882,15 +906,29 @@ ar5212AniGetListenTime(struct ath_hal *a
 		 */
 		listenTime = 0;
 		ahp->ah_stats.ast_ani_lzero++;
-	} else {
-		int32_t ccdelta = cycleCount - aniState->cycleCount;
-		int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
-		int32_t tfdelta = txFrameCount - aniState->txFrameCount;
+	} else if (ANI_ENA(ah)) {
+		/*
+		 * Only calculate and update the cycle count if we have
+		 * an ANI state.
+		 */
+		int32_t ccdelta =
+		    AH5212(ah)->ah_cycleCount - aniState->cycleCount;
+		int32_t rfdelta =
+		    AH5212(ah)->ah_rxBusy - aniState->rxFrameCount;
+		int32_t tfdelta =
+		    AH5212(ah)->ah_txBusy - aniState->txFrameCount;
 		listenTime = (ccdelta - rfdelta - tfdelta) / CLOCK_RATE;
 	}
-	aniState->cycleCount = cycleCount;
-	aniState->txFrameCount = txFrameCount;
-	aniState->rxFrameCount = rxFrameCount;
+
+	/*
+	 * Again, only update ANI state if we have it.
+	 */
+	if (ANI_ENA(ah)) {
+		aniState->cycleCount = AH5212(ah)->ah_cycleCount;
+		aniState->rxFrameCount = AH5212(ah)->ah_rxBusy;
+		aniState->txFrameCount = AH5212(ah)->ah_txBusy;
+	}
+
 	return listenTime;
 }
 
@@ -956,13 +994,15 @@ ar5212AniPoll(struct ath_hal *ah, const 
 	const struct ar5212AniParams *params;
 	int32_t listenTime;
 
+	/* Always update from the MIB, for statistics gathering */
+	listenTime = ar5212AniGetListenTime(ah);
+
 	/* XXX can aniState be null? */
 	if (aniState == AH_NULL)
 		return;
 	if (!ANI_ENA(ah))
 		return;
 
-	listenTime = ar5212AniGetListenTime(ah);
 	if (listenTime < 0) {
 		ahp->ah_stats.ast_ani_lneg++;
 		/* restart ANI period if listenTime is invalid */

Modified: projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c
==============================================================================
--- projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/dev/ath/ath_hal/ar5212/ar5212_misc.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -1405,13 +1405,47 @@ ar5212Get11nExtBusy(struct ath_hal *ah)
 }
 
 /*
- * There's no channel survey support for the AR5212.
+ * Channel survey support.
  */
 HAL_BOOL
 ar5212GetMibCycleCounts(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hsample)
 {
+	struct ath_hal_5212 *ahp = AH5212(ah);
+	u_int32_t good = AH_TRUE;
 
-	return (AH_FALSE);
+	/* XXX freeze/unfreeze mib counters */
+	uint32_t rc = OS_REG_READ(ah, AR_RCCNT);
+	uint32_t rf = OS_REG_READ(ah, AR_RFCNT);
+	uint32_t tf = OS_REG_READ(ah, AR_TFCNT);
+	uint32_t cc = OS_REG_READ(ah, AR_CCCNT); /* read cycles last */
+
+	if (ahp->ah_cycleCount == 0 || ahp->ah_cycleCount > cc) {
+		/*
+		 * Cycle counter wrap (or initial call); it's not possible
+		 * to accurately calculate a value because the registers
+		 * right shift rather than wrap--so punt and return 0.
+		 */
+		HALDEBUG(ah, HAL_DEBUG_ANY,
+		    "%s: cycle counter wrap. ExtBusy = 0\n", __func__);
+		good = AH_FALSE;
+	} else {
+		hsample->cycle_count = cc - ahp->ah_cycleCount;
+		hsample->chan_busy = rc - ahp->ah_ctlBusy;
+		hsample->ext_chan_busy = 0;
+		hsample->rx_busy = rf - ahp->ah_rxBusy;
+		hsample->tx_busy = tf - ahp->ah_txBusy;
+	}
+
+	/*
+	 * Keep a copy of the MIB results so the next sample has something
+	 * to work from.
+	 */
+	ahp->ah_cycleCount = cc;
+	ahp->ah_rxBusy = rf;
+	ahp->ah_ctlBusy = rc;
+	ahp->ah_txBusy = tf;
+
+	return (good);
 }
 
 void

Modified: projects/random_number_generator/sys/dev/nvd/nvd.c
==============================================================================
--- projects/random_number_generator/sys/dev/nvd/nvd.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/dev/nvd/nvd.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -187,17 +187,6 @@ nvd_done(void *arg, const struct nvme_co
 
 	atomic_add_int(&ndisk->cur_depth, -1);
 
-	/*
-	 * TODO: add more extensive translation of NVMe status codes
-	 *  to different bio error codes (i.e. EIO, EINVAL, etc.)
-	 */
-	if (nvme_completion_is_error(cpl)) {
-		bp->bio_error = EIO;
-		bp->bio_flags |= BIO_ERROR;
-		bp->bio_resid = bp->bio_bcount;
-	} else
-		bp->bio_resid = 0;
-
 	biodone(bp);
 }
 

Modified: projects/random_number_generator/sys/dev/nvme/nvme.c
==============================================================================
--- projects/random_number_generator/sys/dev/nvme/nvme.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/dev/nvme/nvme.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -221,8 +221,10 @@ nvme_attach(device_t dev)
 
 	status = nvme_ctrlr_construct(ctrlr, dev);
 
-	if (status != 0)
+	if (status != 0) {
+		nvme_ctrlr_destruct(ctrlr, dev);
 		return (status);
+	}
 
 	/*
 	 * Reset controller twice to ensure we do a transition from cc.en==1
@@ -230,12 +232,16 @@ nvme_attach(device_t dev)
 	 *  the controller was left in when boot handed off to OS.
 	 */
 	status = nvme_ctrlr_hw_reset(ctrlr);
-	if (status != 0)
+	if (status != 0) {
+		nvme_ctrlr_destruct(ctrlr, dev);
 		return (status);
+	}
 
 	status = nvme_ctrlr_hw_reset(ctrlr);
-	if (status != 0)
+	if (status != 0) {
+		nvme_ctrlr_destruct(ctrlr, dev);
 		return (status);
+	}
 
 	nvme_sysctl_initialize_ctrlr(ctrlr);
 

Modified: projects/random_number_generator/sys/dev/nvme/nvme.h
==============================================================================
--- projects/random_number_generator/sys/dev/nvme/nvme.h	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/dev/nvme/nvme.h	Tue Oct  8 19:07:48 2013	(r256162)
@@ -535,7 +535,7 @@ struct nvme_controller_data {
 	uint8_t			reserved6[1024];
 
 	/* bytes 3072-4095: vendor specific */
-	uint8_t			reserved7[1024];
+	uint8_t			vs[1024];
 } __packed __aligned(4);
 
 struct nvme_namespace_data {
@@ -720,7 +720,7 @@ struct nvme_io_test {
 	uint32_t		time;	/* in seconds */
 	uint32_t		num_threads;
 	uint32_t		flags;
-	uint32_t		io_completed[NVME_TEST_MAX_THREADS];
+	uint64_t		io_completed[NVME_TEST_MAX_THREADS];
 };
 
 enum nvme_io_test_flags {

Modified: projects/random_number_generator/sys/dev/nvme/nvme_ctrlr.c
==============================================================================
--- projects/random_number_generator/sys/dev/nvme/nvme_ctrlr.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/dev/nvme/nvme_ctrlr.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -617,9 +617,35 @@ nvme_ctrlr_get_log_page_size(struct nvme
 }
 
 static void
+nvme_ctrlr_log_critical_warnings(struct nvme_controller *ctrlr,
+    union nvme_critical_warning_state state)
+{
+
+	if (state.bits.available_spare == 1)
+		nvme_printf(ctrlr, "available spare space below threshold\n");
+
+	if (state.bits.temperature == 1)
+		nvme_printf(ctrlr, "temperature above threshold\n");
+
+	if (state.bits.device_reliability == 1)
+		nvme_printf(ctrlr, "device reliability degraded\n");
+
+	if (state.bits.read_only == 1)
+		nvme_printf(ctrlr, "media placed in read only mode\n");
+
+	if (state.bits.volatile_memory_backup == 1)
+		nvme_printf(ctrlr, "volatile memory backup device failed\n");
+
+	if (state.bits.reserved != 0)
+		nvme_printf(ctrlr,
+		    "unknown critical warning(s): state = 0x%02x\n", state.raw);
+}
+
+static void
 nvme_ctrlr_async_event_log_page_cb(void *arg, const struct nvme_completion *cpl)
 {
-	struct nvme_async_event_request	*aer = arg;
+	struct nvme_async_event_request		*aer = arg;
+	struct nvme_health_information_page	*health_info;
 
 	/*
 	 * If the log page fetch for some reason completed with an error,
@@ -629,13 +655,33 @@ nvme_ctrlr_async_event_log_page_cb(void 
 	if (nvme_completion_is_error(cpl))
 		nvme_notify_async_consumers(aer->ctrlr, &aer->cpl,
 		    aer->log_page_id, NULL, 0);
-	else
+	else {
+		if (aer->log_page_id == NVME_LOG_HEALTH_INFORMATION) {
+			health_info = (struct nvme_health_information_page *)
+			    aer->log_page_buffer;
+			nvme_ctrlr_log_critical_warnings(aer->ctrlr,
+			    health_info->critical_warning);
+			/*
+			 * Critical warnings reported through the
+			 *  SMART/health log page are persistent, so
+			 *  clear the associated bits in the async event
+			 *  config so that we do not receive repeated
+			 *  notifications for the same event.
+			 */
+			aer->ctrlr->async_event_config.raw &=
+			    ~health_info->critical_warning.raw;
+			nvme_ctrlr_cmd_set_async_event_config(aer->ctrlr,
+			    aer->ctrlr->async_event_config, NULL, NULL);
+		}
+
+
 		/*
 		 * Pass the cpl data from the original async event completion,
 		 *  not the log page fetch.
 		 */
 		nvme_notify_async_consumers(aer->ctrlr, &aer->cpl,
 		    aer->log_page_id, aer->log_page_buffer, aer->log_page_size);
+	}
 
 	/*
 	 * Repost another asynchronous event request to replace the one
@@ -708,13 +754,27 @@ nvme_ctrlr_construct_and_submit_aer(stru
 static void
 nvme_ctrlr_configure_aer(struct nvme_controller *ctrlr)
 {
-	union nvme_critical_warning_state	state;
+	struct nvme_completion_poll_status	status;
 	struct nvme_async_event_request		*aer;
 	uint32_t				i;
 
-	state.raw = 0xFF;
-	state.bits.reserved = 0;
-	nvme_ctrlr_cmd_set_async_event_config(ctrlr, state, NULL, NULL);
+	ctrlr->async_event_config.raw = 0xFF;
+	ctrlr->async_event_config.bits.reserved = 0;
+
+	status.done = FALSE;
+	nvme_ctrlr_cmd_get_feature(ctrlr, NVME_FEAT_TEMPERATURE_THRESHOLD,
+	    0, NULL, 0, nvme_completion_poll_cb, &status);
+	while (status.done == FALSE)
+		pause("nvme", 1);
+	if (nvme_completion_is_error(&status.cpl) ||
+	    (status.cpl.cdw0 & 0xFFFF) == 0xFFFF ||
+	    (status.cpl.cdw0 & 0xFFFF) == 0x0000) {
+		nvme_printf(ctrlr, "temperature threshold not supported\n");
+		ctrlr->async_event_config.bits.temperature = 0;
+	}
+
+	nvme_ctrlr_cmd_set_async_event_config(ctrlr,
+	    ctrlr->async_event_config, NULL, NULL);
 
 	/* aerl is a zero-based value, so we need to add 1 here. */
 	ctrlr->num_aers = min(NVME_MAX_ASYNC_EVENTS, (ctrlr->cdata.aerl+1));

Modified: projects/random_number_generator/sys/dev/nvme/nvme_ns.c
==============================================================================
--- projects/random_number_generator/sys/dev/nvme/nvme_ns.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/dev/nvme/nvme_ns.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -34,13 +34,31 @@ __FBSDID("$FreeBSD$");
 #include <sys/disk.h>
 #include <sys/fcntl.h>
 #include <sys/ioccom.h>
+#include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/proc.h>
 
 #include <dev/pci/pcivar.h>
 
+#include <geom/geom.h>
+
 #include "nvme_private.h"
 
+static void		nvme_bio_child_inbed(struct bio *parent, int bio_error);
+static void		nvme_bio_child_done(void *arg,
+					    const struct nvme_completion *cpl);
+static uint32_t		nvme_get_num_segments(uint64_t addr, uint64_t size,
+					      uint32_t alignment);
+static void		nvme_free_child_bios(int num_bios,
+					     struct bio **child_bios);
+static struct bio **	nvme_allocate_child_bios(int num_bios);
+static struct bio **	nvme_construct_child_bios(struct bio *bp,
+						  uint32_t alignment,
+						  int *num_bios);
+static int		nvme_ns_split_bio(struct nvme_namespace *ns,
+					  struct bio *bp,
+					  uint32_t alignment);
+
 static int
 nvme_ns_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag,
     struct thread *td)
@@ -202,18 +220,218 @@ nvme_ns_bio_done(void *arg, const struct
 	if (bp->bio_driver2)
 		free(bp->bio_driver2, M_NVME);
 
+	if (nvme_completion_is_error(status)) {
+		bp->bio_flags |= BIO_ERROR;
+		if (bp->bio_error == 0)
+			bp->bio_error = EIO;
+	}
+
+	if ((bp->bio_flags & BIO_ERROR) == 0)
+		bp->bio_resid = 0;
+	else
+		bp->bio_resid = bp->bio_bcount;
+
 	bp_cb_fn(bp, status);
 }
 
+static void
+nvme_bio_child_inbed(struct bio *parent, int bio_error)
+{
+	struct nvme_completion	parent_cpl;
+	int			inbed;
+
+	if (bio_error != 0) {
+		parent->bio_flags |= BIO_ERROR;
+		parent->bio_error = bio_error;
+	}
+
+	/*
+	 * atomic_fetchadd will return value before adding 1, so we still
+	 *  must add 1 to get the updated inbed number.
+	 */
+	inbed = atomic_fetchadd_int(&parent->bio_inbed, 1) + 1;
+	if (inbed == parent->bio_children) {
+		bzero(&parent_cpl, sizeof(parent_cpl));
+		if (parent->bio_flags & BIO_ERROR)
+			parent_cpl.status.sc = NVME_SC_DATA_TRANSFER_ERROR;
+		nvme_ns_bio_done(parent, &parent_cpl);
+	}
+}
+
+static void
+nvme_bio_child_done(void *arg, const struct nvme_completion *cpl)
+{
+	struct bio		*child = arg;
+	struct bio		*parent;
+	int			bio_error;
+
+	parent = child->bio_parent;
+	g_destroy_bio(child);
+	bio_error = nvme_completion_is_error(cpl) ? EIO : 0;
+	nvme_bio_child_inbed(parent, bio_error);
+}
+
+static uint32_t
+nvme_get_num_segments(uint64_t addr, uint64_t size, uint32_t align)
+{
+	uint32_t	num_segs, offset, remainder;
+
+	if (align == 0)
+		return (1);
+
+	KASSERT((align & (align - 1)) == 0, ("alignment not power of 2\n"));
+
+	num_segs = size / align;
+	remainder = size & (align - 1);
+	offset = addr & (align - 1);
+	if (remainder > 0 || offset > 0)
+		num_segs += 1 + (remainder + offset - 1) / align;
+	return (num_segs);
+}
+
+static void
+nvme_free_child_bios(int num_bios, struct bio **child_bios)
+{
+	int i;
+
+	for (i = 0; i < num_bios; i++) {
+		if (child_bios[i] != NULL)
+			g_destroy_bio(child_bios[i]);
+	}
+
+	free(child_bios, M_NVME);
+}
+
+static struct bio **
+nvme_allocate_child_bios(int num_bios)
+{
+	struct bio **child_bios;
+	int err = 0, i;
+
+	child_bios = malloc(num_bios * sizeof(struct bio *), M_NVME, M_NOWAIT);
+	if (child_bios == NULL)
+		return (NULL);
+
+	for (i = 0; i < num_bios; i++) {
+		child_bios[i] = g_new_bio();
+		if (child_bios[i] == NULL)
+			err = ENOMEM;
+	}
+
+	if (err == ENOMEM) {
+		nvme_free_child_bios(num_bios, child_bios);
+		return (NULL);
+	}
+
+	return (child_bios);
+}
+
+static struct bio **
+nvme_construct_child_bios(struct bio *bp, uint32_t alignment, int *num_bios)
+{
+	struct bio	**child_bios;
+	struct bio	*child;
+	uint64_t	cur_offset;
+	caddr_t		data;
+	uint32_t	rem_bcount;
+	int		i;
+#ifdef NVME_UNMAPPED_BIO_SUPPORT
+	struct vm_page	**ma;
+	uint32_t	ma_offset;
+#endif
+
+	*num_bios = nvme_get_num_segments(bp->bio_offset, bp->bio_bcount,
+	    alignment);
+	child_bios = nvme_allocate_child_bios(*num_bios);
+	if (child_bios == NULL)
+		return (NULL);
+
+	bp->bio_children = *num_bios;
+	bp->bio_inbed = 0;
+	cur_offset = bp->bio_offset;
+	rem_bcount = bp->bio_bcount;
+	data = bp->bio_data;
+#ifdef NVME_UNMAPPED_BIO_SUPPORT
+	ma_offset = bp->bio_ma_offset;
+	ma = bp->bio_ma;
+#endif
+
+	for (i = 0; i < *num_bios; i++) {
+		child = child_bios[i];
+		child->bio_parent = bp;
+		child->bio_cmd = bp->bio_cmd;
+		child->bio_offset = cur_offset;
+		child->bio_bcount = min(rem_bcount,
+		    alignment - (cur_offset & (alignment - 1)));
+		child->bio_flags = bp->bio_flags;
+#ifdef NVME_UNMAPPED_BIO_SUPPORT
+		if (bp->bio_flags & BIO_UNMAPPED) {
+			child->bio_ma_offset = ma_offset;
+			child->bio_ma = ma;
+			child->bio_ma_n =
+			    nvme_get_num_segments(child->bio_ma_offset,
+				child->bio_bcount, PAGE_SIZE);
+			ma_offset = (ma_offset + child->bio_bcount) &
+			    PAGE_MASK;
+			ma += child->bio_ma_n;
+			if (ma_offset != 0)
+				ma -= 1;
+		} else
+#endif
+		{
+			child->bio_data = data;
+			data += child->bio_bcount;
+		}
+		cur_offset += child->bio_bcount;
+		rem_bcount -= child->bio_bcount;
+	}
+
+	return (child_bios);
+}
+
+static int
+nvme_ns_split_bio(struct nvme_namespace *ns, struct bio *bp,
+    uint32_t alignment)
+{
+	struct bio	*child;
+	struct bio	**child_bios;
+	int		err, i, num_bios;
+
+	child_bios = nvme_construct_child_bios(bp, alignment, &num_bios);
+	if (child_bios == NULL)
+		return (ENOMEM);
+
+	for (i = 0; i < num_bios; i++) {
+		child = child_bios[i];
+		err = nvme_ns_bio_process(ns, child, nvme_bio_child_done);
+		if (err != 0) {
+			nvme_bio_child_inbed(bp, err);
+			g_destroy_bio(child);
+		}
+	}
+
+	free(child_bios, M_NVME);
+	return (0);
+}
+
 int
 nvme_ns_bio_process(struct nvme_namespace *ns, struct bio *bp,
 	nvme_cb_fn_t cb_fn)
 {
 	struct nvme_dsm_range	*dsm_range;
+	uint32_t		num_bios;
 	int			err;
 
 	bp->bio_driver1 = cb_fn;
 
+	if (ns->stripesize > 0 &&
+	    (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE)) {
+		num_bios = nvme_get_num_segments(bp->bio_offset,
+		    bp->bio_bcount, ns->stripesize);
+		if (num_bios > 1)
+			return (nvme_ns_split_bio(ns, bp, ns->stripesize));
+	}
+
 	switch (bp->bio_cmd) {
 	case BIO_READ:
 		err = nvme_ns_cmd_read_bio(ns, bp, nvme_ns_bio_done, bp);
@@ -276,6 +494,11 @@ nvme_ns_construct(struct nvme_namespace 
 
 	ns->ctrlr = ctrlr;
 	ns->id = id;
+	ns->stripesize = 0;
+
+	if (pci_get_devid(ctrlr->dev) == 0x09538086 && ctrlr->cdata.vs[3] != 0)
+		ns->stripesize =
+		    (1 << ctrlr->cdata.vs[3]) * ctrlr->min_page_size;
 
 	/*
 	 * Namespaces are reconstructed after a controller reset, so check

Modified: projects/random_number_generator/sys/dev/nvme/nvme_private.h
==============================================================================
--- projects/random_number_generator/sys/dev/nvme/nvme_private.h	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/dev/nvme/nvme_private.h	Tue Oct  8 19:07:48 2013	(r256162)
@@ -238,6 +238,7 @@ struct nvme_namespace {
 	uint16_t			flags;
 	struct cdev			*cdev;
 	void				*cons_cookie[NVME_MAX_CONSUMERS];
+	uint32_t			stripesize;
 	struct mtx			lock;
 };
 
@@ -321,6 +322,9 @@ struct nvme_controller {
 
 	struct cdev			*cdev;
 
+	/** bit mask of warning types currently enabled for async events */
+	union nvme_critical_warning_state	async_event_config;
+
 	uint32_t			num_aers;
 	struct nvme_async_event_request	aer[NVME_MAX_ASYNC_EVENTS];
 

Modified: projects/random_number_generator/sys/dev/nvme/nvme_test.c
==============================================================================
--- projects/random_number_generator/sys/dev/nvme/nvme_test.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/dev/nvme/nvme_test.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -53,7 +53,7 @@ struct nvme_io_test_thread {
 	void			*buf;
 	uint32_t		size;
 	uint32_t		time;
-	uint32_t		io_completed;
+	uint64_t		io_completed;
 };
 
 struct nvme_io_test_internal {
@@ -66,7 +66,7 @@ struct nvme_io_test_internal {
 	uint32_t		td_active;
 	uint32_t		td_idx;
 	uint32_t		flags;
-	uint32_t		io_completed[NVME_TEST_MAX_THREADS];
+	uint64_t		io_completed[NVME_TEST_MAX_THREADS];
 };
 
 static void
@@ -90,8 +90,8 @@ nvme_ns_bio_test(void *arg)
 	struct cdev			*dev;
 	void				*buf;
 	struct timeval			t;
-	uint64_t			offset;
-	uint32_t			idx, io_completed = 0;
+	uint64_t			io_completed = 0, offset;
+	uint32_t			idx;
 #if __FreeBSD_version >= 900017
 	int				ref;
 #endif

Modified: projects/random_number_generator/sys/dev/random/ivy.c
==============================================================================
--- projects/random_number_generator/sys/dev/random/ivy.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/sys/dev/random/ivy.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -74,12 +74,12 @@ ivy_rng_store(uint64_t *tmp)
 
 	__asm __volatile(
 #ifdef __amd64__
-	    ".byte\t0x48,0x0f,0xc7,0xf0\n\t" /* rdrand %rax */
+	    "rdrand\t%%rax\n\t"
 	    "jnc\t1f\n\t"
 	    "movq\t%%rax,%1\n\t"
 	    "movl\t$8,%%eax\n"
 #else /* i386 */
-	    ".byte\t0x0f,0xc7,0xf0\n\t" /* rdrand %eax */
+	    "rdrand\t%%eax\n\t"
 	    "jnc\t1f\n\t"
 	    "movl\t%%eax,%1\n\t"
 	    "movl\t$4,%%eax\n"

Modified: projects/random_number_generator/usr.sbin/bhyve/bhyverun.c
==============================================================================
--- projects/random_number_generator/usr.sbin/bhyve/bhyverun.c	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/usr.sbin/bhyve/bhyverun.c	Tue Oct  8 19:07:48 2013	(r256162)
@@ -123,7 +123,7 @@ usage(int code)
 		" <vmname>\n"
 		"       -a: local apic is in XAPIC mode (default is X2APIC)\n"
 		"       -A: create an ACPI table\n"
-		"       -g: gdb port (default is %d and 0 means don't open)\n"
+		"       -g: gdb port\n"
 		"       -c: # cpus (default 1)\n"
 		"       -p: pin vcpu 'n' to host cpu 'pincpu + n'\n"
 		"       -H: vmexit from the guest on hlt\n"
@@ -134,7 +134,7 @@ usage(int code)
 		"       -s: <slot,driver,configinfo> PCI slot config\n"
 		"       -S: <slot,driver,configinfo> legacy PCI slot config\n"
 		"       -m: memory size in MB\n",
-		progname, DEFAULT_GDB_PORT);
+		progname);
 
 	exit(code);
 }
@@ -217,17 +217,6 @@ fbsdrun_addcpu(struct vmctx *ctx, int vc
 }
 
 static int
-fbsdrun_get_next_cpu(int curcpu)
-{
-
-	/*
-	 * Get the next available CPU. Assumes they arrive
-	 * in ascending order with no gaps.
-	 */
-	return ((curcpu + 1) % foundcpus);
-}
-
-static int
 vmexit_catch_reset(void)
 {
         stats.io_reset++;
@@ -504,7 +493,7 @@ main(int argc, char *argv[])
 
 	bvmcons = 0;
 	progname = basename(argv[0]);
-	gdb_port = DEFAULT_GDB_PORT;
+	gdb_port = 0;
 	guest_ncpus = 1;
 	ioapic = 0;
 	memsize = 256 * MB;

Modified: projects/random_number_generator/usr.sbin/bhyve/dbgport.h
==============================================================================
--- projects/random_number_generator/usr.sbin/bhyve/dbgport.h	Tue Oct  8 18:59:41 2013	(r256161)
+++ projects/random_number_generator/usr.sbin/bhyve/dbgport.h	Tue Oct  8 19:07:48 2013	(r256162)
@@ -29,8 +29,6 @@
 #ifndef _DBGPORT_H_
 #define	_DBGPORT_H_
 
-#define	DEFAULT_GDB_PORT	6466
-
 void	init_dbgport(int port);
 
 #endif



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