Measurement tools user guide

Measure CPU, memory, and IRQ behavior.

Commands, measurement boundaries, output fields, and reproducible comparisons for Jitter Tools 1.3.0.

Jitter Tools 1.3.0

Start here

Choose a tool, check its version, and run a finite measurement.

Jitter Tools 1.3.0 provides three standalone Linux command-line tools. CPUJitter observes execution gaps on one CPU. MEMjitter measures declared memory operations. IRQjitter observes kernel IRQ and softirq events through tracefs. Use them separately to answer a specific measurement question.

ComponentVersion coveredPrimary question
CPUJitter3.2.2How long are adjacent counter-read intervals on the selected CPU?
MEMjitter3.5.2How long do resident accesses, first writes, or successful mmap calls take?
IRQjitter1.3.0Which observed IRQ/softirq handlers and waits have long elapsed times?
Machine-readable streamjitter.stream/0.6.0How are measurements, coverage, quality, and cleanup recorded?
From a directory containing the three executables
./cpujitter --version
./memjitter --version
./irqjitter --version

The examples below run from an unpacked binary distribution. After a source build, the same executables are in ./bin/. If installed on PATH, omit the ./ prefix. CPU numbers are examples, not a production placement recommendation. Replace them with allowed, online Linux CPU IDs on your host.

Read the current process CPU and memory-node limits
grep -E "Cpus_allowed_list|Mems_allowed_list" /proc/self/status
cat /sys/devices/system/cpu/online
CPU execution intervals, one summary per second
./cpujitter -c 4 --duration 10
Resident byte reads, one summary per second
./memjitter -c 4 --duration 10
IRQ overview; CPU 1 runs the collector, all online CPUs are observed
sudo ./irqjitter -c 1 --duration 10

Run these examples one at a time. CPU and memory tests are active workloads. IRQjitter is passive in the sense that it does not generate test traffic, but tracing and collection still have overhead. CPU/MEM do not require root, disabled SMT, CPU isolation, an exclusive CPU, or HFTKernel. IRQ collection requires access to an existing tracefs mount and permission to create its own instance; sudo is one way to provide those permissions.

Jitter Tools 1.3.0

Build and verify

Keep source-build checks separate from binary-distribution checks.

The supplied 1.3.0 archive is source-only. It does not contain ready-to-run ELF executables. Its recorded qualification does not establish a completed Rust build or a live IRQ run. The supported source entry point is test.sh; it builds and tests before publishing binaries.

Build requirementScope
Linux GNU, x86_64 or aarch64Build natively for the host architecture.
Rust 1.85 or later, rustfmt and clippyCompiler and Rust quality gates.
C compiler, ar, static libc development files, readelfNative ABI code, GNU-static linking and ELF checks.
Python 3.10 or later and the test requirementsSource tests and build orchestration. Python is not required by the resulting measurement executables.
Supported source build and test entry point
cd jitter-tools-1.3.0
./test.sh

Cargo runs offline with a locked dependency set and no registry dependencies. Python test dependencies may be provisioned into the project-local .test-env/. Use --offline when the environment is already prepared and package-index downloads must be disabled.

Source acceptance run, with dependencies already available
./test.sh --offline --acceptance

After all required gates pass, the workflow publishes bin/cpujitter, bin/memjitter, bin/irqjitter, bin/build-ok.json, and dist/jitter-tools-1.3.0-linux-<architecture>-static.tgz. The release bundle includes BUILD.json, ELF.json, checksums, notices and documentation. Do not treat a partially completed source build as a qualified static distribution.

In an unpacked binary distribution, test.sh checks the delivered files
./test.sh
./cpujitter --build-info
./memjitter --build-info
./irqjitter --build-info

The binary-distribution test.sh requires sh, readelf, sha256sum, and grep. It is not the source build runner. GNU-static executables do not need Rust, Python, an ELF interpreter, or neighboring shared libraries at runtime. They still need an architecture-compatible Linux kernel, the required system calls and /proc and /sys; IRQjitter additionally needs tracefs. ELF checks are packaging evidence, not a guarantee of measurement accuracy or support on every kernel version.

Jitter Tools 1.3.0

Common controls

Select a CPU, define a run limit, and choose windowed or raw output.

ControlBehavior
-c CPURequired for all measurement runs. A single decimal Linux CPU ID, 0..65535. Lists and ranges are not accepted here. No automatic fallback CPU.
-n SECWindow width and summary interval; default 1 second, range 0.001..86400. It does not set sampling frequency.
--duration SECFinite observation duration, 0.001..86400 seconds. CPU/MEM preparation and calibration precede observation.
--samples NCPU/MEM only. Stop after a positive number of completed observations. IRQjitter has no --samples option.
--jsonJSON Lines. Keeps the default one-second windows unless --raw is also supplied.
--rawIndividual observations with full protocol records. Cannot be combined with -n or window-only controls.
--help, --version, --build-infoRun each informational option separately. No -c, calibration, or measurement is needed.

CPU/MEM also accept --cpu and --interval. IRQjitter 1.3.0 uses only -c and -n for these controls. All three accept attached short values such as -c4 -n0.1. Use plain decimal seconds, for example 0.1, not 100ms, 1e-1, or .1. Repeated options are rejected.

100 ms statistical windows; the capture loop continues between summaries
./cpujitter -c4 -n0.1 --duration 5
Bounded raw capture; no -n option
./cpujitter -c 4 --raw --json --samples 1000 > cpu-raw.jsonl 2> cpu-raw.stderr.log

Data goes to stdout and diagnostics to stderr. Redirecting stdout does not select JSON or raw mode. Use a finite duration or Ctrl+C to stop. A handled SIGINT/SIGTERM emits final records when the output channel remains usable and cleanup succeeds. A blocked system call, SIGKILL, failed host, or closed pipe prevents any guarantee of an immediate stop or complete final output.

Jitter Tools 1.3.0

CPUJitter

Measure adjacent execution intervals on one selected CPU.

The metric cpu_iteration_elapsed_ns is the calibrated elapsed time between adjacent hardware-counter reads inside a capture batch. It includes the loop branch, timestamp storage and counter-read overhead. It is not the CPU core cycle count, a device interrupt-delivery measurement, or a direct classification of the cause of a pause.

ordered is the default counter-read mode; relaxed is an explicit alternative with a distinct context. Calibration uses seven segments of at least 50 ms against CLOCK_MONOTONIC_RAW, with a fixed scale for the run. No baseline or counter cost is subtracted. On x86, declared invariant-TSC support and usable counter access are required; unsupported counters are rejected rather than replaced silently.

Separate ordered and relaxed runs; keep their distributions separate
./cpujitter -c 4 -n 1 --duration 30
./cpujitter -c 4 -n 1 --duration 30 --counter-read relaxed
Count intervals strictly greater than 5 microseconds, without filtering any sample
./cpujitter -c 4 -n 1 --duration 30 \
  --threshold cpu_iteration_elapsed_ns=5000
Save windows, metadata and termination state
./cpujitter -c 4 --duration 30 --json > cpu.jsonl 2> cpu.stderr.log
CPU-specific or capture controlDefault and range
--counter-read ordered|relaxedordered. Compare like-for-like counter-read contexts.
--batch-records N4096; 1..65536. Preallocated consecutive-read batch capacity.
--buffer-bytes N8388608; 16384..8388608. Bounded stdout queue.
--write-timeout-ms N1000; 1..60000. Cooperative output deadline, not a hard real-time guarantee.
--threshold cpu_iteration_elapsed_ns=NNonnegative integer nanoseconds. Counts values > N in windows.

One batch has a seed timestamp and completed observations. Capture is separated from clock anchors, validation, aggregation and output. A cooperative counter budget checks for roughly 20 ms of capture work every 256 records; it does not clip a large observed delay. ACTIVE% describes the covered capture portion, not total CPU utilization. Pauses occurring outside capture are unobserved for this metric.

Nanoseconds are computed with checked integer arithmetic and rounding to nearest: (delta_ticks * 1000000000 + hz / 2) / hz. Event timestamps for window assignment use the bracketed counter-to-MONOTONIC mapping. The value and its mapped start/end interval serve different purposes and need not be numerically identical. Unknown physical accuracy remains null in the stream.

Jitter Tools 1.3.0

MEMjitter

Choose resident access, first-touch, or mmap-call latency.

ModeMetricTimed operation
resident, defaultmem_resident_operation_nsOne byte read, non-atomic read/modify/write, or pointer-chase step.
first-touchmem_first_touch_nsOne volatile byte write to an untouched offset in a verified mapping/reset epoch.
allocmem_alloc_call_nsOne successful private anonymous mmap API call; no page touch or munmap inside the bracket.

Resident reads and read/modify/write

The default is resident, read, sequential, a 16777216-byte mapping (16 MiB), a system-page-sized stride, offset 0 and seed 1. Preparation touches each base page, warms the access plan and checks initial residency with mincore. Without an explicit lock, that snapshot is not a promise of continued residency.

Separate resident tests: default reads and random non-atomic byte RMW
./memjitter -c 4 --bytes 16777216 --duration 30
./memjitter -c 4 --operation rmw --pattern random --seed 1 --duration 30

read times one volatile byte load. rmw times a byte load, wrapping increment and store; it is not atomic and does not measure globally visible store completion. The timing bracket includes timestamp/fence overhead. A result is not pure DRAM latency.

Dependent pointer chase

A dependent chain through the selected offsets
./memjitter -c 4 --operation chase --bytes 16777216 \
  --seed 1 --duration 30

--operation chase selects pointer-chase automatically unless a pattern is explicit. An explicit pattern must also be pointer-chase. Other resident patterns are sequential, random with replacement, and permutation. Address selection and bookkeeping are outside each measured operation. A page-strided 16 MiB mapping on a 4096-byte-page host has 4096 sampled positions, not 16 MiB of payload read on each pass.

First-touch writes

Fresh mappings, with reset outside the timed write
./memjitter -c 4 --mode first-touch --reset remap \
  --bytes 16777216 --duration 30
Explicit MADV_DONTNEED discard with a repeatable access order
./memjitter -c 4 --mode first-touch --reset madvise \
  --pattern permutation --seed 1 --duration 30

First-touch permits sequential or permutation, without replacement inside an epoch. write is the only operation and need not be specified. After every successful remap/discard, mincore must confirm no resident pages before a new epoch begins. Reset work is excluded service time. A first byte write is not necessarily a separate page fault or physical-page allocation, especially when THP backs multiple offsets. Remap and madvise are different experiments.

Allocation API calls

Plain mmap-call latency; these are separate runs
./memjitter -c 4 --mode alloc --bytes 65536 --duration 30
./memjitter -c 4 --mode alloc --operation mmap --samples 65 --json

Alloc creates at most one owned mapping at a time and unmaps it before the next call. Only successful mmap intervals enter the histogram. mmap establishes a virtual mapping, not physical population of every page. The C ABI/libc wrapper and timestamp bracket remain part of the value. The legacy alloc-cycle, malloc/calloc latency and automatic memory-pressure generation are not implemented by this mode.

Layout and mode options

OptionValues and constraints
--moderesident | first-touch | alloc; default resident.
--operationresident: read | rmw | chase. first-touch: write. alloc: mmap.
--bytes NDecimal bytes, page multiple; default 16777216, maximum 1073741824. Not a MiB-suffixed string.
--stride-bytes NAt least one OS page, page-aligned and divides --bytes; default system page size. Resident/first-touch only.
--offset-bytes NByte offset inside a sampled base page; default 0. Chase also requires usize alignment and fit.
--seed NNonzero integer; default 1. Resident/first-touch only.
--patternResident: sequential | random | permutation | pointer-chase. First-touch: sequential | permutation.
--resetFirst-touch only: remap (default) | madvise.
--batch-records, --buffer-bytes, --write-timeout-msSame defaults and limits as CPUJitter.
--threshold METRIC=NUse the exact metric for the selected mode; strict > comparison in windows.
Count first-touch values above 20 microseconds
./memjitter -c 4 --mode first-touch --duration 30 \
  --threshold mem_first_touch_ns=20000

Alloc rejects pattern, stride, offset, seed and reset options, even when their values resemble defaults. No memory mode accepts CPUJitter's --counter-read. Keep the same operation, pattern, bytes, stride, offset, seed, reset and output mode when comparing results.

Jitter Tools 1.3.0

Memory policies

Apply optional policies only to the tool-owned mapping.

The default is --lock none, --thp system, inherited NUMA policy, and no explicit HugeTLB request. The tool does not reconfigure the system, enlarge lock limits, change a huge-page pool, or retry under a weaker policy. An explicit unsupported request fails with its reason.

Policyresidentfirst-touchalloc
--lock noneDefaultDefaultAllowed
--lock residentmlock before preparationRejectedRejected
--lock onfaultmlock2, followed by resident preparationOnly with --reset remapRejected
--thp systemDefault, no adviceDefault, no adviceAllowed
--thp never or --thp preferMADV_NOHUGEPAGE / MADV_HUGEPAGEAllowed and reapplied after remapRejected
--numa-node NRange-scoped MPOL_BINDRange-scoped MPOL_BINDRejected
--hugetlb-bytes NExplicit HugeTLB mappingRejectedRejected
A small locked resident working set, subject to RLIMIT_MEMLOCK
./memjitter -c 4 --bytes 65536 --lock resident --duration 10
Lock on fault while preserving first-touch preparation
./memjitter -c 4 --mode first-touch --lock onfault \
  --reset remap --bytes 65536 --duration 10
Separate THP-advice experiments, not global THP configuration
./memjitter -c 4 --thp never --duration 10
./memjitter -c 4 --thp prefer --duration 10
Bind the owned mapping to an allowed physical NUMA node
./memjitter -c 4 --numa-node 0 --duration 10
Explicit 2 MiB HugeTLB pages, only when the pool and host support are already available
./memjitter -c 4 --bytes 2097152 \
  --hugetlb-bytes 2097152 --duration 10

Locking prevents swapping of the mapping while held; it does not put data permanently in CPU cache. An accepted THP advice call does not prove huge-page backing. NUMA policy readback is distinct from observed physical page placement. NUMA IDs are 0..4095 and must be allowed by the host.

An explicit HugeTLB size must be a power of two greater than the OS base page, at most 1 GiB, and divide the mapping size. It is incompatible with explicit locking or non-system THP advice. Resident preparation requires successful MADV_POPULATE_WRITE for that range. The existing pool, quotas, permissions and required kernel operation must support the request; there is no fallback to ordinary pages.

Requested policy, successful operations and observed mapping state are recorded separately. Initial observations appear in meta; final mapping observations are written to stderr before unmap. Unavailable or unattributable information stays null. Proc-file snapshots and policy checks add service work, so compare runs with matching policies.

Jitter Tools 1.3.0

IRQjitter

Observe handler durations and softirq waits without changing IRQ placement.

IRQjitter uses one userspace reader thread and its own tracefs instance. Required IRQ tracepoints are irq_handler_entry, irq_handler_exit, softirq_raise, softirq_entry, and softirq_exit. The instance must support the mono trace clock. It does not mount tracefs, chmod it, change IRQ/RSS affinity, stop irqbalance, or enable an alternative backend.

Check for an existing tracefs mount; use its actual mount point
grep " tracefs " /proc/mounts
Explicit tracefs mount path, with one overview row per second
sudo ./irqjitter -c 1 --tracefs /sys/kernel/tracing --duration 15

Collector CPU versus observed CPUs

Collector on CPU 1; observe only CPUs 4 through 7
sudo ./irqjitter -c 1 --target-cpus 4-7 --duration 30

Without --target-cpus, supported events on all online CPUs are observed, including the collector CPU. A CPU list such as 2,4-7 restricts collection, not just presentation. IRQ activity that moves outside the selected set is outside coverage. CPU hotplug is monitored within the initial possible-CPU envelope and changes are reported with coverage information.

Three distinct timing metrics

MetricWhat it measuresInterpretation
irq_handler_elapsed_nsOne matching action-handler entry/exit on the same CPUIncludes intervening/nested work; not device-to-CPU interrupt delivery latency.
softirq_elapsed_nsOne matching softirq vector entry/exit on the same CPUNot exclusive CPU time or per-packet processing time.
softirq_observed_raise_to_entry_nsFirst saved observed pending raise to the next entry on that CPU/vectorAn observed, potentially coalesced wait; not waiting time for an individual packet.

An IRQ source is identified by metric, actual CPU, source number and name. Counts describe completed handler observations, not physical interrupts or packets. Identical source number/name pairs do not prove a persistent device identity across reconfiguration. A zero elapsed value may reflect the resolution of textual trace timestamps, commonly microsecond-level, rather than zero physical time.

Overview, details and raw events

Separate runs: overview, per-source compact table, and detailed JSON windows
sudo ./irqjitter -c 1 -n 1 --duration 30
sudo ./irqjitter -c 1 -n 1 --details --duration 30
sudo ./irqjitter -c 1 -n 1 --json --duration 30 > irq.jsonl 2> irq.stderr.log
Short raw capture for one observed CPU
sudo ./irqjitter -c 1 --target-cpus 4 --raw --json \
  --duration 2 > irq-raw.jsonl 2> irq-raw.stderr.log

--details is valid only for compact windows and cannot be combined with --json or --raw. JSON already preserves per-CPU/source window records. There is no timerlat mode or eBPF backend in this release. The real TIMER softirq is still observable.

Optional NAPI work/budget observations

NAPI adds work/budget observations to either compact view
sudo ./irqjitter -c 1 --napi --duration 15
sudo ./irqjitter -c 1 --napi --details --duration 15

--napi requires a supported napi:napi_poll tracepoint. The metric is napi_poll_work, unit work, not nanoseconds. It reports the return work value and budget. at_budget requires a positive budget with work equal to budget; over_budget requires work greater than a positive budget. Neither implies a proven packet backlog by itself. NAPI duration, IRQ-to-NAPI latency and an inferred hardware queue ID are not provided.

Window and resource controls

OptionDefault and range
--threshold NSNonnegative integer; applies to timing series only. Unlike CPU/MEM, no metric name is supplied.
--lateness SECDefault min(window / 10, 0.01 seconds). Range 0..window, up to nine fractional digits. Window-only.
--max-series N256 for windows, 4096 for raw; range 1..4096.
--window-memory-mib N64; 1..512. Window-memory ceiling.
--buffer-kb N256 per possible CPU; 16..16384.
--max-trace-mib N256; 1..4096. Conservative total kernel trace-buffer budget, not total process memory.
--output-bytes N8388608; 65536..8388608. Bounded output queue.
--write-timeout-ms N1000; 1..60000. Cooperative output deadline.
Observe timing values above 10 microseconds in the selected CPU scope
sudo ./irqjitter -c 1 --target-cpus 4-7 -n 1 \
  --threshold 10000 --duration 30

Late completed samples are reported as late and are not moved into a later window or used to rewrite old output. Slow output can delay trace reading and lead to kernel-buffer loss. The collector checks controls and buffer statistics, but neither empty reads nor lack of a loss notice prove complete coverage. Trace instrumentation runs on event CPUs too, not only on the collector CPU.

Jitter Tools 1.3.0

Read the output

Separate measured values, coverage, statistical bounds and run status.

CPU/MEM compact columns

Column layout only, not measurement results
TIME(s) CPU COUNT MIN AVG P99<= P99.9<= MAX ACTIVE% LOSS QUALITY PART
ColumnMeaning
TIME(s)End of the window relative to observation start, in seconds, not UTC.
COUNTNumber of accepted observations in that row.
MIN / MAXExact extrema of the reported integer values, in ns for timing metrics. This does not assert physical accuracy.
AVGDisplayed to 0.1 ns using integer arithmetic; JSON preserves exact sum/count.
P99<= / P99.9<=Upper bounds of the corresponding histogram bins, limited by observed extrema. Not an exact sorted percentile or a confidence interval.
ACTIVE%Covered measurement time divided by window duration, not CPU utilization.
LOSSseen means a loss notice has been observed; the flag is sticky. A dash means no notice was seen, not proven completeness.
QUALITYPreserved data-quality classification. partial may describe unqualified instrumentation.
PARTyes means the final statistical window is shorter than the requested width. It is independent of QUALITY.

A timing threshold adds a suffix such as >5000=N, where N is the count strictly above the limit. An empty population has COUNT=0 and NA statistics, not zero latency. IRQ --details adds METRIC, SOURCE, UNIT and the NAPI-specific BUDGET_MAX, AT_BUDGET and OVER_BUDGET fields; inapplicable values are NA.

IRQ overview columns

Default IRQ overview; --napi adds a separate work/budget group
TIME(s) IRQ_N IRQ_P99<= IRQ_MAX SOFT_N SOFT_P99<= SOFT_MAX WAIT_N WAIT_P99<= WAIT_MAX PAIR_GAPS LATE BUFFER OTHER PART

IRQ, SOFT and WAIT are separate populations. Each combines compatible source histograms across the observed CPUs for that metric and window; percentiles are recomputed from pooled bin counts, not averaged across source percentiles.

Diagnostic columnMeaning
PAIR_GAPSNumber of detected pairing notices. It is not a count of lost hardware interrupts or packets.
LATECompleted samples rejected after their window was already published. Unknown counts stay unknown.
BUFFERnot-observed, loss-observed or unknown. not-observed does not certify absence of loss.
OTHEROther diagnostic notices, not IRQ counts.
PARTA shorter final statistical window.

For example, softirq_entry_without_observed_raise increments pairing diagnostics. It does not establish a trace-ring overflow, and a valid subsequent entry/exit duration can still be retained. Buffer statistics and textual loss markers may overlap; do not add them to a fabricated total loss count.

End-of-run summaries

Compact output prints # SUMMARY, # TOTAL rows and an end status after the last window, including the final partial window. CPU/MEM and IRQ details summarize each series; IRQ overview produces separate pooled timing totals and optional NAPI work totals. The IRQ overview summary includes MAX_CPU and MAX_SOURCE, so the largest observed event retains its source.

Totals use exact counts and sums from fully reported windows, weighted mean, extrema and merged histogram bins. They are not averages of window averages or percentiles. scope=reported_windows excludes unreported and late samples. A source associated with a maximum is an observation identity, not a proven root cause.

JSON Lines for automation

Use --json to retain metadata, per-series windows, quality reasons, loss/gap records and the terminal end record. Use --raw --json for individual samples. Compact summary text is not appended to JSON. Wide integer values such as nanoseconds, counts and sums are decimal strings; parse them as integers, not floating-point numbers. A null value is unknown, not zero.

Optional jq examples for inspecting a saved JSONL file
jq 'select(.type == "meta")' cpu.jsonl
jq 'select(.type == "end") | {execution, exit_code, quality, cleanup}' cpu.jsonl
jq 'select(.type == "window") | {series, stats, coverage}' cpu.jsonl

The end record separates execution, quality and cleanup.confirmed. observations_aggregated is important for window mode; a zero observations_emitted does not mean no data was collected if values were aggregated into windows. Retain the complete file and stderr, rather than only selected window lines.

Jitter Tools 1.3.0

Automation and A/B runs

Save complete runs and preserve the producer exit code.

Exit codeMeaning
0Complete execution/data under the reported contract. Current live producers normally retain unqualified status instead.
2CLI, capability, runtime, output or cleanup failure. Inspect stderr and any available end record.
3Partial or unqualified data. May be a functionally completed run with confirmed cleanup.
130Handled SIGINT, such as Ctrl+C, when cleanup succeeds.
143Handled SIGTERM when cleanup succeeds.

These are the tool's documented codes, not a promise about every shell, timeout wrapper or fatal signal. Preserve a nonzero status; avoid appending || true to make a result appear successful. A pipe closed by head can prevent final records. --samples or --duration is the supported way to bound a capture.

Bash example that retains output, diagnostics, build identity and exit status
out="jitter-run-$(date -u +%Y%m%dT%H%M%SZ)"
mkdir "$out"
./cpujitter --build-info > "$out/build-info.json"

if ./cpujitter -c 4 -n 1 --duration 30 --json \
    > "$out/cpu.jsonl" 2> "$out/cpu.stderr.log"; then
    rc=0
else
    rc=$?
fi
printf "%s\n" "$rc" > "$out/exit-code.txt"
printf "Saved %s, exit code %s\n" "$out" "$rc"

case "$rc" in
  0) echo "Completed; inspect the end record." ;;
  3) echo "Partial/unqualified; inspect quality and cleanup before comparing." ;;
  *) echo "Run did not complete normally; inspect diagnostics." >&2 ;;
esac

Compare like-for-like runs

For a stock-kernel versus HFTKernel comparison, use the same executable build, CPU role, memory mode, operation, pattern, size, seed, reset policy, explicit memory policies, counter-read mode, batch, output destination, window size and duration. Preserve kernel, topology and scheduler metadata from each run. Change the intended variable, rather than changing the measurement definition at the same time.

Run each experiment separately. Launching two active tools on the same CPU is allowed by this release, but the runs then interfere and are not independent baselines. Keep diagnostic tracing separate from the primary A/B measurement when the goal is to avoid introducing a different tracing load into only one side.

Compare counts, distributions, maximums, threshold exceedances, coverage and quality together. Do not average p99 values across runs or windows. A whole-run compact total pools reported histograms inside that run; exact cross-run population analysis requires retaining compatible underlying data. The 3.x CPU/MEM CLI and measurement populations are not interchangeable with the older 2.x benchmark profiles already published on the HFTKernel site.

Jitter Tools 1.3.0

Troubleshooting

Locate the failed phase without silently changing the experiment.

ObservationInterpretation and next check
No row immediately after launchCPU/MEM prepare and calibrate first. A full -n window then has to elapse. A finite shorter run emits its final partial window.
CPU rejected or affinity errorCheck the requested Linux CPU ID, online state and cpuset permissions. Select a valid CPU explicitly; the tool will not silently choose another.
Counter-access or calibration failureInspect the counter and clock diagnostics. CPU/MEM require usable architecture-specific counters; there is no alternate-clock fallback in this CLI.
Exit 3 / partial / producer_unqualifiedRead execution and cleanup as separate facts. This status alone is not evidence of overloaded IRQ handling or bad kernel tuning.
Zero or NA IRQ valuesZero can reflect trace timestamp resolution; NA can mean no completed sample. Neither proves a delay-free system.
softirq_entry_without_observed_raiseAn incomplete observed pending pair. Check PAIR_GAPS and detailed JSON; do not call it packet loss or ring overflow.
Late events or buffer lossKeep the loss evidence. Review event scope, output speed and resource budgets. Shorter windows and raw output can add load. A new run with changed settings is a different configuration.
Cannot open/create tracefs instanceVerify the mount, permissions, mono clock and supported event formats. The program does not mount, chmod, or take ownership of another session.
Missing record-cmd or record-tgid in an instanceThese global caches are optional for this collector. Diagnose the actual required control and errno; do not change global caches just to satisfy the tool.
NAPI requested but unsupportedThe --napi request fails explicitly. Run without --napi only as a deliberately separate IRQ-only experiment.
mlock / NUMA / HugeTLB request rejectedInspect errno, lock limit, allowed nodes, existing huge-page pool and host support. No automatic elevation, pool provisioning or policy fallback is performed.
Output timeout, EPIPE, or missing end recordThe output is incomplete. Preserve stderr, use bounded runs and a destination that can keep up. Do not classify a truncated capture as complete.
Cleanup failure or leftover instanceInspect cleanup.errors and recovery_required. Verify the reported owned instance and absence of a live owner before any administrator action. Do not delete tracefs instances recursively.

Orderly IRQ shutdown stops recording, drains within bounded limits, disables owned events, closes descriptors, removes only its own instance and restores affinity. A handled failure remains a failure even if later cleanup releases resources. SIGKILL and host failure cannot guarantee complete instance removal.

Source references

Version-scoped implementation references

This guide is derived from the supplied Jitter Tools 1.3.0 source, CLI parsers and measurement contracts. It does not certify live timing accuracy or compatibility with every distribution. Source file paths below are relative to the source archive.

Source archive: jitter-tools-1.3.0-source(1).tgz
SHA-256: 39f803db80f8e598af67fa93171b0c0ead0c6350d2911bc9368b639cdee746ec

S1. Release identity and build workflow
  • package.json
  • README.md
  • docs/BINARY_README.md
  • scripts/run-tests.py
  • scripts/static_release.py
  • validation/qualification.json
S2. Command-line parsers and validation
  • tools/cpujitter/src/cli.rs
  • tools/memjitter/src/cli.rs
  • tools/irqjitter/src/cli.rs
  • vendor/jitter-common/src/interval.rs
  • docs/CLI_TRACEFS.md
S3. CPU capture, clocks and placement
  • tools/cpujitter/src/counter.rs
  • tools/cpujitter/src/model.rs
  • tools/cpujitter/src/runtime.rs
  • vendor/jitter-common/src/observed_placement.rs
  • docs/CPUJITTER.md
  • docs/LAUNCH.md
S4. Resident memory operations
  • tools/memjitter/src/resident.rs
  • tools/memjitter/src/counter.rs
  • tools/memjitter/src/runtime.rs
  • docs/MEMJITTER.md
S5. First-touch and allocation modes
  • tools/memjitter/src/first_touch.rs
  • tools/memjitter/src/first_touch_runtime.rs
  • tools/memjitter/src/alloc.rs
  • tools/memjitter/src/alloc_runtime.rs
  • tools/memjitter/native/allocation.c
  • docs/FIRST_TOUCH.md
  • docs/ALLOC.md
S6. Explicit per-mapping memory policies
  • tools/memjitter/src/policy.rs
  • tools/memjitter/native/policy.c
  • docs/MEMORY_POLICIES.md
S7. Passive IRQ collection and tracefs lifecycle
  • tools/irqjitter/src/engine.rs
  • tools/irqjitter/src/parser.rs
  • tools/irqjitter/src/runtime.rs
  • tools/irqjitter/src/session.rs
  • tools/irqjitter/src/native.rs
  • docs/IRQJITTER.md
  • docs/CLI_TRACEFS.md
S8. IRQ windows, overview and NAPI
  • tools/irqjitter/src/windows.rs
  • vendor/jitter-common/src/irq_overview.rs
  • docs/IRQ_OVERVIEW.md
  • docs/IRQ_WINDOWS_NAPI.md
S9. Output, histograms, summary and stream schema
  • vendor/jitter-common/src/compact.rs
  • vendor/jitter-common/src/run_summary.rs
  • vendor/jitter-common/src/histogram.rs
  • vendor/jitter-common/src/record.rs
  • vendor/jitter-common/src/lifecycle.rs
  • docs/OUTPUT.md
  • contracts/stream/schemas/stream.schema.json
  • contracts/stream/contracts/metrics.json