Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Jan 2021 05:08:03 GMT
From:      Bryan Venteicher <bryanv@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 703f17d60f7f - main - virtio_pci: Add sysctl to show current features
Message-ID:  <202101190508.10J583pG085599@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by bryanv:

URL: https://cgit.FreeBSD.org/src/commit/?id=703f17d60f7fd2885b5041eec6734804dae49de7

commit 703f17d60f7fd2885b5041eec6734804dae49de7
Author:     Bryan Venteicher <bryanv@FreeBSD.org>
AuthorDate: 2021-01-19 04:55:23 +0000
Commit:     Bryan Venteicher <bryanv@FreeBSD.org>
CommitDate: 2021-01-19 04:55:23 +0000

    virtio_pci: Add sysctl to show current features
    
    Reviewed by: grehan (mentor)
    Differential Revision: https://reviews.freebsd.org/D27898
---
 sys/dev/virtio/pci/virtio_pci.c | 71 ++++++++++++++++++++++++++++++++++++++++-
 sys/dev/virtio/pci/virtio_pci.h |  1 +
 sys/dev/virtio/virtio.c         | 57 +++++++++++++++++++++------------
 sys/dev/virtio/virtio.h         |  5 ++-
 4 files changed, 112 insertions(+), 22 deletions(-)

diff --git a/sys/dev/virtio/pci/virtio_pci.c b/sys/dev/virtio/pci/virtio_pci.c
index 4d6fa929ef19..1a60196b5d02 100644
--- a/sys/dev/virtio/pci/virtio_pci.c
+++ b/sys/dev/virtio/pci/virtio_pci.c
@@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
+#include <sys/sbuf.h>
+#include <sys/sysctl.h>
 #include <sys/module.h>
 #include <sys/malloc.h>
 
@@ -85,6 +87,8 @@ static int	vtpci_vq_intr_filter(void *);
 static void	vtpci_vq_intr(void *);
 static void	vtpci_config_intr(void *);
 
+static void	vtpci_setup_sysctl(struct vtpci_common *);
+
 #define vtpci_setup_msi_interrupt vtpci_setup_intx_interrupt
 
 /*
@@ -156,6 +160,8 @@ vtpci_init(struct vtpci_common *cn, device_t dev, bool modern)
 		cn->vtpci_flags |= VTPCI_FLAG_NO_MSI;
 	if (pci_find_cap(dev, PCIY_MSIX, NULL) != 0)
 		cn->vtpci_flags |= VTPCI_FLAG_NO_MSIX;
+
+	vtpci_setup_sysctl(cn);
 }
 
 int
@@ -202,6 +208,7 @@ vtpci_child_detached(struct vtpci_common *cn)
 	vtpci_release_child_resources(cn);
 
 	cn->vtpci_child_feat_desc = NULL;
+	cn->vtpci_host_features = 0;
 	cn->vtpci_features = 0;
 }
 
@@ -246,6 +253,7 @@ vtpci_negotiate_features(struct vtpci_common *cn,
 {
 	uint64_t features;
 
+	cn->vtpci_host_features = host_features;
 	vtpci_describe_features(cn, "host", host_features);
 
 	/*
@@ -254,9 +262,9 @@ vtpci_negotiate_features(struct vtpci_common *cn,
 	 */
 	features = host_features & child_features;
 	features = virtio_filter_transport_features(features);
-	vtpci_describe_features(cn, "negotiated", features);
 
 	cn->vtpci_features = features;
+	vtpci_describe_features(cn, "negotiated", features);
 
 	return (features);
 }
@@ -930,3 +938,64 @@ vtpci_config_intr(void *xcn)
 	if (child != NULL)
 		VIRTIO_CONFIG_CHANGE(child);
 }
+
+static int
+vtpci_feature_sysctl(struct sysctl_req *req, struct vtpci_common *cn,
+    uint64_t features)
+{
+	struct sbuf *sb;
+	int error;
+
+	sb = sbuf_new_for_sysctl(NULL, NULL, 256, req);
+	if (sb == NULL)
+		return (ENOMEM);
+
+	error = virtio_describe_sbuf(sb, features, cn->vtpci_child_feat_desc);
+	sbuf_delete(sb);
+
+	return (error);
+}
+
+static int
+vtpci_host_features_sysctl(SYSCTL_HANDLER_ARGS)
+{
+	struct vtpci_common *cn;
+
+	cn = arg1;
+
+	return (vtpci_feature_sysctl(req, cn, cn->vtpci_host_features));
+}
+
+static int
+vtpci_negotiated_features_sysctl(SYSCTL_HANDLER_ARGS)
+{
+	struct vtpci_common *cn;
+
+	cn = arg1;
+
+	return (vtpci_feature_sysctl(req, cn, cn->vtpci_features));
+}
+
+static void
+vtpci_setup_sysctl(struct vtpci_common *cn)
+{
+	device_t dev;
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid *tree;
+	struct sysctl_oid_list *child;
+
+	dev = cn->vtpci_dev;
+	ctx = device_get_sysctl_ctx(dev);
+	tree = device_get_sysctl_tree(dev);
+	child = SYSCTL_CHILDREN(tree);
+
+	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "nvqs",
+	    CTLFLAG_RD, &cn->vtpci_nvqs, 0, "Number of virtqueues");
+
+	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "host_features",
+	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, cn, 0,
+	    vtpci_host_features_sysctl, "A", "Features supported by the host");
+	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "negotiated_features",
+	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, cn, 0,
+	    vtpci_negotiated_features_sysctl, "A", "Features negotiated");
+}
diff --git a/sys/dev/virtio/pci/virtio_pci.h b/sys/dev/virtio/pci/virtio_pci.h
index d65ed853c33e..4c9a0e1c4cbe 100644
--- a/sys/dev/virtio/pci/virtio_pci.h
+++ b/sys/dev/virtio/pci/virtio_pci.h
@@ -45,6 +45,7 @@ struct vtpci_virtqueue {
 
 struct vtpci_common {
 	device_t			 vtpci_dev;
+	uint64_t			 vtpci_host_features;
 	uint64_t			 vtpci_features;
 	struct vtpci_virtqueue		*vtpci_vqs;
 	int				 vtpci_nvqs;
diff --git a/sys/dev/virtio/virtio.c b/sys/dev/virtio/virtio.c
index 18eace65a12b..53b47004610e 100644
--- a/sys/dev/virtio/virtio.c
+++ b/sys/dev/virtio/virtio.c
@@ -119,24 +119,15 @@ virtio_feature_name(uint64_t val, struct virtio_feature_desc *desc)
 	return (NULL);
 }
 
-void
-virtio_describe(device_t dev, const char *msg,
-    uint64_t features, struct virtio_feature_desc *desc)
+int
+virtio_describe_sbuf(struct sbuf *sb, uint64_t features,
+    struct virtio_feature_desc *desc)
 {
-	struct sbuf sb;
-	uint64_t val;
-	char *buf;
 	const char *name;
+	uint64_t val;
 	int n;
 
-	if ((buf = malloc(1024, M_TEMP, M_NOWAIT)) == NULL) {
-		device_printf(dev, "%s features: %#jx\n",
-		    msg, (uintmax_t) features);
-		return;
-	}
-
-	sbuf_new(&sb, buf, 1024, SBUF_FIXEDLEN);
-	sbuf_printf(&sb, "%s features: %#jx", msg, (uintmax_t) features);
+	sbuf_printf(sb, "%#jx", (uintmax_t) features);
 
 	for (n = 0, val = 1ULL << 63; val != 0; val >>= 1) {
 		/*
@@ -147,25 +138,51 @@ virtio_describe(device_t dev, const char *msg,
 			continue;
 
 		if (n++ == 0)
-			sbuf_cat(&sb, " <");
+			sbuf_cat(sb, " <");
 		else
-			sbuf_cat(&sb, ",");
+			sbuf_cat(sb, ",");
 
 		name = virtio_feature_name(val, desc);
 		if (name == NULL)
-			sbuf_printf(&sb, "%#jx", (uintmax_t) val);
+			sbuf_printf(sb, "%#jx", (uintmax_t) val);
 		else
-			sbuf_cat(&sb, name);
+			sbuf_cat(sb, name);
 	}
 
 	if (n > 0)
-		sbuf_cat(&sb, ">");
+		sbuf_cat(sb, ">");
 
-	if (sbuf_finish(&sb) == 0)
+	return (sbuf_finish(sb));
+}
+
+void
+virtio_describe(device_t dev, const char *msg, uint64_t features,
+    struct virtio_feature_desc *desc)
+{
+	struct sbuf sb;
+	char *buf;
+	int error;
+
+	if ((buf = malloc(1024, M_TEMP, M_NOWAIT)) == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+
+	sbuf_new(&sb, buf, 1024, SBUF_FIXEDLEN);
+	sbuf_printf(&sb, "%s features: ", msg);
+
+	error = virtio_describe_sbuf(&sb, features, desc);
+	if (error == 0)
 		device_printf(dev, "%s\n", sbuf_data(&sb));
 
 	sbuf_delete(&sb);
 	free(buf, M_TEMP);
+
+out:
+	if (error != 0) {
+		device_printf(dev, "%s features: %#jx\n", msg,
+		    (uintmax_t) features);
+	}
 }
 
 uint64_t
diff --git a/sys/dev/virtio/virtio.h b/sys/dev/virtio/virtio.h
index 85160eb18d0d..ccac57a5ad96 100644
--- a/sys/dev/virtio/virtio.h
+++ b/sys/dev/virtio/virtio.h
@@ -35,6 +35,7 @@
 #include <dev/virtio/virtio_ids.h>
 #include <dev/virtio/virtio_config.h>
 
+struct sbuf;
 struct vq_alloc_info;
 
 /*
@@ -82,7 +83,9 @@ struct virtio_pnp_match {
 
 const char *virtio_device_name(uint16_t devid);
 void	 virtio_describe(device_t dev, const char *msg,
-	     uint64_t features, struct virtio_feature_desc *feature_desc);
+	     uint64_t features, struct virtio_feature_desc *desc);
+int	 virtio_describe_sbuf(struct sbuf *sb, uint64_t features,
+	     struct virtio_feature_desc *desc);
 uint64_t virtio_filter_transport_features(uint64_t features);
 int	 virtio_bus_is_modern(device_t dev);
 void	 virtio_read_device_config_array(device_t dev, bus_size_t offset,



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