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/...
Mark Murray
markm at FreeBSD.org
Tue Oct 8 19:07:52 UTC 2013
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
More information about the svn-src-projects
mailing list