Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174379761
D58722.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D58722.diff
View Options
diff --git a/share/man/man4/iflib.4 b/share/man/man4/iflib.4
--- a/share/man/man4/iflib.4
+++ b/share/man/man4/iflib.4
@@ -248,7 +248,47 @@
.Pp
Additional OIDs useful for driver and iflib development are exposed when the
INVARIANTS and/or WITNESS options are enabled in the kernel.
+.Ss FAILURE INJECTION
+Registration failures can be injected for one selected device through the
+.Xr fail 9
+framework.
+Set
+.Va debug.fail_point.iflib.register_device
+to the exact device name and configure one of these fail points:
+.Bl -tag -width "register_before_attach_pre"
+.It Va register_before_attach_pre
+Before the driver's pre-attach method.
+.It Va register_after_attach_pre
+After the driver's pre-attach method succeeds.
+.It Va register_after_taskqueue
+After the private taskqueue is started.
+.It Va register_after_interrupts
+After interrupt resources are allocated.
+.It Va register_after_queues
+After queue setup and core-offset allocation.
+.It Va register_after_attach_post
+After the interface is attached and the driver's post-attach method succeeds.
+.El
+.Pp
+The fail points are under
+.Va debug.fail_point.iflib
+and accept the syntax described by
+.Xr fail 9 .
+A one-shot failure is safest because it permits the next probe to recover the
+device:
+.Bd -literal -offset indent
+sysctl debug.fail_point.iflib.register_device=igc1
+sysctl debug.fail_point.iflib.register_after_attach_pre='1*return(5)'
+devctl detach igc1
+devctl attach pci0:4:0:0 # returns EIO
+devctl attach pci0:4:0:0 # succeeds
+.Ed
+.Pp
+After detach, a device may no longer have its former name.
+Use a bus-specific address, as shown in the PCI example above, to reprobe it.
.Sh SEE ALSO
+.Xr devctl 8 ,
+.Xr fail 9 ,
.Xr iflib 9
.Sh HISTORY
This framework was introduced in
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -34,6 +34,7 @@
#include <sys/types.h>
#include <sys/bus.h>
#include <sys/eventhandler.h>
+#include <sys/fail.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@@ -565,6 +566,15 @@
static SYSCTL_NODE(_net, OID_AUTO, iflib, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"iflib driver parameters");
+static SYSCTL_NODE(_debug_fail_point, OID_AUTO, iflib,
+ CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "iflib fail points");
+
+static char iflib_register_fail_device[32];
+SYSCTL_STRING(_debug_fail_point_iflib, OID_AUTO, register_device,
+ CTLFLAG_RW | CTLFLAG_MPSAFE,
+ iflib_register_fail_device, sizeof(iflib_register_fail_device),
+ "device name eligible for registration fail points");
+
/*
* XXX need to ensure that this can't accidentally cause the head to be moved backwards
*/
@@ -5198,6 +5208,30 @@
MPASS(!ctx->ifc_core_offset_ref);
}
+static bool
+iflib_register_fail_device_matches(device_t dev)
+{
+ const char *nameunit;
+
+ nameunit = device_get_nameunit(dev);
+ return (iflib_register_fail_device[0] != '\0' && nameunit != NULL &&
+ strcmp(nameunit, iflib_register_fail_device) == 0);
+}
+
+#define IFLIB_REGISTER_FAIL_POINT(_dev, _name, _error, _label) do { \
+ KFAIL_POINT_CODE_COND(_debug_fail_point_iflib, _name, \
+ iflib_register_fail_device_matches((_dev)), \
+ FAIL_POINT_NONSLEEPABLE, { \
+ (_error) = RETURN_VALUE; \
+ if ((_error) <= 0) \
+ (_error) = EIO; \
+ device_printf((_dev), \
+ "injecting iflib registration failure at %s: %d\n", \
+ #_name, (_error)); \
+ goto _label; \
+ }); \
+} while (0)
+
int
iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ctxp)
{
@@ -5245,11 +5279,15 @@
iflib_reset_qvalues(ctx);
IFNET_WLOCK();
CTX_LOCK(ctx);
+ IFLIB_REGISTER_FAIL_POINT(dev, register_before_attach_pre, err,
+ fail_cleanup);
if ((err = IFDI_ATTACH_PRE(ctx)) != 0) {
device_printf(dev, "IFDI_ATTACH_PRE failed %d\n", err);
goto fail_cleanup;
}
attach_pre_succeeded = true;
+ IFLIB_REGISTER_FAIL_POINT(dev, register_after_attach_pre, err,
+ fail_cleanup);
_iflib_pre_assert(scctx);
ctx->ifc_txrx = *scctx->isc_txrx;
@@ -5333,6 +5371,8 @@
TASK_INIT(&ctx->ifc_admin_task, 0, _task_fn_admin, ctx);
TASK_INIT(&ctx->ifc_led_task, 0, _task_fn_led, ctx);
+ IFLIB_REGISTER_FAIL_POINT(dev, register_after_taskqueue, err,
+ fail_cleanup);
/* Set up cpu set. If it fails, use the set of all CPUs. */
if (bus_get_cpus(dev, INTR_CPUS, sizeof(ctx->ifc_cpus), &ctx->ifc_cpus) != 0) {
@@ -5363,6 +5403,8 @@
msix = 0;
}
intr_allocated = true;
+ IFLIB_REGISTER_FAIL_POINT(dev, register_after_interrupts, err,
+ fail_cleanup);
/* Get memory for the station queues */
if ((err = iflib_queues_alloc(ctx))) {
device_printf(dev, "Unable to allocate queue memory\n");
@@ -5377,6 +5419,8 @@
* Now that we know how many queues there are, get the core offset.
*/
ctx->ifc_sysctl_core_offset = get_ctx_core_offset(ctx);
+ IFLIB_REGISTER_FAIL_POINT(dev, register_after_queues, err,
+ fail_cleanup);
if (msix > 1) {
/*
@@ -5442,6 +5486,8 @@
device_printf(dev, "IFDI_ATTACH_POST failed %d\n", err);
goto fail_detach;
}
+ IFLIB_REGISTER_FAIL_POINT(dev, register_after_attach_post, err,
+ fail_detach);
/*
* Tell the upper layer(s) if IFCAP_VLAN_MTU is supported.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 3, 7:39 PM (13 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40147606
Default Alt Text
D58722.diff (5 KB)
Attached To
Mode
D58722: iflib: Add registration failure injection points
Attached
Detach File
Event Timeline
Log In to Comment