DF-3965 / trigger.c
/* * DF-3965 trigger sketch โ per-I/O dmamap unload only on IOP_RESULT_SUCCESS * ========================================================================== * hptiop_action() loads the CCB buffer into the per-SRB map for every * data command (hptiop.c:2304-2309). The completion callbacks unload ONLY * in the success case: * * hptiop_request_callback_itl hptiop.c:393-409 case IOP_RESULT_SUCCESS: * sync + bus_dmamap_unload * hptiop_request_callback_mv hptiop.c:547-561 (same shape) * hptiop_request_callback_mvfrey hptiop.c:654-668 (same shape) * * Every other result โ BAD_TARGET, BUSY, INVALID_REQUEST, FAIL, RESET, * CHECK_CONDITION โ returns the srb to the freelist with its dma_map STILL * LOADED. Deterministic source of leaked loads: every bus-scan probe of an * absent target id completes BAD_TARGET (hptiop.c:411-412) โ one leaked map * state per probe, at attach and at every HPT_SCAN_BUS ioctl / CAM rescan. * * Consequences: * - busdmamap_load() on an already-loaded map on next use of that srb * (hptiop.c:2304): on bounce-capable tags/platforms the cumulative * reserve/needed accounting (busdma_machdep.c:616-660) never releases the * prior reservation -> hw.busdma pool exhaustion (guest: max_bpages=1024) * -> permanent ENOMEM/EINPROGRESS -> CAM_BUSY forever on those srbs. * - On this no-bounce io_dmat (lowaddr=BUS_SPACE_MAXADDR) the leak is * bookkeeping-only on amd64, hence Low; on i-compat/32-bit configs and * any tag with a real lowaddr, it strands reserved bounce pages. * * Trigger on hardware: repeatedly `camcontrol rescan all` (or the * HPT_DO_IOCONTROL/HPT_SCAN_BUS ioctl) on an HBA with absent target ids; * watch hw.busdma.total_bpages climb / maps fail. */ int main(void) { return 0; } |