svn commit: r275356 - in projects/sendfile: bin/sh contrib/binutils/bfd contrib/gcc/config/arm contrib/ofed/management/infiniband-diags/src contrib/ofed/usr.bin sys/dev/virtio/block sys/kern sys/vm...
Gleb Smirnoff
glebius at FreeBSD.org
Mon Dec 1 11:28:09 UTC 2014
Author: glebius
Date: Mon Dec 1 11:28:05 2014
New Revision: 275356
URL: https://svnweb.freebsd.org/changeset/base/275356
Log:
Merge head r258543 through r275355.
Modified:
projects/sendfile/bin/sh/eval.c
projects/sendfile/bin/sh/output.c
projects/sendfile/contrib/binutils/bfd/elf32-arm.c
projects/sendfile/contrib/gcc/config/arm/lib1funcs.asm
projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibnetdiscover.c
projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibroute.c
projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibsendtrap.c
projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibtracert.c
projects/sendfile/contrib/ofed/management/infiniband-diags/src/saquery.c
projects/sendfile/contrib/ofed/management/infiniband-diags/src/smpquery.c
projects/sendfile/contrib/ofed/usr.bin/Makefile.inc
projects/sendfile/sys/dev/virtio/block/virtio_blk.c
projects/sendfile/sys/kern/subr_taskqueue.c
projects/sendfile/sys/vm/uma_core.c
projects/sendfile/tools/tools/shlib-compat/shlib-compat.py
projects/sendfile/tools/tools/shlib-compat/test/Makefile.inc
projects/sendfile/tools/tools/shlib-compat/test/regress.sh
projects/sendfile/tools/tools/sysbuild/sysbuild.sh
Directory Properties:
projects/sendfile/ (props changed)
projects/sendfile/contrib/binutils/ (props changed)
projects/sendfile/contrib/gcc/ (props changed)
projects/sendfile/sys/ (props changed)
Modified: projects/sendfile/bin/sh/eval.c
==============================================================================
--- projects/sendfile/bin/sh/eval.c Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/bin/sh/eval.c Mon Dec 1 11:28:05 2014 (r275356)
@@ -774,15 +774,7 @@ xtracecommand(struct arglist *varlist, s
for (sp = arglist->list ; sp ; sp = sp->next) {
if (sep != 0)
out2c(' ');
- /* Disambiguate command looking like assignment. */
- if (sp == arglist->list &&
- strchr(sp->text, '=') != NULL &&
- strchr(sp->text, '\'') == NULL) {
- out2c('\'');
- out2str(sp->text);
- out2c('\'');
- } else
- out2qstr(sp->text);
+ out2qstr(sp->text);
sep = ' ';
}
out2c('\n');
Modified: projects/sendfile/bin/sh/output.c
==============================================================================
--- projects/sendfile/bin/sh/output.c Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/bin/sh/output.c Mon Dec 1 11:28:05 2014 (r275356)
@@ -122,8 +122,7 @@ outqstr(const char *p, struct output *fi
outstr("''", file);
return;
}
- /* Caller will handle '=' if necessary */
- if (p[strcspn(p, "|&;<>()$`\\\"' \t\n*?[~#")] == '\0' ||
+ if (p[strcspn(p, "|&;<>()$`\\\"' \t\n*?[~#=")] == '\0' ||
strcmp(p, "[") == 0) {
outstr(p, file);
return;
Modified: projects/sendfile/contrib/binutils/bfd/elf32-arm.c
==============================================================================
--- projects/sendfile/contrib/binutils/bfd/elf32-arm.c Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/contrib/binutils/bfd/elf32-arm.c Mon Dec 1 11:28:05 2014 (r275356)
@@ -4960,7 +4960,7 @@ elf32_arm_final_link_relocate (reloc_how
+ input_section->output_offset
+ rel->r_offset);
- value = abs (relocation);
+ value = llabs (relocation);
if (value >= 0x1000)
return bfd_reloc_overflow;
@@ -4998,7 +4998,7 @@ elf32_arm_final_link_relocate (reloc_how
+ input_section->output_offset
+ rel->r_offset);
- value = abs (relocation);
+ value = llabs (relocation);
if (value >= 0x1000)
return bfd_reloc_overflow;
@@ -5984,7 +5984,7 @@ elf32_arm_final_link_relocate (reloc_how
/* Calculate the value of the relevant G_n, in encoded
constant-with-rotation format. */
- g_n = calculate_group_reloc_mask (abs (signed_value), group,
+ g_n = calculate_group_reloc_mask (llabs (signed_value), group,
&residual);
/* Check for overflow if required. */
@@ -5998,7 +5998,7 @@ elf32_arm_final_link_relocate (reloc_how
(*_bfd_error_handler)
(_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
input_bfd, input_section,
- (long) rel->r_offset, abs (signed_value), howto->name);
+ (long) rel->r_offset, llabs (signed_value), howto->name);
return bfd_reloc_overflow;
}
@@ -6077,7 +6077,7 @@ elf32_arm_final_link_relocate (reloc_how
/* Calculate the value of the relevant G_{n-1} to obtain
the residual at that stage. */
- calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
+ calculate_group_reloc_mask (llabs (signed_value), group - 1, &residual);
/* Check for overflow. */
if (residual >= 0x1000)
@@ -6085,7 +6085,7 @@ elf32_arm_final_link_relocate (reloc_how
(*_bfd_error_handler)
(_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
input_bfd, input_section,
- (long) rel->r_offset, abs (signed_value), howto->name);
+ (long) rel->r_offset, llabs (signed_value), howto->name);
return bfd_reloc_overflow;
}
@@ -6160,7 +6160,7 @@ elf32_arm_final_link_relocate (reloc_how
/* Calculate the value of the relevant G_{n-1} to obtain
the residual at that stage. */
- calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
+ calculate_group_reloc_mask (llabs (signed_value), group - 1, &residual);
/* Check for overflow. */
if (residual >= 0x100)
@@ -6168,7 +6168,7 @@ elf32_arm_final_link_relocate (reloc_how
(*_bfd_error_handler)
(_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
input_bfd, input_section,
- (long) rel->r_offset, abs (signed_value), howto->name);
+ (long) rel->r_offset, llabs (signed_value), howto->name);
return bfd_reloc_overflow;
}
@@ -6243,7 +6243,7 @@ elf32_arm_final_link_relocate (reloc_how
/* Calculate the value of the relevant G_{n-1} to obtain
the residual at that stage. */
- calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
+ calculate_group_reloc_mask (llabs (signed_value), group - 1, &residual);
/* Check for overflow. (The absolute value to go in the place must be
divisible by four and, after having been divided by four, must
@@ -6253,7 +6253,7 @@ elf32_arm_final_link_relocate (reloc_how
(*_bfd_error_handler)
(_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
input_bfd, input_section,
- (long) rel->r_offset, abs (signed_value), howto->name);
+ (long) rel->r_offset, llabs (signed_value), howto->name);
return bfd_reloc_overflow;
}
Modified: projects/sendfile/contrib/gcc/config/arm/lib1funcs.asm
==============================================================================
--- projects/sendfile/contrib/gcc/config/arm/lib1funcs.asm Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/contrib/gcc/config/arm/lib1funcs.asm Mon Dec 1 11:28:05 2014 (r275356)
@@ -980,8 +980,6 @@ LSYM(Lover12):
RET
- FUNC_END aeabi_ldiv0
- FUNC_END aeabi_idiv0
FUNC_END div0
#endif /* L_divmodsi_tools */
Modified: projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibnetdiscover.c
==============================================================================
--- projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibnetdiscover.c Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibnetdiscover.c Mon Dec 1 11:28:05 2014 (r275356)
@@ -50,7 +50,7 @@
#include <infiniband/common.h>
#include <infiniband/umad.h>
#include <infiniband/mad.h>
-#include <infiniband/complib/cl_nodenamemap.h>
+#include <complib/cl_nodenamemap.h>
#include "ibnetdiscover.h"
#include "grouping.h"
Modified: projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibroute.c
==============================================================================
--- projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibroute.c Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibroute.c Mon Dec 1 11:28:05 2014 (r275356)
@@ -49,7 +49,7 @@
#include <infiniband/common.h>
#include <infiniband/umad.h>
#include <infiniband/mad.h>
-#include <infiniband/complib/cl_nodenamemap.h>
+#include <complib/cl_nodenamemap.h>
#include "ibdiag_common.h"
Modified: projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibsendtrap.c
==============================================================================
--- projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibsendtrap.c Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibsendtrap.c Mon Dec 1 11:28:05 2014 (r275356)
@@ -43,7 +43,7 @@
#include <getopt.h>
#include <infiniband/mad.h>
-#include <infiniband/iba/ib_types.h>
+#include <iba/ib_types.h>
#include "ibdiag_common.h"
Modified: projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibtracert.c
==============================================================================
--- projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibtracert.c Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/contrib/ofed/management/infiniband-diags/src/ibtracert.c Mon Dec 1 11:28:05 2014 (r275356)
@@ -49,7 +49,7 @@
#include <infiniband/common.h>
#include <infiniband/umad.h>
#include <infiniband/mad.h>
-#include <infiniband/complib/cl_nodenamemap.h>
+#include <complib/cl_nodenamemap.h>
#include "ibdiag_common.h"
Modified: projects/sendfile/contrib/ofed/management/infiniband-diags/src/saquery.c
==============================================================================
--- projects/sendfile/contrib/ofed/management/infiniband-diags/src/saquery.c Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/contrib/ofed/management/infiniband-diags/src/saquery.c Mon Dec 1 11:28:05 2014 (r275356)
@@ -50,12 +50,12 @@
#include <getopt.h>
#include <infiniband/mad.h>
-#include <infiniband/opensm/osm_log.h>
-#include <infiniband/vendor/osm_vendor_api.h>
-#include <infiniband/vendor/osm_vendor_sa_api.h>
-#include <infiniband/opensm/osm_mad_pool.h>
-#include <infiniband/complib/cl_debug.h>
-#include <infiniband/complib/cl_nodenamemap.h>
+#include <opensm/osm_log.h>
+#include <vendor/osm_vendor_api.h>
+#include <vendor/osm_vendor_sa_api.h>
+#include <opensm/osm_mad_pool.h>
+#include <complib/cl_debug.h>
+#include <complib/cl_nodenamemap.h>
#include <netinet/in.h>
Modified: projects/sendfile/contrib/ofed/management/infiniband-diags/src/smpquery.c
==============================================================================
--- projects/sendfile/contrib/ofed/management/infiniband-diags/src/smpquery.c Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/contrib/ofed/management/infiniband-diags/src/smpquery.c Mon Dec 1 11:28:05 2014 (r275356)
@@ -50,7 +50,7 @@
#include <infiniband/common.h>
#include <infiniband/umad.h>
#include <infiniband/mad.h>
-#include <infiniband/complib/cl_nodenamemap.h>
+#include <complib/cl_nodenamemap.h>
#include "ibdiag_common.h"
Modified: projects/sendfile/contrib/ofed/usr.bin/Makefile.inc
==============================================================================
--- projects/sendfile/contrib/ofed/usr.bin/Makefile.inc Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/contrib/ofed/usr.bin/Makefile.inc Mon Dec 1 11:28:05 2014 (r275356)
@@ -1,4 +1,9 @@
DIAGPATH= ${.CURDIR}/../../management/infiniband-diags
BINDIR?= /usr/bin
CFLAGS+= -I${.CURDIR}/../../include/infiniband
+CFLAGS+= -I${.CURDIR}/../../include
CFLAGS+= -I${.CURDIR}/../../management/opensm/include/
+CFLAGS+= -I${.CURDIR}/../../management/opensm
+CFLAGS+= -I${.CURDIR}/../../management/libibcommon/include
+CFLAGS+= -I${.CURDIR}/../../management/libibumad/include
+CFLAGS+= -I${.CURDIR}/../../management/libibmad/include
Modified: projects/sendfile/sys/dev/virtio/block/virtio_blk.c
==============================================================================
--- projects/sendfile/sys/dev/virtio/block/virtio_blk.c Mon Dec 1 10:17:23 2014 (r275355)
+++ projects/sendfile/sys/dev/virtio/block/virtio_blk.c Mon Dec 1 11:28:05 2014 (r275356)
@@ -58,7 +58,6 @@ struct vtblk_request {
struct virtio_blk_outhdr vbr_hdr;
struct bio *vbr_bp;
uint8_t vbr_ack;
-
TAILQ_ENTRY(vtblk_request) vbr_link;
};
@@ -132,53 +131,60 @@ static int vtblk_dump(void *, void *, vm
static void vtblk_strategy(struct bio *);
static void vtblk_negotiate_features(struct vtblk_softc *);
+static void vtblk_setup_features(struct vtblk_softc *);
static int vtblk_maximum_segments(struct vtblk_softc *,
struct virtio_blk_config *);
static int vtblk_alloc_virtqueue(struct vtblk_softc *);
static void vtblk_resize_disk(struct vtblk_softc *, uint64_t);
-static void vtblk_set_write_cache(struct vtblk_softc *, int);
-static int vtblk_write_cache_enabled(struct vtblk_softc *sc,
- struct virtio_blk_config *);
-static int vtblk_write_cache_sysctl(SYSCTL_HANDLER_ARGS);
static void vtblk_alloc_disk(struct vtblk_softc *,
struct virtio_blk_config *);
static void vtblk_create_disk(struct vtblk_softc *);
-static int vtblk_quiesce(struct vtblk_softc *);
-static void vtblk_startio(struct vtblk_softc *);
-static struct vtblk_request * vtblk_bio_request(struct vtblk_softc *);
-static int vtblk_execute_request(struct vtblk_softc *,
+static int vtblk_request_prealloc(struct vtblk_softc *);
+static void vtblk_request_free(struct vtblk_softc *);
+static struct vtblk_request *
+ vtblk_request_dequeue(struct vtblk_softc *);
+static void vtblk_request_enqueue(struct vtblk_softc *,
struct vtblk_request *);
+static struct vtblk_request *
+ vtblk_request_next_ready(struct vtblk_softc *);
+static void vtblk_request_requeue_ready(struct vtblk_softc *,
+ struct vtblk_request *);
+static struct vtblk_request *
+ vtblk_request_next(struct vtblk_softc *);
+static struct vtblk_request *
+ vtblk_request_bio(struct vtblk_softc *);
+static int vtblk_request_execute(struct vtblk_softc *,
+ struct vtblk_request *);
+static int vtblk_request_error(struct vtblk_request *);
-static void vtblk_vq_intr(void *);
+static void vtblk_queue_completed(struct vtblk_softc *,
+ struct bio_queue *);
+static void vtblk_done_completed(struct vtblk_softc *,
+ struct bio_queue *);
+static void vtblk_drain_vq(struct vtblk_softc *, int);
+static void vtblk_drain(struct vtblk_softc *);
-static void vtblk_stop(struct vtblk_softc *);
+static void vtblk_startio(struct vtblk_softc *);
+static void vtblk_bio_done(struct vtblk_softc *, struct bio *, int);
static void vtblk_read_config(struct vtblk_softc *,
struct virtio_blk_config *);
-static void vtblk_get_ident(struct vtblk_softc *);
-static void vtblk_prepare_dump(struct vtblk_softc *);
-static int vtblk_write_dump(struct vtblk_softc *, void *, off_t, size_t);
-static int vtblk_flush_dump(struct vtblk_softc *);
+static void vtblk_ident(struct vtblk_softc *);
static int vtblk_poll_request(struct vtblk_softc *,
struct vtblk_request *);
+static int vtblk_quiesce(struct vtblk_softc *);
+static void vtblk_vq_intr(void *);
+static void vtblk_stop(struct vtblk_softc *);
-static void vtblk_finish_completed(struct vtblk_softc *);
-static void vtblk_drain_vq(struct vtblk_softc *, int);
-static void vtblk_drain(struct vtblk_softc *);
-
-static int vtblk_alloc_requests(struct vtblk_softc *);
-static void vtblk_free_requests(struct vtblk_softc *);
-static struct vtblk_request * vtblk_dequeue_request(struct vtblk_softc *);
-static void vtblk_enqueue_request(struct vtblk_softc *,
- struct vtblk_request *);
-
-static struct vtblk_request * vtblk_dequeue_ready(struct vtblk_softc *);
-static void vtblk_enqueue_ready(struct vtblk_softc *,
- struct vtblk_request *);
+static void vtblk_dump_prepare(struct vtblk_softc *);
+static int vtblk_dump_write(struct vtblk_softc *, void *, off_t, size_t);
+static int vtblk_dump_flush(struct vtblk_softc *);
-static int vtblk_request_error(struct vtblk_request *);
-static void vtblk_finish_bio(struct bio *, int);
+static void vtblk_set_write_cache(struct vtblk_softc *, int);
+static int vtblk_write_cache_enabled(struct vtblk_softc *sc,
+ struct virtio_blk_config *);
+static int vtblk_write_cache_sysctl(SYSCTL_HANDLER_ARGS);
static void vtblk_setup_sysctl(struct vtblk_softc *);
static int vtblk_tunable_int(struct vtblk_softc *, const char *, int);
@@ -290,30 +296,18 @@ vtblk_attach(device_t dev)
struct virtio_blk_config blkcfg;
int error;
+ virtio_set_feature_desc(dev, vtblk_feature_desc);
+
sc = device_get_softc(dev);
sc->vtblk_dev = dev;
-
VTBLK_LOCK_INIT(sc, device_get_nameunit(dev));
-
bioq_init(&sc->vtblk_bioq);
TAILQ_INIT(&sc->vtblk_req_free);
TAILQ_INIT(&sc->vtblk_req_ready);
- virtio_set_feature_desc(dev, vtblk_feature_desc);
- vtblk_negotiate_features(sc);
-
- if (virtio_with_feature(dev, VIRTIO_RING_F_INDIRECT_DESC))
- sc->vtblk_flags |= VTBLK_FLAG_INDIRECT;
- if (virtio_with_feature(dev, VIRTIO_BLK_F_RO))
- sc->vtblk_flags |= VTBLK_FLAG_READONLY;
- if (virtio_with_feature(dev, VIRTIO_BLK_F_BARRIER))
- sc->vtblk_flags |= VTBLK_FLAG_BARRIER;
- if (virtio_with_feature(dev, VIRTIO_BLK_F_CONFIG_WCE))
- sc->vtblk_flags |= VTBLK_FLAG_WC_CONFIG;
-
vtblk_setup_sysctl(sc);
+ vtblk_setup_features(sc);
- /* Get local copy of config. */
vtblk_read_config(sc, &blkcfg);
/*
@@ -352,7 +346,7 @@ vtblk_attach(device_t dev)
goto fail;
}
- error = vtblk_alloc_requests(sc);
+ error = vtblk_request_prealloc(sc);
if (error) {
device_printf(dev, "cannot preallocate requests\n");
goto fail;
@@ -519,14 +513,14 @@ vtblk_dump(void *arg, void *virtual, vm_
VTBLK_LOCK(sc);
if ((sc->vtblk_flags & VTBLK_FLAG_DUMPING) == 0) {
- vtblk_prepare_dump(sc);
+ vtblk_dump_prepare(sc);
sc->vtblk_flags |= VTBLK_FLAG_DUMPING;
}
if (length > 0)
- error = vtblk_write_dump(sc, virtual, offset, length);
+ error = vtblk_dump_write(sc, virtual, offset, length);
else if (virtual == NULL && offset == 0)
- error = vtblk_flush_dump(sc);
+ error = vtblk_dump_flush(sc);
else {
error = EINVAL;
sc->vtblk_flags &= ~VTBLK_FLAG_DUMPING;
@@ -543,7 +537,7 @@ vtblk_strategy(struct bio *bp)
struct vtblk_softc *sc;
if ((sc = bp->bio_disk->d_drv1) == NULL) {
- vtblk_finish_bio(bp, EINVAL);
+ vtblk_bio_done(NULL, bp, EINVAL);
return;
}
@@ -553,37 +547,21 @@ vtblk_strategy(struct bio *bp)
*/
if (sc->vtblk_flags & VTBLK_FLAG_READONLY &&
(bp->bio_cmd == BIO_WRITE || bp->bio_cmd == BIO_FLUSH)) {
- vtblk_finish_bio(bp, EROFS);
+ vtblk_bio_done(sc, bp, EROFS);
return;
}
-#ifdef INVARIANTS
- /*
- * Prevent read/write buffers spanning too many segments from
- * getting into the queue. This should only trip if d_maxsize
- * was incorrectly set.
- */
- if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) {
- int nsegs, max_nsegs;
-
- nsegs = sglist_count(bp->bio_data, bp->bio_bcount);
- max_nsegs = sc->vtblk_max_nsegs - VTBLK_MIN_SEGMENTS;
+ VTBLK_LOCK(sc);
- KASSERT(nsegs <= max_nsegs,
- ("%s: bio %p spanned too many segments: %d, max: %d",
- __func__, bp, nsegs, max_nsegs));
+ if (sc->vtblk_flags & VTBLK_FLAG_DETACH) {
+ VTBLK_UNLOCK(sc);
+ vtblk_bio_done(sc, bp, ENXIO);
+ return;
}
-#endif
- VTBLK_LOCK(sc);
- if (sc->vtblk_flags & VTBLK_FLAG_DETACH)
- vtblk_finish_bio(bp, ENXIO);
- else {
- bioq_insert_tail(&sc->vtblk_bioq, bp);
+ bioq_insert_tail(&sc->vtblk_bioq, bp);
+ vtblk_startio(sc);
- if ((sc->vtblk_flags & VTBLK_FLAG_SUSPEND) == 0)
- vtblk_startio(sc);
- }
VTBLK_UNLOCK(sc);
}
@@ -599,6 +577,25 @@ vtblk_negotiate_features(struct vtblk_so
sc->vtblk_features = virtio_negotiate_features(dev, features);
}
+static void
+vtblk_setup_features(struct vtblk_softc *sc)
+{
+ device_t dev;
+
+ dev = sc->vtblk_dev;
+
+ vtblk_negotiate_features(sc);
+
+ if (virtio_with_feature(dev, VIRTIO_RING_F_INDIRECT_DESC))
+ sc->vtblk_flags |= VTBLK_FLAG_INDIRECT;
+ if (virtio_with_feature(dev, VIRTIO_BLK_F_RO))
+ sc->vtblk_flags |= VTBLK_FLAG_READONLY;
+ if (virtio_with_feature(dev, VIRTIO_BLK_F_BARRIER))
+ sc->vtblk_flags |= VTBLK_FLAG_BARRIER;
+ if (virtio_with_feature(dev, VIRTIO_BLK_F_CONFIG_WCE))
+ sc->vtblk_flags |= VTBLK_FLAG_WC_CONFIG;
+}
+
static int
vtblk_maximum_segments(struct vtblk_softc *sc,
struct virtio_blk_config *blkcfg)
@@ -660,59 +657,6 @@ vtblk_resize_disk(struct vtblk_softc *sc
}
static void
-vtblk_set_write_cache(struct vtblk_softc *sc, int wc)
-{
-
- /* Set either writeback (1) or writethrough (0) mode. */
- virtio_write_dev_config_1(sc->vtblk_dev,
- offsetof(struct virtio_blk_config, writeback), wc);
-}
-
-static int
-vtblk_write_cache_enabled(struct vtblk_softc *sc,
- struct virtio_blk_config *blkcfg)
-{
- int wc;
-
- if (sc->vtblk_flags & VTBLK_FLAG_WC_CONFIG) {
- wc = vtblk_tunable_int(sc, "writecache_mode",
- vtblk_writecache_mode);
- if (wc >= 0 && wc < VTBLK_CACHE_MAX)
- vtblk_set_write_cache(sc, wc);
- else
- wc = blkcfg->writeback;
- } else
- wc = virtio_with_feature(sc->vtblk_dev, VIRTIO_BLK_F_WCE);
-
- return (wc);
-}
-
-static int
-vtblk_write_cache_sysctl(SYSCTL_HANDLER_ARGS)
-{
- struct vtblk_softc *sc;
- int wc, error;
-
- sc = oidp->oid_arg1;
- wc = sc->vtblk_write_cache;
-
- error = sysctl_handle_int(oidp, &wc, 0, req);
- if (error || req->newptr == NULL)
- return (error);
- if ((sc->vtblk_flags & VTBLK_FLAG_WC_CONFIG) == 0)
- return (EPERM);
- if (wc < 0 || wc >= VTBLK_CACHE_MAX)
- return (EINVAL);
-
- VTBLK_LOCK(sc);
- sc->vtblk_write_cache = wc;
- vtblk_set_write_cache(sc, sc->vtblk_write_cache);
- VTBLK_UNLOCK(sc);
-
- return (0);
-}
-
-static void
vtblk_alloc_disk(struct vtblk_softc *sc, struct virtio_blk_config *blkcfg)
{
device_t dev;
@@ -728,7 +672,8 @@ vtblk_alloc_disk(struct vtblk_softc *sc,
dp->d_name = VTBLK_DISK_NAME;
dp->d_unit = device_get_unit(dev);
dp->d_drv1 = sc;
- dp->d_flags = DISKFLAG_CANFLUSHCACHE | DISKFLAG_UNMAPPED_BIO;
+ dp->d_flags = DISKFLAG_CANFLUSHCACHE | DISKFLAG_UNMAPPED_BIO |
+ DISKFLAG_DIRECT_COMPLETION;
dp->d_hba_vendor = virtio_get_vendor(dev);
dp->d_hba_device = virtio_get_device(dev);
dp->d_hba_subvendor = virtio_get_subvendor(dev);
@@ -789,11 +734,7 @@ vtblk_create_disk(struct vtblk_softc *sc
dp = sc->vtblk_disk;
- /*
- * Retrieving the identification string must be done after
- * the virtqueue interrupt is setup otherwise it will hang.
- */
- vtblk_get_ident(sc);
+ vtblk_ident(sc);
device_printf(sc->vtblk_dev, "%juMB (%ju %u byte sectors)\n",
(uintmax_t) dp->d_mediasize >> 20,
@@ -804,57 +745,107 @@ vtblk_create_disk(struct vtblk_softc *sc
}
static int
-vtblk_quiesce(struct vtblk_softc *sc)
+vtblk_request_prealloc(struct vtblk_softc *sc)
{
- int error;
+ struct vtblk_request *req;
+ int i, nreqs;
- error = 0;
+ nreqs = virtqueue_size(sc->vtblk_vq);
- VTBLK_LOCK_ASSERT(sc);
+ /*
+ * Preallocate sufficient requests to keep the virtqueue full. Each
+ * request consumes VTBLK_MIN_SEGMENTS or more descriptors so reduce
+ * the number allocated when indirect descriptors are not available.
+ */
+ if ((sc->vtblk_flags & VTBLK_FLAG_INDIRECT) == 0)
+ nreqs /= VTBLK_MIN_SEGMENTS;
- while (!virtqueue_empty(sc->vtblk_vq)) {
- if (mtx_sleep(&sc->vtblk_vq, VTBLK_MTX(sc), PRIBIO, "vtblkq",
- VTBLK_QUIESCE_TIMEOUT) == EWOULDBLOCK) {
- error = EBUSY;
- break;
- }
+ for (i = 0; i < nreqs; i++) {
+ req = malloc(sizeof(struct vtblk_request), M_DEVBUF, M_NOWAIT);
+ if (req == NULL)
+ return (ENOMEM);
+
+ MPASS(sglist_count(&req->vbr_hdr, sizeof(req->vbr_hdr)) == 1);
+ MPASS(sglist_count(&req->vbr_ack, sizeof(req->vbr_ack)) == 1);
+
+ sc->vtblk_request_count++;
+ vtblk_request_enqueue(sc, req);
}
- return (error);
+ return (0);
}
static void
-vtblk_startio(struct vtblk_softc *sc)
+vtblk_request_free(struct vtblk_softc *sc)
{
- struct virtqueue *vq;
struct vtblk_request *req;
- int enq;
- vq = sc->vtblk_vq;
- enq = 0;
+ MPASS(TAILQ_EMPTY(&sc->vtblk_req_ready));
- VTBLK_LOCK_ASSERT(sc);
+ while ((req = vtblk_request_dequeue(sc)) != NULL) {
+ sc->vtblk_request_count--;
+ free(req, M_DEVBUF);
+ }
- while (!virtqueue_full(vq)) {
- if ((req = vtblk_dequeue_ready(sc)) == NULL)
- req = vtblk_bio_request(sc);
- if (req == NULL)
- break;
+ KASSERT(sc->vtblk_request_count == 0,
+ ("%s: leaked %d requests", __func__, sc->vtblk_request_count));
+}
- if (vtblk_execute_request(sc, req) != 0) {
- vtblk_enqueue_ready(sc, req);
- break;
- }
+static struct vtblk_request *
+vtblk_request_dequeue(struct vtblk_softc *sc)
+{
+ struct vtblk_request *req;
- enq++;
+ req = TAILQ_FIRST(&sc->vtblk_req_free);
+ if (req != NULL) {
+ TAILQ_REMOVE(&sc->vtblk_req_free, req, vbr_link);
+ bzero(req, sizeof(struct vtblk_request));
}
- if (enq > 0)
- virtqueue_notify(vq);
+ return (req);
+}
+
+static void
+vtblk_request_enqueue(struct vtblk_softc *sc, struct vtblk_request *req)
+{
+
+ TAILQ_INSERT_HEAD(&sc->vtblk_req_free, req, vbr_link);
+}
+
+static struct vtblk_request *
+vtblk_request_next_ready(struct vtblk_softc *sc)
+{
+ struct vtblk_request *req;
+
+ req = TAILQ_FIRST(&sc->vtblk_req_ready);
+ if (req != NULL)
+ TAILQ_REMOVE(&sc->vtblk_req_ready, req, vbr_link);
+
+ return (req);
+}
+
+static void
+vtblk_request_requeue_ready(struct vtblk_softc *sc, struct vtblk_request *req)
+{
+
+ /* NOTE: Currently, there will be at most one request in the queue. */
+ TAILQ_INSERT_HEAD(&sc->vtblk_req_ready, req, vbr_link);
+}
+
+static struct vtblk_request *
+vtblk_request_next(struct vtblk_softc *sc)
+{
+ struct vtblk_request *req;
+
+ req = vtblk_request_next_ready(sc);
+ if (req != NULL)
+ return (req);
+
+ return (vtblk_request_bio(sc));
}
static struct vtblk_request *
-vtblk_bio_request(struct vtblk_softc *sc)
+vtblk_request_bio(struct vtblk_softc *sc)
{
struct bio_queue_head *bioq;
struct vtblk_request *req;
@@ -865,7 +856,7 @@ vtblk_bio_request(struct vtblk_softc *sc
if (bioq_first(bioq) == NULL)
return (NULL);
- req = vtblk_dequeue_request(sc);
+ req = vtblk_request_dequeue(sc);
if (req == NULL)
return (NULL);
@@ -890,11 +881,14 @@ vtblk_bio_request(struct vtblk_softc *sc
panic("%s: bio with unhandled cmd: %d", __func__, bp->bio_cmd);
}
+ if (bp->bio_flags & BIO_ORDERED)
+ req->vbr_hdr.type |= VIRTIO_BLK_T_BARRIER;
+
return (req);
}
static int
-vtblk_execute_request(struct vtblk_softc *sc, struct vtblk_request *req)
+vtblk_request_execute(struct vtblk_softc *sc, struct vtblk_request *req)
{
struct virtqueue *vq;
struct sglist *sg;
@@ -907,26 +901,20 @@ vtblk_execute_request(struct vtblk_softc
ordered = 0;
writable = 0;
- VTBLK_LOCK_ASSERT(sc);
-
/*
- * Wait until the ordered request completes before
- * executing subsequent requests.
+ * Some hosts (such as bhyve) do not implement the barrier feature,
+ * so we emulate it in the driver by allowing the barrier request
+ * to be the only one in flight.
*/
- if (sc->vtblk_req_ordered != NULL)
- return (EBUSY);
-
- if (bp->bio_flags & BIO_ORDERED) {
- if ((sc->vtblk_flags & VTBLK_FLAG_BARRIER) == 0) {
- /*
- * This request will be executed once all
- * the in-flight requests are completed.
- */
+ if ((sc->vtblk_flags & VTBLK_FLAG_BARRIER) == 0) {
+ if (sc->vtblk_req_ordered != NULL)
+ return (EBUSY);
+ if (bp->bio_flags & BIO_ORDERED) {
if (!virtqueue_empty(vq))
return (EBUSY);
ordered = 1;
- } else
- req->vbr_hdr.type |= VIRTIO_BLK_T_BARRIER;
+ req->vbr_hdr.type &= ~VIRTIO_BLK_T_BARRIER;
+ }
}
sglist_reset(sg);
@@ -935,7 +923,7 @@ vtblk_execute_request(struct vtblk_softc
if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) {
error = sglist_append_bio(sg, bp);
if (error || sg->sg_nseg == sg->sg_maxseg) {
- panic("%s: data buffer too big bio:%p error:%d",
+ panic("%s: bio %p data buffer too big %d",
__func__, bp, error);
}
@@ -955,44 +943,156 @@ vtblk_execute_request(struct vtblk_softc
return (error);
}
-static void
-vtblk_vq_intr(void *xsc)
+static int
+vtblk_request_error(struct vtblk_request *req)
{
- struct vtblk_softc *sc;
- struct virtqueue *vq;
-
- sc = xsc;
- vq = sc->vtblk_vq;
+ int error;
-again:
- VTBLK_LOCK(sc);
- if (sc->vtblk_flags & VTBLK_FLAG_DETACH) {
- VTBLK_UNLOCK(sc);
- return;
+ switch (req->vbr_ack) {
+ case VIRTIO_BLK_S_OK:
+ error = 0;
+ break;
+ case VIRTIO_BLK_S_UNSUPP:
+ error = ENOTSUP;
+ break;
+ default:
+ error = EIO;
+ break;
}
- vtblk_finish_completed(sc);
+ return (error);
+}
- if ((sc->vtblk_flags & VTBLK_FLAG_SUSPEND) == 0)
- vtblk_startio(sc);
- else
- wakeup(&sc->vtblk_vq);
+static void
+vtblk_queue_completed(struct vtblk_softc *sc, struct bio_queue *queue)
+{
+ struct vtblk_request *req;
+ struct bio *bp;
- if (virtqueue_enable_intr(vq) != 0) {
- virtqueue_disable_intr(vq);
- VTBLK_UNLOCK(sc);
- goto again;
+ while ((req = virtqueue_dequeue(sc->vtblk_vq, NULL)) != NULL) {
+ if (sc->vtblk_req_ordered != NULL) {
+ MPASS(sc->vtblk_req_ordered == req);
+ sc->vtblk_req_ordered = NULL;
+ }
+
+ bp = req->vbr_bp;
+ bp->bio_error = vtblk_request_error(req);
+ TAILQ_INSERT_TAIL(queue, bp, bio_queue);
+
+ vtblk_request_enqueue(sc, req);
}
+}
- VTBLK_UNLOCK(sc);
+static void
+vtblk_done_completed(struct vtblk_softc *sc, struct bio_queue *queue)
+{
+ struct bio *bp, *tmp;
+
+ TAILQ_FOREACH_SAFE(bp, queue, bio_queue, tmp) {
+ if (bp->bio_error != 0)
+ disk_err(bp, "hard error", -1, 1);
+ vtblk_bio_done(sc, bp, bp->bio_error);
+ }
}
static void
-vtblk_stop(struct vtblk_softc *sc)
+vtblk_drain_vq(struct vtblk_softc *sc, int skip_done)
{
+ struct virtqueue *vq;
+ struct vtblk_request *req;
+ int last;
- virtqueue_disable_intr(sc->vtblk_vq);
- virtio_stop(sc->vtblk_dev);
+ vq = sc->vtblk_vq;
+ last = 0;
+
+ while ((req = virtqueue_drain(vq, &last)) != NULL) {
+ if (!skip_done)
+ vtblk_bio_done(sc, req->vbr_bp, ENXIO);
+
+ vtblk_request_enqueue(sc, req);
+ }
+
+ sc->vtblk_req_ordered = NULL;
+ KASSERT(virtqueue_empty(vq), ("virtqueue not empty"));
+}
+
+static void
+vtblk_drain(struct vtblk_softc *sc)
+{
+ struct bio_queue queue;
+ struct bio_queue_head *bioq;
+ struct vtblk_request *req;
+ struct bio *bp;
+
+ bioq = &sc->vtblk_bioq;
+ TAILQ_INIT(&queue);
+
+ if (sc->vtblk_vq != NULL) {
+ vtblk_queue_completed(sc, &queue);
+ vtblk_done_completed(sc, &queue);
+
+ vtblk_drain_vq(sc, 0);
+ }
+
+ while ((req = vtblk_request_next_ready(sc)) != NULL) {
+ vtblk_bio_done(sc, req->vbr_bp, ENXIO);
+ vtblk_request_enqueue(sc, req);
+ }
+
+ while (bioq_first(bioq) != NULL) {
+ bp = bioq_takefirst(bioq);
+ vtblk_bio_done(sc, bp, ENXIO);
+ }
+
+ vtblk_request_free(sc);
+}
+
+static void
+vtblk_startio(struct vtblk_softc *sc)
+{
+ struct virtqueue *vq;
+ struct vtblk_request *req;
+ int enq;
+
+ VTBLK_LOCK_ASSERT(sc);
+ vq = sc->vtblk_vq;
+ enq = 0;
+
+ if (sc->vtblk_flags & VTBLK_FLAG_SUSPEND)
+ return;
+
+ while (!virtqueue_full(vq)) {
+ req = vtblk_request_next(sc);
+ if (req == NULL)
+ break;
+
+ if (vtblk_request_execute(sc, req) != 0) {
+ vtblk_request_requeue_ready(sc, req);
+ break;
+ }
+
+ enq++;
+ }
+
+ if (enq > 0)
+ virtqueue_notify(vq);
+}
+
+static void
+vtblk_bio_done(struct vtblk_softc *sc, struct bio *bp, int error)
+{
+
+ /* Because of GEOM direct dispatch, we cannot hold any locks. */
+ if (sc != NULL)
+ VTBLK_LOCK_ASSERT_NOTOWNED(sc);
+
+ if (error) {
+ bp->bio_resid = bp->bio_bcount;
+ bp->bio_error = error;
+ bp->bio_flags |= BIO_ERROR;
+ }
+
+ biodone(bp);
}
#define VTBLK_GET_CONFIG(_dev, _feature, _field, _cfg) \
@@ -1027,7 +1127,7 @@ vtblk_read_config(struct vtblk_softc *sc
#undef VTBLK_GET_CONFIG
static void
-vtblk_get_ident(struct vtblk_softc *sc)
+vtblk_ident(struct vtblk_softc *sc)
{
struct bio buf;
struct disk *dp;
@@ -1040,7 +1140,7 @@ vtblk_get_ident(struct vtblk_softc *sc)
if (vtblk_tunable_int(sc, "no_ident", vtblk_no_ident) != 0)
return;
- req = vtblk_dequeue_request(sc);
+ req = vtblk_request_dequeue(sc);
if (req == NULL)
return;
@@ -1060,7 +1160,7 @@ vtblk_get_ident(struct vtblk_softc *sc)
error = vtblk_poll_request(sc, req);
VTBLK_UNLOCK(sc);
- vtblk_enqueue_request(sc, req);
+ vtblk_request_enqueue(sc, req);
if (error) {
device_printf(sc->vtblk_dev,
@@ -1068,77 +1168,6 @@ vtblk_get_ident(struct vtblk_softc *sc)
}
}
-static void
-vtblk_prepare_dump(struct vtblk_softc *sc)
-{
- device_t dev;
- struct virtqueue *vq;
-
- dev = sc->vtblk_dev;
- vq = sc->vtblk_vq;
-
- vtblk_stop(sc);
-
- /*
- * Drain all requests caught in-flight in the virtqueue,
- * skipping biodone(). When dumping, only one request is
- * outstanding at a time, and we just poll the virtqueue
- * for the response.
- */
- vtblk_drain_vq(sc, 1);
-
- if (virtio_reinit(dev, sc->vtblk_features) != 0) {
- panic("%s: cannot reinit VirtIO block device during dump",
- device_get_nameunit(dev));
- }
-
- virtqueue_disable_intr(vq);
- virtio_reinit_complete(dev);
-}
-
-static int
-vtblk_write_dump(struct vtblk_softc *sc, void *virtual, off_t offset,
- size_t length)
-{
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list