git: ed34a6b6eab9 - main - iflib: Add subinterface interrupt allocation function

From: Eric Joyner <erj_at_FreeBSD.org>
Date: Thu, 18 Apr 2024 23:23:18 UTC
The branch main has been updated by erj:

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

commit ed34a6b6eab9ea39759ccd3f12876a815d271929
Author:     Eric Joyner <erj@FreeBSD.org>
AuthorDate: 2023-01-18 00:46:39 +0000
Commit:     Eric Joyner <erj@FreeBSD.org>
CommitDate: 2024-04-18 23:14:02 +0000

    iflib: Add subinterface interrupt allocation function
    
    The ice(4) driver will add the ability to create extra interfaces
    that hang off of the base interface; to do that the driver requires
    a method for the subinterface to request hardware interrupt resources
    from the base interface.
    
    Signed-off-by: Eric Joyner <erj@FreeBSD.org>
    
    MFC after:      3 days
    Sponsored by:   Intel Corporation
    Differential Revision:  https://reviews.freebsd.org/D39930
---
 sys/net/iflib.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 sys/net/iflib.h | 12 +++++++++
 2 files changed, 89 insertions(+), 2 deletions(-)

diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index 9be99df08a81..8129fb3f2f0b 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -1469,8 +1469,8 @@ iflib_dma_alloc_align(if_ctx_t ctx, int size, int align, iflib_dma_info_t dma, i
 				&dma->idi_tag);
 	if (err) {
 		device_printf(dev,
-		    "%s: bus_dma_tag_create failed: %d\n",
-		    __func__, err);
+		    "%s: bus_dma_tag_create failed: %d (size=%d, align=%d)\n",
+		    __func__, err, size, align);
 		goto fail_0;
 	}
 
@@ -6199,6 +6199,81 @@ iflib_irq_set_affinity(if_ctx_t ctx, if_irq_t irq, iflib_intr_type_t type,
 	return (0);
 }
 
+/*
+ * Allocate a hardware interrupt for subctx using the parent (ctx)'s hardware
+ * resources.
+ *
+ * Similar to iflib_irq_alloc_generic(), but for interrupt type IFLIB_INTR_RXTX
+ * only.
+ *
+ * XXX: Could be removed if subctx's dev has its intr resource allocation
+ * methods replaced with custom ones?
+ */
+int
+iflib_irq_alloc_generic_subctx(if_ctx_t ctx, if_ctx_t subctx, if_irq_t irq,
+			       int rid, iflib_intr_type_t type,
+			       driver_filter_t *filter, void *filter_arg,
+			       int qid, const char *name)
+{
+	device_t dev, subdev;
+	struct grouptask *gtask;
+	struct taskqgroup *tqg;
+	iflib_filter_info_t info;
+	gtask_fn_t *fn;
+	int tqrid, err;
+	driver_filter_t *intr_fast;
+	void *q;
+
+	MPASS(ctx != NULL);
+	MPASS(subctx != NULL);
+
+	tqrid = rid;
+	dev = ctx->ifc_dev;
+	subdev = subctx->ifc_dev;
+
+	switch (type) {
+	case IFLIB_INTR_RXTX:
+		q = &subctx->ifc_rxqs[qid];
+		info = &subctx->ifc_rxqs[qid].ifr_filter_info;
+		gtask = &subctx->ifc_rxqs[qid].ifr_task;
+		tqg = qgroup_if_io_tqg;
+		fn = _task_fn_rx;
+		intr_fast = iflib_fast_intr_rxtx;
+		NET_GROUPTASK_INIT(gtask, 0, fn, q);
+		break;
+	default:
+		device_printf(dev, "%s: unknown net intr type for subctx %s (%d)\n",
+		    __func__, device_get_nameunit(subdev), type);
+		return (EINVAL);
+	}
+
+	info->ifi_filter = filter;
+	info->ifi_filter_arg = filter_arg;
+	info->ifi_task = gtask;
+	info->ifi_ctx = q;
+
+	NET_GROUPTASK_INIT(gtask, 0, fn, q);
+
+	/* Allocate interrupts from hardware using parent context */
+	err = _iflib_irq_alloc(ctx, irq, rid, intr_fast, NULL, info, name);
+	if (err != 0) {
+		device_printf(dev, "_iflib_irq_alloc failed for subctx %s: %d\n",
+		    device_get_nameunit(subdev), err);
+		return (err);
+	}
+
+	if (tqrid != -1) {
+		err = iflib_irq_set_affinity(ctx, irq, type, qid, gtask, tqg, q,
+		    name);
+		if (err)
+			return (err);
+	} else {
+		taskqgroup_attach(tqg, gtask, q, dev, irq->ii_res, name);
+	}
+
+	return (0);
+}
+
 int
 iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid,
 			iflib_intr_type_t type, driver_filter_t *filter,
diff --git a/sys/net/iflib.h b/sys/net/iflib.h
index 5e1adccf202c..bf40c7429fb8 100644
--- a/sys/net/iflib.h
+++ b/sys/net/iflib.h
@@ -393,6 +393,11 @@ typedef enum {
  * function.
  */
 #define IFLIB_FEATURE_QUEUE_SELECT_V2	1400073
+/*
+ * Driver can create subinterfaces with their own Tx/Rx queues
+ * that all share a single device (or commonly, port)
+ */
+#define IFLIB_FEATURE_SUB_INTERFACES	1500014
 
 /*
  * These enum values are used in iflib_needs_restart to indicate to iflib
@@ -491,4 +496,11 @@ void iflib_add_int_delay_sysctl(if_ctx_t, const char *, const char *,
 								if_int_delay_info_t, int, int);
 uint16_t iflib_get_extra_msix_vectors_sysctl(if_ctx_t ctx);
 
+/*
+ * Sub-interface support
+ */
+int iflib_irq_alloc_generic_subctx(if_ctx_t ctx, if_ctx_t subctx, if_irq_t irq,
+				   int rid, iflib_intr_type_t type,
+				   driver_filter_t *filter, void *filter_arg,
+				   int qid, const char *name);
 #endif /*  __IFLIB_H_ */