DF-4064 / fxp_callout_replica_fixed.c
/* * fxp_callout_replica_fixed.c - protocol-level validation of the fix.diff * shape for if_fxp.c (DF-4064): fxp_tick() becomes non-blocking via * lwkt_serialize_try() + 1-tick callout_reset retry (same shape as the * DF-3738-validated emx fix). */ #include <sys/param.h> #include <sys/kernel.h> #include <sys/module.h> #include <sys/serialize.h> #include <sys/callout.h> #include <sys/sysctl.h> #include <sys/systm.h> static struct lwkt_serialize ser; static struct callout blk_c; static volatile int blk_fired, blk_ran; static void blk_timer(void *arg) { blk_fired++; /* FIXED shape: non-blocking try + 1-tick retry */ if (lwkt_serialize_try(&ser) == 0) { callout_reset(&blk_c, 1, blk_timer, NULL); return; } blk_ran++; callout_reset(&blk_c, hz, blk_timer, NULL); lwkt_serialize_exit(&ser); } static int arm_sysctl(SYSCTL_HANDLER_ARGS) { int error, v = 0; error = sysctl_handle_int(oidp, &v, 0, req); if (error || req->newptr == NULL) return error; if (v == 1) { blk_fired = blk_ran = 0; callout_reset(&blk_c, 1, blk_timer, NULL); kprintf("fxrf: armed (FIXED fxp_tick shape)\n"); } return 0; } static int stop_blk_sysctl(SYSCTL_HANDLER_ARGS) { int error, v = 0; error = sysctl_handle_int(oidp, &v, 0, req); if (error || req->newptr == NULL) return error; if (v != 1) return 0; lwkt_serialize_enter(&ser); /* hold it long enough for the handler to hit the try + retry path */ tsleep(&blk_ran, 0, "blkw", 3 * hz); kprintf("fxrf: holding serializer, callout_stop() [fxp_stop shape]...\n"); callout_stop(&blk_c); kprintf("fxrf: callout_stop RETURNED cleanly, pending=%d\n", callout_pending(&blk_c)); lwkt_serialize_exit(&ser); return 0; } static SYSCTL_NODE(_kern, OID_AUTO, fxrf, CTLFLAG_RW, 0, "fxp callout replica fixed"); SYSCTL_PROC(_kern_fxrf, OID_AUTO, arm, CTLTYPE_INT | CTLFLAG_RW, 0, 0, arm_sysctl, "I", "arm FIXED fxp_stat_timer replica"); SYSCTL_PROC(_kern_fxrf, OID_AUTO, stop_blk, CTLTYPE_INT | CTLFLAG_RW, 0, 0, stop_blk_sysctl, "I", "fxp_stop vs FIXED (try+retry) fxp_tick"); static int fxp_callout_replica_fixed_load(struct module *m, int what, void *arg) { switch (what) { case MOD_LOAD: lwkt_serialize_init(&ser); callout_init(&blk_c); /* NON-MP, exactly if_fxp.c:399 */ kprintf("fxp_callout_replica_fixed: loaded (hz=%d)\n", hz); return 0; case MOD_UNLOAD: callout_stop(&blk_c); return 0; } return 0; } static moduledata_t fxp_callout_replica_fixed_mod = { "fxp_callout_replica_fixed", fxp_callout_replica_fixed_load, NULL }; DECLARE_MODULE(fxp_callout_replica_fixed, fxp_callout_replica_fixed_mod, SI_SUB_DRIVERS, SI_ORDER_ANY); |