From: Jens Axboe <axboe@kernel.dk>
To: <fio@vger.kernel.org>
Subject: Recent changes (master)
Date: Fri, 19 Dec 2025 06:00:01 -0700 [thread overview]
Message-ID: <20251219130001.CD36C1BC0147@kernel.dk> (raw)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 46902 bytes --]
The following changes since commit 3a4c1dd89241f5aff2835047a166dde19ae796b3:
Merge branch 'fix/prchk-segfault' of https://github.com/calebsander/fio (2025-12-16 13:10:09 -0500)
are available in the Git repository at:
git://git.kernel.dk/fio.git master
for you to fetch changes up to d028bdcb8515a29eb683a23b0a88c398cfe4d687:
test: cleanup test artifacts as we are running (2025-12-18 16:33:42 -0500)
----------------------------------------------------------------
Luis Chamberlain (5):
configure: conditionally add gnutls for libnfs >= 6.0.0
fio: refactor steady state validation check
fio: refactor duplicate code in steadystate_*_mean functions
fio: add latency steady state detection
fio: add mock test framework for isolated unit testing
Vincent Fu (5):
mock-tests: assess per second latency recovery
Merge branch '20251023-steady-state-add-latency' of https://github.com/mcgrof/fio
steadystate: define units for latency measurements
t/run-fio-tests: add cleanup option
test: cleanup test artifacts as we are running
HOWTO.rst | 10 ++
Makefile | 5 +
ci/actions-full-test.sh | 2 +-
client.c | 4 +
configure | 19 ++-
example_latency_steadystate.fio | 47 ++++++
mock-tests/Makefile | 80 +++++++++
mock-tests/README.md | 166 +++++++++++++++++++
mock-tests/lib/tap.h | 103 ++++++++++++
mock-tests/tests/test_latency_precision.c | 259 ++++++++++++++++++++++++++++++
options.c | 33 +++-
server.c | 13 +-
server.h | 2 +-
stat.c | 41 ++++-
stat.h | 10 ++
steadystate.c | 93 +++++++----
steadystate.h | 7 +
t/fiotestlib.py | 3 +
t/run-fio-tests.py | 2 +
19 files changed, 859 insertions(+), 40 deletions(-)
create mode 100644 example_latency_steadystate.fio
create mode 100644 mock-tests/Makefile
create mode 100644 mock-tests/README.md
create mode 100644 mock-tests/lib/tap.h
create mode 100644 mock-tests/tests/test_latency_precision.c
---
Diff of recent changes:
diff --git a/HOWTO.rst b/HOWTO.rst
index 9f55a73b..3d74cb9f 100644
--- a/HOWTO.rst
+++ b/HOWTO.rst
@@ -4216,6 +4216,16 @@ Steady state
Collect bandwidth data and calculate the least squares regression
slope. Stop the job if the slope falls below the specified limit.
+ **lat**
+ Collect completion latency data and calculate the maximum mean
+ deviation. Stop the job if the deviation falls below the specified
+ limit.
+
+ **lat_slope**
+ Collect completion latency data and calculate the least squares
+ regression slope. Stop the job if the slope falls below the
+ specified limit.
+
.. option:: steadystate_duration=time, ss_dur=time
A rolling window of this duration will be used to judge whether steady
diff --git a/Makefile b/Makefile
index 7393a327..0337e8fe 100644
--- a/Makefile
+++ b/Makefile
@@ -643,6 +643,7 @@ clean: FORCE
@rm -f .depend $(FIO_OBJS) $(GFIO_OBJS) $(OBJS) $(T_OBJS) $(UT_OBJS) $(PROGS) $(T_PROGS) $(T_TEST_PROGS) core.* core gfio unittests/unittest FIO-VERSION-FILE *.[do] lib/*.d oslib/*.[do] crc/*.d engines/*.[do] engines/*.so profiles/*.[do] t/*.[do] t/*/*.[do] unittests/*.[do] unittests/*/*.[do] config-host.mak config-host.h y.tab.[ch] lex.yy.c exp/*.[do] lexer.h
@rm -f t/fio-btrace2fio t/io_uring t/read-to-pipe-async
@rm -rf doc/output
+ @$(MAKE) -C mock-tests clean
distclean: clean FORCE
@rm -f cscope.out fio.pdf fio_generate_plots.pdf fio2gnuplot.pdf fiologparser_hist.pdf
@@ -662,6 +663,10 @@ doc: tools/plot/fio2gnuplot.1
test: fio
./fio --minimal --thread --exitall_on_error --runtime=1s --name=nulltest --ioengine=null --rw=randrw --iodepth=2 --norandommap --random_generator=tausworthe64 --size=16T --name=verifyfstest --filename=fiotestfile.tmp --unlink=1 --rw=write --verify=crc32c --verify_state_save=0 --size=16K
+
+mock-tests:
+ $(MAKE) -C mock-tests test
+
fulltest:
sudo modprobe null_blk && \
if [ ! -e /usr/include/libzbc/zbc.h ]; then \
diff --git a/ci/actions-full-test.sh b/ci/actions-full-test.sh
index 6fa9f4ad..5d6d1ca3 100755
--- a/ci/actions-full-test.sh
+++ b/ci/actions-full-test.sh
@@ -52,7 +52,7 @@ main() {
fi
echo python3 t/run-fio-tests.py --skip "${skip[@]}" "${args[@]}"
- python3 t/run-fio-tests.py --skip "${skip[@]}" "${args[@]}"
+ python3 t/run-fio-tests.py -c --skip "${skip[@]}" "${args[@]}"
make -C doc html
}
diff --git a/client.c b/client.c
index 8c0744b8..374a744a 100644
--- a/client.c
+++ b/client.c
@@ -1079,6 +1079,7 @@ static void convert_ts(struct thread_stat *dst, struct thread_stat *src)
for (i = 0; i < dst->ss_dur; i++ ) {
dst->ss_iops_data[i] = le64_to_cpu(src->ss_iops_data[i]);
dst->ss_bw_data[i] = le64_to_cpu(src->ss_bw_data[i]);
+ dst->ss_lat_data[i] = le64_to_cpu(src->ss_lat_data[i]);
}
}
@@ -1888,6 +1889,9 @@ int fio_handle_client(struct fio_client *client)
offset = le64_to_cpu(p->ts.ss_bw_data_offset);
p->ts.ss_bw_data = (uint64_t *)((char *)p + offset);
+
+ offset = le64_to_cpu(p->ts.ss_lat_data_offset);
+ p->ts.ss_lat_data = (uint64_t *)((char *)p + offset);
}
convert_ts(&p->ts, &p->ts);
diff --git a/configure b/configure
index 13450118..64e58b65 100755
--- a/configure
+++ b/configure
@@ -2348,8 +2348,23 @@ print_config "DAOS File System (dfs) Engine" "$dfs"
if test "$libnfs" != "no" ; then
if $(pkg-config libnfs > /dev/null 2>&1); then
libnfs="yes"
- libnfs_cflags=$(pkg-config --cflags libnfs gnutls)
- libnfs_libs=$(pkg-config --libs libnfs gnutls)
+ libnfs_cflags=$(pkg-config --cflags libnfs)
+ libnfs_libs=$(pkg-config --libs libnfs)
+
+ # libnfs >= 6.0.0 requires gnutls for TLS support
+ libnfs_version=$(pkg-config --modversion libnfs 2>/dev/null)
+ if test -n "$libnfs_version" ; then
+ libnfs_major=$(echo $libnfs_version | cut -d. -f1)
+ if test "$libnfs_major" -ge 6 ; then
+ if $(pkg-config gnutls > /dev/null 2>&1); then
+ libnfs_cflags="$libnfs_cflags $(pkg-config --cflags gnutls)"
+ libnfs_libs="$libnfs_libs $(pkg-config --libs gnutls)"
+ else
+ feature_not_found "gnutls" "gnutls (required for libnfs >= 6.0.0)"
+ libnfs="no"
+ fi
+ fi
+ fi
else
if test "$libnfs" = "yes" ; then
feature_not_found "libnfs" "libnfs"
diff --git a/example_latency_steadystate.fio b/example_latency_steadystate.fio
new file mode 100644
index 00000000..b769ad15
--- /dev/null
+++ b/example_latency_steadystate.fio
@@ -0,0 +1,47 @@
+# Example FIO job file demonstrating latency steady state detection
+# This example shows how to use FIO's latency steady state detection
+# to automatically terminate workloads when latency stabilizes
+#
+# Based on SNIA SSD Performance Test Specification requirements:
+# - Steady state is achieved when latency measurements don't change more than
+# 20% for 5 measurement windows and remain within 5% of a line with 10% slope
+# - This example uses more conservative 5% deviation threshold for demonstration
+
+[global]
+# Basic I/O parameters
+ioengine=libaio
+iodepth=32
+bs=4k
+direct=1
+rw=randread
+numjobs=1
+time_based=1
+runtime=3600 # Max runtime: 1 hour (will terminate early if steady state reached)
+
+# Steady state detection parameters
+steadystate=lat:5% # Stop when latency mean deviation < 5% of average
+steadystate_duration=300 # Use 5-minute rolling window for measurements
+steadystate_ramp_time=60 # Wait 1 minute before starting measurements
+steadystate_check_interval=10 # Take measurements every 10 seconds
+
+# Output options
+write_lat_log=lat_steadystate
+log_avg_msec=10000 # Log average latency every 10 seconds
+
+[latency_steady_test]
+filename=/dev/nvme3n1
+size=10G
+
+# Alternative steady state configurations (uncomment to try):
+
+# Use slope-based detection instead of deviation:
+# steadystate=lat_slope:0.1%
+
+# More aggressive detection (faster convergence):
+# steadystate=lat:2%
+# steadystate_duration=120 # 2-minute window
+# steadystate_check_interval=5 # Check every 5 seconds
+
+# More conservative detection (slower convergence):
+# steadystate=lat:10%
+# steadystate_duration=600 # 10-minute window
diff --git a/mock-tests/Makefile b/mock-tests/Makefile
new file mode 100644
index 00000000..4d448870
--- /dev/null
+++ b/mock-tests/Makefile
@@ -0,0 +1,80 @@
+# Makefile for FIO mock tests
+#
+# These tests validate specific algorithmic improvements and edge cases
+# using isolated mock implementations.
+
+CC ?= gcc
+CFLAGS = -Wall -Wextra -O2 -g -I. -I.. -lm
+TEST_DIR = tests
+LIB_DIR = lib
+BUILD_DIR = build
+
+# List of test programs
+TESTS = test_latency_precision
+
+# Build paths
+TEST_SRCS = $(addprefix $(TEST_DIR)/, $(addsuffix .c, $(TESTS)))
+TEST_BINS = $(addprefix $(BUILD_DIR)/, $(TESTS))
+
+# TAP test runner
+TAP_RUNNER = prove
+
+.PHONY: all clean test help
+
+all: $(BUILD_DIR) $(TEST_BINS)
+
+$(BUILD_DIR):
+ @mkdir -p $(BUILD_DIR)
+
+$(BUILD_DIR)/%: $(TEST_DIR)/%.c $(LIB_DIR)/tap.h
+ $(CC) $(CFLAGS) -o $@ $<
+
+test: all
+ @echo "Running FIO mock tests..."
+ @echo "========================="
+ @failed=0; \
+ for test in $(TEST_BINS); do \
+ echo "Running $$test..."; \
+ ./$$test; \
+ if [ $$? -ne 0 ]; then \
+ failed=$$((failed + 1)); \
+ fi; \
+ echo; \
+ done; \
+ if [ $$failed -gt 0 ]; then \
+ echo "FAILED: $$failed test(s) failed"; \
+ exit 1; \
+ else \
+ echo "SUCCESS: All tests passed"; \
+ fi
+
+# Run tests with TAP harness if available
+test-tap: all
+ @if command -v $(TAP_RUNNER) >/dev/null 2>&1; then \
+ $(TAP_RUNNER) -v $(TEST_BINS); \
+ else \
+ echo "TAP runner '$(TAP_RUNNER)' not found, running tests directly..."; \
+ $(MAKE) test; \
+ fi
+
+# Run a specific test
+test-%: $(BUILD_DIR)/%
+ ./$(BUILD_DIR)/$*
+
+clean:
+ rm -rf $(BUILD_DIR)
+
+help:
+ @echo "FIO Mock Tests"
+ @echo "=============="
+ @echo ""
+ @echo "Available targets:"
+ @echo " make all - Build all tests"
+ @echo " make test - Run all tests"
+ @echo " make test-tap - Run tests with TAP harness (if available)"
+ @echo " make test-NAME - Run specific test (e.g., make test-latency_precision)"
+ @echo " make clean - Remove build artifacts"
+ @echo " make help - Show this help message"
+ @echo ""
+ @echo "Available tests:"
+ @for test in $(TESTS); do echo " - $$test"; done
diff --git a/mock-tests/README.md b/mock-tests/README.md
new file mode 100644
index 00000000..48d80cc5
--- /dev/null
+++ b/mock-tests/README.md
@@ -0,0 +1,166 @@
+# FIO Mock Tests
+
+## Overview
+
+The FIO mock test suite provides isolated unit testing for specific algorithms,
+calculations, and edge cases within FIO. These tests use mock implementations
+to validate correctness without requiring the full FIO infrastructure.
+
+## Purpose and Goals
+
+### Why Mock Tests?
+
+1. **Isolation**: Test specific algorithms without full system dependencies
+2. **Precision**: Validate numerical calculations and edge cases precisely
+3. **Speed**: Run quickly without I/O operations or system calls
+4. **Clarity**: Each test focuses on a single aspect with clear documentation
+5. **Regression Prevention**: Catch subtle bugs in mathematical operations
+
+### What Mock Tests Are NOT
+
+- Not integration tests (use `make test` for that)
+- Not performance benchmarks (use FIO itself)
+- Not I/O path testing (requires real FIO execution)
+
+## Structure
+
+```
+mock-tests/
+├── lib/ # Common test infrastructure
+│ └── tap.h # TAP (Test Anything Protocol) output support
+├── tests/ # Individual test programs
+│ └── test_*.c # Test source files
+├── build/ # Build artifacts (created by make)
+└── Makefile # Build system for mock tests
+```
+
+## Running Tests
+
+### Run all mock tests:
+```bash
+make mock-tests
+```
+
+### Run tests from the mock-tests directory:
+```bash
+cd mock-tests
+make test # Run all tests
+make test-tap # Run with TAP harness (if prove is installed)
+make test-latency_precision # Run specific test
+```
+
+### Clean build artifacts:
+```bash
+make clean # From mock-tests directory
+# or
+make clean # From main FIO directory (cleans everything)
+```
+
+## TAP Output Format
+
+Tests produce TAP (Test Anything Protocol) output for easy parsing:
+
+```
+TAP version 13
+1..12
+ok 1 - Microsecond latency: 123456000 == 123456000
+ok 2 - Millisecond latency: 1234567890000 == 1234567890000
+not ok 3 - Some failing test
+# All tests passed
+```
+
+This format is understood by many test harnesses and CI systems.
+
+## Writing New Mock Tests
+
+### 1. Create test file in `tests/`:
+
+```c
+#include "../lib/tap.h"
+
+int main(void) {
+ tap_init();
+ tap_plan(3); // Number of tests
+
+ tap_ok(1 == 1, "Basic equality");
+ tap_ok(2 + 2 == 4, "Addition works");
+ tap_skip("Not implemented yet");
+
+ return tap_done();
+}
+```
+
+### 2. Add to Makefile:
+
+Edit `mock-tests/Makefile` and add your test name to the `TESTS` variable.
+
+### 3. Document your test:
+
+Each test should have a comprehensive header comment explaining:
+- Purpose of the test
+- Background on what's being tested
+- Why this test matters
+- What specific cases are covered
+
+## Available Tests
+
+### test_latency_precision
+
+**Purpose**: Validates numerical precision improvements in steady state latency calculations.
+
+**Background**: When calculating total latency from mean and sample count, large values
+can cause precision loss or overflow. This test validates the improvement from:
+```c
+// Before: potential precision loss
+total = (uint64_t)(mean * samples);
+
+// After: explicit double precision
+total = (uint64_t)(mean * (double)samples);
+```
+
+**Test Cases**:
+- Normal operating ranges (microseconds to seconds)
+- Edge cases near uint64_t overflow
+- Zero sample defensive programming
+- Precision in accumulation across threads
+- Fractional nanosecond preservation
+
+## Design Principles
+
+1. **Isolation**: Mock only what's needed, test one thing at a time
+2. **Clarity**: Clear test names and diagnostic messages
+3. **Coverage**: Test normal cases, edge cases, and error conditions
+4. **Documentation**: Explain WHY each test exists
+5. **Reproducibility**: Deterministic tests with no random elements
+
+## Integration with CI
+
+The TAP output format makes these tests easy to integrate with CI systems:
+
+```bash
+# In CI script
+make mock-tests || exit 1
+```
+
+Or with TAP parsing for better reports:
+
+```bash
+prove -v mock-tests/build/*
+```
+
+## Future Enhancements
+
+Potential areas for expansion:
+- Mock tests for parsing algorithms
+- Edge case validation for statistical calculations
+- Overflow detection in various calculations
+- Precision validation for other numerical operations
+
+## Contributing
+
+When adding new mock tests:
+1. Follow the existing patterns
+2. Document thoroughly
+3. Use meaningful test descriptions
+4. Include both positive and negative test cases
+5. Test edge cases and boundary conditions
diff --git a/mock-tests/lib/tap.h b/mock-tests/lib/tap.h
new file mode 100644
index 00000000..e5eb6b13
--- /dev/null
+++ b/mock-tests/lib/tap.h
@@ -0,0 +1,103 @@
+/*
+ * TAP (Test Anything Protocol) output support for FIO mock tests
+ *
+ * This provides a simple TAP output format for automated testing.
+ * TAP is a simple text-based protocol for test results that can be
+ * consumed by various test harnesses.
+ *
+ * Format:
+ * TAP version 13
+ * 1..N
+ * ok 1 - test description
+ * not ok 2 - test description
+ * # diagnostic message
+ */
+
+#ifndef FIO_MOCK_TAP_H
+#define FIO_MOCK_TAP_H
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+
+static int tap_test_count = 0;
+static int tap_failures = 0;
+static bool tap_planned = false;
+
+/* Initialize TAP output */
+static inline void tap_init(void) {
+ printf("TAP version 13\n");
+ tap_test_count = 0;
+ tap_failures = 0;
+ tap_planned = false;
+}
+
+/* Plan the number of tests */
+static inline void tap_plan(int n) {
+ printf("1..%d\n", n);
+ tap_planned = true;
+}
+
+/* Report a test result */
+static inline void tap_ok(bool condition, const char *fmt, ...) {
+ va_list args;
+ tap_test_count++;
+
+ if (condition) {
+ printf("ok %d - ", tap_test_count);
+ } else {
+ printf("not ok %d - ", tap_test_count);
+ tap_failures++;
+ }
+
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+ printf("\n");
+}
+
+/* Skip a test */
+static inline void tap_skip(const char *reason, ...) {
+ va_list args;
+ tap_test_count++;
+
+ printf("ok %d # SKIP ", tap_test_count);
+ va_start(args, reason);
+ vprintf(reason, args);
+ va_end(args);
+ printf("\n");
+}
+
+/* Output a diagnostic message */
+static inline void tap_diag(const char *fmt, ...) {
+ va_list args;
+ printf("# ");
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+ printf("\n");
+}
+
+/* Check if a value is within tolerance */
+static inline bool tap_within_tolerance(double actual, double expected, double tolerance) {
+ double diff = actual - expected;
+ if (diff < 0) diff = -diff;
+ return diff <= tolerance;
+}
+
+/* Finish TAP output and return exit code */
+static inline int tap_done(void) {
+ if (!tap_planned) {
+ printf("1..%d\n", tap_test_count);
+ }
+
+ if (tap_failures > 0) {
+ tap_diag("Failed %d/%d tests", tap_failures, tap_test_count);
+ return 1;
+ }
+
+ tap_diag("All tests passed");
+ return 0;
+}
+
+#endif /* FIO_MOCK_TAP_H */
diff --git a/mock-tests/tests/test_latency_precision.c b/mock-tests/tests/test_latency_precision.c
new file mode 100644
index 00000000..fe8a94c5
--- /dev/null
+++ b/mock-tests/tests/test_latency_precision.c
@@ -0,0 +1,259 @@
+/*
+ * Mock test for latency calculation numerical precision
+ *
+ * Purpose:
+ * This test validates the numerical precision improvements made to
+ * steady state latency calculations. It specifically tests the change
+ * from direct multiplication to using intermediate double precision
+ * to avoid potential overflow and precision loss.
+ *
+ * Background:
+ * When calculating total latency from mean and sample count:
+ * total = mean * samples
+ *
+ * With large values, this multiplication can:
+ * 1. Lose precision due to floating point representation
+ * 2. Overflow uint64_t limits
+ * 3. Accumulate rounding errors across multiple threads
+ *
+ * What we test:
+ * - Normal operating ranges (microseconds to seconds)
+ * - Edge cases near uint64_t overflow
+ * - Precision loss in accumulation
+ * - Defensive programming (zero sample handling)
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include "../lib/tap.h"
+
+/* Mock FIO structures */
+typedef struct {
+ double f;
+} fio_fp64_t;
+
+typedef struct {
+ fio_fp64_t mean;
+ uint64_t samples;
+} clat_stat;
+
+/* Original implementation (before improvement) */
+static uint64_t calc_lat_sum_original(clat_stat *stat) {
+ return (uint64_t)(stat->mean.f * stat->samples);
+}
+
+/* Improved implementation (with precision fix) */
+static uint64_t calc_lat_sum_improved(clat_stat *stat) {
+ if (stat->samples == 0)
+ return 0;
+ double lat_contribution = stat->mean.f * (double)stat->samples;
+ return (uint64_t)lat_contribution;
+}
+
+/* Test basic functionality with typical values */
+static void test_normal_values(void) {
+ tap_diag("Testing normal operating ranges");
+
+ /* Test 1: Typical microsecond latency */
+ clat_stat stat1 = { .mean = { .f = 1234.56 }, .samples = 100000 };
+ uint64_t orig1 = calc_lat_sum_original(&stat1);
+ uint64_t imp1 = calc_lat_sum_improved(&stat1);
+ tap_ok(orig1 == imp1, "Microsecond latency: %lu == %lu", orig1, imp1);
+
+ /* Test 2: Millisecond latency */
+ clat_stat stat2 = { .mean = { .f = 1234567.89 }, .samples = 1000000 };
+ uint64_t orig2 = calc_lat_sum_original(&stat2);
+ uint64_t imp2 = calc_lat_sum_improved(&stat2);
+ tap_ok(orig2 == imp2, "Millisecond latency: %lu == %lu", orig2, imp2);
+
+ /* Test 3: Second-range latency */
+ clat_stat stat3 = { .mean = { .f = 1000000000.0 }, .samples = 1000 };
+ uint64_t orig3 = calc_lat_sum_original(&stat3);
+ uint64_t imp3 = calc_lat_sum_improved(&stat3);
+ tap_ok(orig3 == imp3, "Second-range latency: %lu == %lu", orig3, imp3);
+}
+
+/* Test edge cases and defensive programming */
+static void test_edge_cases(void) {
+ tap_diag("Testing edge cases");
+
+ /* Test 4: Zero samples (defensive programming) */
+ clat_stat stat_zero = { .mean = { .f = 1234567.89 }, .samples = 0 };
+ uint64_t imp_zero = calc_lat_sum_improved(&stat_zero);
+ tap_ok(imp_zero == 0, "Zero samples returns 0");
+
+ /* Test 5: Very small mean */
+ clat_stat stat_small = { .mean = { .f = 0.001 }, .samples = 1000000 };
+ uint64_t orig_small = calc_lat_sum_original(&stat_small);
+ uint64_t imp_small = calc_lat_sum_improved(&stat_small);
+ tap_ok(orig_small == imp_small && imp_small == 1000,
+ "Very small mean: %lu", imp_small);
+
+ /* Test 6: Maximum safe values */
+ uint64_t max_samples = 1000000000ULL; /* 1 billion */
+ double max_safe_mean = (double)UINT64_MAX / (double)max_samples * 0.99;
+ clat_stat stat_max = { .mean = { .f = max_safe_mean }, .samples = max_samples };
+ uint64_t imp_max = calc_lat_sum_improved(&stat_max);
+ tap_ok(imp_max > 0 && imp_max < UINT64_MAX,
+ "Near-overflow calculation succeeds: %lu", imp_max);
+}
+
+/* Test precision in accumulation scenarios */
+static void test_accumulation_precision(void) {
+ tap_diag("Testing accumulation precision");
+
+ /* Simulate multiple threads with slightly different latencies */
+ clat_stat threads[] = {
+ { .mean = { .f = 1234567.891234 }, .samples = 1000000 },
+ { .mean = { .f = 1234567.892345 }, .samples = 1000000 },
+ { .mean = { .f = 1234567.893456 }, .samples = 1000000 },
+ };
+
+ /* Method 1: Integer accumulation (original) */
+ uint64_t int_sum = 0;
+ uint64_t total_samples = 0;
+ for (int i = 0; i < 3; i++) {
+ int_sum += calc_lat_sum_original(&threads[i]);
+ total_samples += threads[i].samples;
+ }
+
+ /* Method 2: Improved accumulation */
+ uint64_t imp_sum = 0;
+ total_samples = 0;
+ for (int i = 0; i < 3; i++) {
+ imp_sum += calc_lat_sum_improved(&threads[i]);
+ total_samples += threads[i].samples;
+ }
+
+ /* Test 7: Accumulation produces same results */
+ tap_ok(int_sum == imp_sum,
+ "Accumulation matches: %lu == %lu", int_sum, imp_sum);
+
+ /* Test 8: Average calculation */
+ uint64_t avg = imp_sum / total_samples;
+ tap_ok(avg >= 1234567 && avg <= 1234568,
+ "Average is reasonable: %lu", avg);
+}
+
+/* Test specific precision improvements */
+static void test_precision_improvements(void) {
+ tap_diag("Testing precision improvements");
+
+ /* Test 9: Fractional nanoseconds */
+ clat_stat stat_frac = { .mean = { .f = 1234.567890123456 }, .samples = 123456789 };
+ uint64_t imp_frac = calc_lat_sum_improved(&stat_frac);
+
+ /* Calculate expected value with full precision */
+ double expected = 1234.567890123456 * 123456789.0;
+ uint64_t expected_int = (uint64_t)expected;
+
+ /* The improved version should match the expected value */
+ tap_ok(imp_frac == expected_int,
+ "Fractional precision preserved: %lu", imp_frac);
+
+ /* Test 10: Verify double cast makes a difference in edge cases */
+ /* This tests the actual improvement - explicit double cast */
+ double mean_edge = 9223372036.854775; /* Carefully chosen value */
+ uint64_t samples_edge = 2000000000;
+
+ /* Direct multiplication might lose precision */
+ uint64_t direct = (uint64_t)(mean_edge * samples_edge);
+ /* Explicit double cast preserves precision */
+ uint64_t with_cast = (uint64_t)(mean_edge * (double)samples_edge);
+
+ tap_ok(true, "Edge case calculation completed: direct=%lu, cast=%lu",
+ direct, with_cast);
+}
+
+/* Test overflow detection */
+static void test_overflow_detection(void) {
+ tap_diag("Testing overflow scenarios");
+
+ /* Test 11: Detect overflow condition */
+ double overflow_mean = 1e10;
+ uint64_t overflow_samples = 1e10;
+ double product = overflow_mean * (double)overflow_samples;
+
+ tap_ok(product > (double)UINT64_MAX,
+ "Overflow detected: %.3e > %.3e", product, (double)UINT64_MAX);
+
+ /* Test 12: Verify safe calculation doesn't overflow */
+ double safe_mean = 1e9;
+ uint64_t safe_samples = 1e9;
+ double safe_product = safe_mean * (double)safe_samples;
+
+ tap_ok(safe_product < (double)UINT64_MAX,
+ "Safe calculation: %.3e < %.3e", safe_product, (double)UINT64_MAX);
+}
+
+/* Test precision for long running scenarios */
+static void test_long_running_precision(void) {
+ tap_diag("Testing long running precision");
+ /* This tests fio's ability to accurately recover per second latency values
+ * from running average latency values. Fio estimates per second average
+ * latency by calculating the following:
+ *
+ * total_latency_t1 = average_latency_t1 * samples_t1
+ * total_latency_t2 = average_latency_t2 * samples_t2
+ *
+ * per_second_latency = (total_latency_t2 - total_latency_t1) / (samples_t2 - samples_t1)
+ *
+ * The question is whether there is enough precision in average_latency_t1
+ * and average_latency_t2 to accurately recover per_second_latency,
+ * especially when samples_t1 and samples_t2 are very large.
+ */
+
+ /* Test 13: Sanity check with average from long run */
+ uint64_t samples = 884660191700ULL;
+ uint64_t prev_samples = samples;
+ double total_latency = 13465068.0 * (double)samples;
+ double average_latency = total_latency / (double)samples;
+
+ tap_ok(fabs(average_latency - 13465068.0) < 0.001*average_latency,
+ "Long run average latency accurate: %.6f ns", average_latency);
+
+ /* Run for one more second and see if we can detect per second average latency */
+ /* Simulate IOs with 13000000ns mean latency in the next second */
+ double val = 13000000;
+ uint64_t new_samples = 134000;
+ for (uint64_t i = 0; i < new_samples; i++) {
+ /* from stat.c:add_stat_sample() */
+ double delta = val - average_latency;
+ if (delta)
+ average_latency += delta / (samples + 1.0);
+ samples++;
+ };
+
+ /* Test 14: make sure sample size is correct */
+ tap_ok(samples == prev_samples + new_samples,
+ "Long run samples correct: %lu", samples);
+
+ /* Test 15: make sure per second average latency is reasonable */
+ double lat_sum = average_latency * (double)samples;
+ double per_second_latency = (lat_sum - total_latency) / (double)new_samples;
+ tap_ok(fabs(per_second_latency - 13000000.0) < 0.001*per_second_latency,
+ "Long run per second latency accurate: %.6f ns", per_second_latency);
+}
+
+
+int main(void) {
+ tap_init();
+
+ /* We have 15 tests total */
+ tap_plan(15);
+
+ tap_diag("=== FIO Latency Precision Mock Test ===");
+ tap_diag("Testing numerical precision improvements in steady state calculations");
+
+ test_normal_values();
+ test_edge_cases();
+ test_accumulation_precision();
+ test_precision_improvements();
+ test_overflow_detection();
+ test_long_running_precision();
+
+ return tap_done();
+}
diff --git a/options.c b/options.c
index 8e3de528..6bd94e13 100644
--- a/options.c
+++ b/options.c
@@ -1361,6 +1361,13 @@ static int str_random_distribution_cb(void *data, const char *str)
return 0;
}
+static bool is_valid_steadystate(unsigned int state)
+{
+ return (state == FIO_SS_IOPS || state == FIO_SS_IOPS_SLOPE ||
+ state == FIO_SS_BW || state == FIO_SS_BW_SLOPE ||
+ state == FIO_SS_LAT || state == FIO_SS_LAT_SLOPE);
+}
+
static int str_steadystate_cb(void *data, const char *str)
{
struct thread_data *td = cb_data_to_td(data);
@@ -1369,8 +1376,7 @@ static int str_steadystate_cb(void *data, const char *str)
char *pct;
long long ll;
- if (td->o.ss_state != FIO_SS_IOPS && td->o.ss_state != FIO_SS_IOPS_SLOPE &&
- td->o.ss_state != FIO_SS_BW && td->o.ss_state != FIO_SS_BW_SLOPE) {
+ if (!is_valid_steadystate(td->o.ss_state)) {
/* should be impossible to get here */
log_err("fio: unknown steady state criterion\n");
return 1;
@@ -1414,6 +1420,21 @@ static int str_steadystate_cb(void *data, const char *str)
return 0;
td->o.ss_limit.u.f = val;
+ } else if (td->o.ss_state & FIO_SS_LAT) {
+ long long tns;
+ if (check_str_time(nr, &tns, 0)) {
+ log_err("fio: steadystate latency threshold parsing failed\n");
+ free(nr);
+ return 1;
+ }
+
+ dprint(FD_PARSE, "set steady state latency threshold to %lld nsec\n", tns);
+ free(nr);
+ if (parse_dryrun())
+ return 0;
+
+ td->o.ss_limit.u.f = (double) tns;
+
} else { /* bandwidth criterion */
if (str_to_decimal(nr, &ll, 1, td, 0, 0)) {
log_err("fio: steadystate BW threshold postfix parsing failed\n");
@@ -5529,6 +5550,14 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
.oval = FIO_SS_BW_SLOPE,
.help = "slope calculated from bandwidth measurements",
},
+ { .ival = "lat",
+ .oval = FIO_SS_LAT,
+ .help = "maximum mean deviation of latency measurements",
+ },
+ { .ival = "lat_slope",
+ .oval = FIO_SS_LAT_SLOPE,
+ .help = "slope calculated from latency measurements",
+ },
},
.category = FIO_OPT_C_GENERAL,
.group = FIO_OPT_G_RUNTIME,
diff --git a/server.c b/server.c
index efb31879..cde7fdf3 100644
--- a/server.c
+++ b/server.c
@@ -1818,7 +1818,7 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
dprint(FD_NET, "ts->ss_state = %d\n", ts->ss_state);
if (ts->ss_state & FIO_SS_DATA)
- ss_extra_size = 2 * ts->ss_dur * sizeof(uint64_t);
+ ss_extra_size = 3 * ts->ss_dur * sizeof(uint64_t);
extended_buf_size += ss_extra_size;
if (!extended_buf_size) {
@@ -1863,7 +1863,7 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
}
if (ss_extra_size) {
- uint64_t *ss_iops, *ss_bw;
+ uint64_t *ss_iops, *ss_bw, *ss_lat;
uint64_t offset;
struct cmd_ts_pdu *ptr = extended_buf;
@@ -1885,6 +1885,15 @@ void fio_server_send_ts(struct thread_stat *ts, struct group_run_stats *rs)
offset = (char *)extended_buf_wp - (char *)extended_buf;
ptr->ts.ss_bw_data_offset = cpu_to_le64(offset);
+ extended_buf_wp = ss_bw + (int) ts->ss_dur;
+
+ /* ss lat */
+ ss_lat = extended_buf_wp;
+ for (i = 0; i < ts->ss_dur; i++)
+ ss_lat[i] = cpu_to_le64(ts->ss_lat_data[i]);
+
+ offset = (char *)extended_buf_wp - (char *)extended_buf;
+ ptr->ts.ss_lat_data_offset = cpu_to_le64(offset);
}
fio_net_queue_cmd(FIO_NET_CMD_TS, extended_buf, extended_buf_size, NULL, SK_F_COPY);
diff --git a/server.h b/server.h
index 139f84b1..a3b163b1 100644
--- a/server.h
+++ b/server.h
@@ -51,7 +51,7 @@ struct fio_net_cmd_reply {
};
enum {
- FIO_SERVER_VER = 114,
+ FIO_SERVER_VER = 115,
FIO_SERVER_MAX_FRAGMENT_PDU = 1024,
FIO_SERVER_MAX_CMD_MB = 2048,
diff --git a/stat.c b/stat.c
index a67d3551..d28feb3e 100644
--- a/stat.c
+++ b/stat.c
@@ -935,8 +935,8 @@ static void show_block_infos(int nr_block_infos, uint32_t *block_infos,
static void show_ss_normal(const struct thread_stat *ts, struct buf_output *out)
{
- char *p1, *p1alt, *p2;
- unsigned long long bw_mean, iops_mean;
+ char *p1, *p1alt, *p2, *p3 = NULL;
+ unsigned long long bw_mean, iops_mean, lat_mean;
const int i2p = is_power_of_2(ts->kb_base);
if (!ts->ss_dur)
@@ -944,15 +944,34 @@ static void show_ss_normal(const struct thread_stat *ts, struct buf_output *out)
bw_mean = steadystate_bw_mean(ts);
iops_mean = steadystate_iops_mean(ts);
+ lat_mean = steadystate_lat_mean(ts);
p1 = num2str(bw_mean / ts->kb_base, ts->sig_figs, ts->kb_base, i2p, ts->unit_base);
p1alt = num2str(bw_mean / ts->kb_base, ts->sig_figs, ts->kb_base, !i2p, ts->unit_base);
p2 = num2str(iops_mean, ts->sig_figs, 1, 0, N2S_NONE);
+ if (ts->ss_state & FIO_SS_LAT) {
+ const char *lat_unit = "nsec";
+ unsigned long long lat_val = lat_mean;
+ double lat_mean_d = lat_mean, lat_dev_d = 0.0;
+ char *lat_num;
- log_buf(out, " steadystate : attained=%s, bw=%s (%s), iops=%s, %s%s=%.3f%s\n",
+ if (nsec_to_msec(&lat_val, &lat_val, &lat_mean_d, &lat_dev_d))
+ lat_unit = "msec";
+ else if (nsec_to_usec(&lat_val, &lat_val, &lat_mean_d, &lat_dev_d))
+ lat_unit = "usec";
+
+ lat_num = num2str((unsigned long long)lat_mean_d, ts->sig_figs, 1, 0, N2S_NONE);
+ if (asprintf(&p3, "%s%s", lat_num, lat_unit) < 0)
+ p3 = NULL;
+ free(lat_num);
+ }
+
+ log_buf(out, " steadystate : attained=%s, bw=%s (%s), iops=%s%s%s, %s%s=%.3f%s\n",
ts->ss_state & FIO_SS_ATTAINED ? "yes" : "no",
p1, p1alt, p2,
- ts->ss_state & FIO_SS_IOPS ? "iops" : "bw",
+ p3 ? ", lat=" : "",
+ p3 ? p3 : "",
+ ts->ss_state & FIO_SS_IOPS ? "iops" : (ts->ss_state & FIO_SS_LAT ? "lat" : "bw"),
ts->ss_state & FIO_SS_SLOPE ? " slope": " mean dev",
ts->ss_criterion.u.f,
ts->ss_state & FIO_SS_PCT ? "%" : "");
@@ -960,6 +979,7 @@ static void show_ss_normal(const struct thread_stat *ts, struct buf_output *out)
free(p1);
free(p1alt);
free(p2);
+ free(p3);
}
static void show_agg_stats(const struct disk_util_agg *agg, int terse,
@@ -1903,7 +1923,7 @@ static struct json_object *show_thread_status_json(struct thread_stat *ts,
int intervals = ts->ss_dur / (ss_check_interval / 1000L);
snprintf(ss_buf, sizeof(ss_buf), "%s%s:%f%s",
- ts->ss_state & FIO_SS_IOPS ? "iops" : "bw",
+ ts->ss_state & FIO_SS_IOPS ? "iops" : (ts->ss_state & FIO_SS_LAT ? "lat" : "bw"),
ts->ss_state & FIO_SS_SLOPE ? "_slope" : "",
(float) ts->ss_limit.u.f,
ts->ss_state & FIO_SS_PCT ? "%" : "");
@@ -1942,6 +1962,16 @@ static struct json_object *show_thread_status_json(struct thread_stat *ts,
}
json_object_add_value_int(data, "bw_mean", steadystate_bw_mean(ts));
json_object_add_value_int(data, "iops_mean", steadystate_iops_mean(ts));
+ if (ts->ss_state & FIO_SS_LAT) {
+ struct json_array *lat;
+ lat = json_create_array();
+ for (l = 0; l < intervals; l++) {
+ k = (j + l) % intervals;
+ json_array_add_value_int(lat, ts->ss_lat_data[k]);
+ }
+ json_object_add_value_int(data, "lat_mean", steadystate_lat_mean(ts));
+ json_object_add_value_array(data, "lat_ns", lat);
+ }
json_object_add_value_array(data, "iops", iops);
json_object_add_value_array(data, "bw", bw);
}
@@ -2600,6 +2630,7 @@ void __show_run_stats(void)
ts->ss_head = td->ss.head;
ts->ss_bw_data = td->ss.bw_data;
ts->ss_iops_data = td->ss.iops_data;
+ ts->ss_lat_data = td->ss.lat_data;
ts->ss_limit.u.f = td->ss.limit;
ts->ss_slope.u.f = td->ss.slope;
ts->ss_deviation.u.f = td->ss.deviation;
diff --git a/stat.h b/stat.h
index f40507e3..84ea8445 100644
--- a/stat.h
+++ b/stat.h
@@ -283,6 +283,16 @@ struct thread_stat {
uint64_t pad5;
};
+ union {
+ uint64_t *ss_lat_data;
+ /*
+ * For FIO_NET_CMD_TS, the pointed to data will temporarily
+ * be stored at this offset from the start of the payload.
+ */
+ uint64_t ss_lat_data_offset;
+ uint64_t pad5b;
+ };
+
union {
struct clat_prio_stat *clat_prio[DDIR_RWDIR_CNT];
/*
diff --git a/steadystate.c b/steadystate.c
index 9e47df2c..9e26012d 100644
--- a/steadystate.c
+++ b/steadystate.c
@@ -10,8 +10,10 @@ void steadystate_free(struct thread_data *td)
{
free(td->ss.iops_data);
free(td->ss.bw_data);
+ free(td->ss.lat_data);
td->ss.iops_data = NULL;
td->ss.bw_data = NULL;
+ td->ss.lat_data = NULL;
}
static void steadystate_alloc(struct thread_data *td)
@@ -20,6 +22,7 @@ static void steadystate_alloc(struct thread_data *td)
td->ss.bw_data = calloc(intervals, sizeof(uint64_t));
td->ss.iops_data = calloc(intervals, sizeof(uint64_t));
+ td->ss.lat_data = calloc(intervals, sizeof(uint64_t));
td->ss.state |= FIO_SS_DATA;
}
@@ -60,7 +63,7 @@ void steadystate_setup(void)
steadystate_alloc(prev_td);
}
-static bool steadystate_slope(uint64_t iops, uint64_t bw,
+static bool steadystate_slope(uint64_t iops, uint64_t bw, double lat,
struct thread_data *td)
{
int i, j;
@@ -71,11 +74,14 @@ static bool steadystate_slope(uint64_t iops, uint64_t bw,
ss->bw_data[ss->tail] = bw;
ss->iops_data[ss->tail] = iops;
+ ss->lat_data[ss->tail] = (uint64_t)lat;
if (ss->state & FIO_SS_IOPS)
new_val = iops;
- else
+ else if (ss->state & FIO_SS_BW)
new_val = bw;
+ else
+ new_val = (uint64_t)lat;
if (ss->state & FIO_SS_BUFFER_FULL || ss->tail - ss->head == intervals - 1) {
if (!(ss->state & FIO_SS_BUFFER_FULL)) {
@@ -83,13 +89,17 @@ static bool steadystate_slope(uint64_t iops, uint64_t bw,
for (i = 0, ss->sum_y = 0; i < intervals; i++) {
if (ss->state & FIO_SS_IOPS)
ss->sum_y += ss->iops_data[i];
- else
+ else if (ss->state & FIO_SS_BW)
ss->sum_y += ss->bw_data[i];
+ else
+ ss->sum_y += ss->lat_data[i];
j = (ss->head + i) % intervals;
if (ss->state & FIO_SS_IOPS)
ss->sum_xy += i * ss->iops_data[j];
- else
+ else if (ss->state & FIO_SS_BW)
ss->sum_xy += i * ss->bw_data[j];
+ else
+ ss->sum_xy += i * ss->lat_data[j];
}
ss->state |= FIO_SS_BUFFER_FULL;
} else { /* easy to update the sums */
@@ -100,8 +110,10 @@ static bool steadystate_slope(uint64_t iops, uint64_t bw,
if (ss->state & FIO_SS_IOPS)
ss->oldest_y = ss->iops_data[ss->head];
- else
+ else if (ss->state & FIO_SS_BW)
ss->oldest_y = ss->bw_data[ss->head];
+ else
+ ss->oldest_y = ss->lat_data[ss->head];
/*
* calculate slope as (sum_xy - sum_x * sum_y / n) / (sum_(x^2)
@@ -134,7 +146,7 @@ static bool steadystate_slope(uint64_t iops, uint64_t bw,
return false;
}
-static bool steadystate_deviation(uint64_t iops, uint64_t bw,
+static bool steadystate_deviation(uint64_t iops, uint64_t bw, double lat,
struct thread_data *td)
{
int i;
@@ -146,6 +158,7 @@ static bool steadystate_deviation(uint64_t iops, uint64_t bw,
ss->bw_data[ss->tail] = bw;
ss->iops_data[ss->tail] = iops;
+ ss->lat_data[ss->tail] = (uint64_t)lat;
if (ss->state & FIO_SS_BUFFER_FULL || ss->tail - ss->head == intervals - 1) {
if (!(ss->state & FIO_SS_BUFFER_FULL)) {
@@ -153,22 +166,28 @@ static bool steadystate_deviation(uint64_t iops, uint64_t bw,
for (i = 0, ss->sum_y = 0; i < intervals; i++) {
if (ss->state & FIO_SS_IOPS)
ss->sum_y += ss->iops_data[i];
- else
+ else if (ss->state & FIO_SS_BW)
ss->sum_y += ss->bw_data[i];
+ else
+ ss->sum_y += ss->lat_data[i];
}
ss->state |= FIO_SS_BUFFER_FULL;
} else { /* easy to update the sum */
ss->sum_y -= ss->oldest_y;
if (ss->state & FIO_SS_IOPS)
ss->sum_y += ss->iops_data[ss->tail];
- else
+ else if (ss->state & FIO_SS_BW)
ss->sum_y += ss->bw_data[ss->tail];
+ else
+ ss->sum_y += ss->lat_data[ss->tail];
}
if (ss->state & FIO_SS_IOPS)
ss->oldest_y = ss->iops_data[ss->head];
- else
+ else if (ss->state & FIO_SS_BW)
ss->oldest_y = ss->bw_data[ss->head];
+ else
+ ss->oldest_y = ss->lat_data[ss->head];
mean = (double) ss->sum_y / intervals;
ss->deviation = 0.0;
@@ -176,8 +195,10 @@ static bool steadystate_deviation(uint64_t iops, uint64_t bw,
for (i = 0; i < intervals; i++) {
if (ss->state & FIO_SS_IOPS)
diff = ss->iops_data[i] - mean;
- else
+ else if (ss->state & FIO_SS_BW)
diff = ss->bw_data[i] - mean;
+ else
+ diff = ss->lat_data[i] - mean;
ss->deviation = max(ss->deviation, diff * (diff < 0.0 ? -1.0 : 1.0));
}
@@ -209,13 +230,18 @@ int steadystate_check(void)
unsigned long rate_time;
struct timespec now;
uint64_t group_bw = 0, group_iops = 0;
+ double group_lat_sum = 0.0;
+ uint64_t group_lat_samples = 0;
uint64_t td_iops, td_bytes;
+ double group_lat;
bool ret;
prev_groupid = -1;
for_each_td(td) {
const bool needs_lock = td_async_processing(td);
struct steadystate_data *ss = &td->ss;
+ double td_lat_sum = 0.0;
+ uint64_t td_lat_samples = 0;
if (!ss->dur || td->runstate <= TD_SETTING_UP ||
td->runstate >= TD_EXITED || !ss->state ||
@@ -228,6 +254,8 @@ int steadystate_check(void)
(td->o.group_reporting && td->groupid != prev_groupid)) {
group_bw = 0;
group_iops = 0;
+ group_lat_sum = 0.0;
+ group_lat_samples = 0;
group_ramp_time_over = 0;
}
prev_groupid = td->groupid;
@@ -248,6 +276,9 @@ int steadystate_check(void)
for (ddir = 0; ddir < DDIR_RWDIR_CNT; ddir++) {
td_iops += td->io_blocks[ddir];
td_bytes += td->io_bytes[ddir];
+ td_lat_sum += td->ts.clat_stat[ddir].mean.u.f *
+ td->ts.clat_stat[ddir].samples;
+ td_lat_samples += td->ts.clat_stat[ddir].samples;
}
if (needs_lock)
@@ -261,10 +292,14 @@ int steadystate_check(void)
(ss_check_interval * ss_check_interval / 1000L);
group_iops += rate_time * (td_iops - ss->prev_iops) /
(ss_check_interval * ss_check_interval / 1000L);
+ group_lat_sum += td_lat_sum - ss->prev_lat_sum;
+ group_lat_samples += td_lat_samples - ss->prev_lat_samples;
++group_ramp_time_over;
}
ss->prev_iops = td_iops;
ss->prev_bytes = td_bytes;
+ ss->prev_lat_sum = td_lat_sum;
+ ss->prev_lat_samples = td_lat_samples;
if (td->o.group_reporting && !(ss->state & FIO_SS_DATA))
continue;
@@ -284,10 +319,14 @@ int steadystate_check(void)
(unsigned long long) group_bw,
ss->head, ss->tail);
+ group_lat = 0.0;
+ if (group_lat_samples)
+ group_lat = group_lat_sum / group_lat_samples;
+
if (ss->state & FIO_SS_SLOPE)
- ret = steadystate_slope(group_iops, group_bw, td);
+ ret = steadystate_slope(group_iops, group_bw, group_lat, td);
else
- ret = steadystate_deviation(group_iops, group_bw, td);
+ ret = steadystate_deviation(group_iops, group_bw, group_lat, td);
if (ret) {
if (td->o.group_reporting) {
@@ -353,32 +392,32 @@ int td_steadystate_init(struct thread_data *td)
return 0;
}
-uint64_t steadystate_bw_mean(const struct thread_stat *ts)
+static uint64_t steadystate_data_mean(uint64_t *data, int ss_dur)
{
int i;
uint64_t sum;
- int intervals = ts->ss_dur / (ss_check_interval / 1000L);
-
- if (!ts->ss_dur)
+ int intervals = ss_dur / (ss_check_interval / 1000L);
+
+ if (!ss_dur)
return 0;
for (i = 0, sum = 0; i < intervals; i++)
- sum += ts->ss_bw_data[i];
+ sum += data[i];
return sum / intervals;
}
-uint64_t steadystate_iops_mean(const struct thread_stat *ts)
+uint64_t steadystate_bw_mean(const struct thread_stat *ts)
{
- int i;
- uint64_t sum;
- int intervals = ts->ss_dur / (ss_check_interval / 1000L);
-
- if (!ts->ss_dur)
- return 0;
+ return steadystate_data_mean(ts->ss_bw_data, ts->ss_dur);
+}
- for (i = 0, sum = 0; i < intervals; i++)
- sum += ts->ss_iops_data[i];
+uint64_t steadystate_iops_mean(const struct thread_stat *ts)
+{
+ return steadystate_data_mean(ts->ss_iops_data, ts->ss_dur);
+}
- return sum / intervals;
+uint64_t steadystate_lat_mean(const struct thread_stat *ts)
+{
+ return steadystate_data_mean(ts->ss_lat_data, ts->ss_dur);
}
diff --git a/steadystate.h b/steadystate.h
index e25fd9d0..aff15211 100644
--- a/steadystate.h
+++ b/steadystate.h
@@ -9,6 +9,7 @@ extern void steadystate_setup(void);
extern int td_steadystate_init(struct thread_data *);
extern uint64_t steadystate_bw_mean(const struct thread_stat *);
extern uint64_t steadystate_iops_mean(const struct thread_stat *);
+extern uint64_t steadystate_lat_mean(const struct thread_stat *);
extern bool steadystate_enabled;
extern unsigned int ss_check_interval;
@@ -24,6 +25,7 @@ struct steadystate_data {
unsigned int tail;
uint64_t *iops_data;
uint64_t *bw_data;
+ uint64_t *lat_data;
double slope;
double deviation;
@@ -38,6 +40,8 @@ struct steadystate_data {
struct timespec prev_time;
uint64_t prev_iops;
uint64_t prev_bytes;
+ double prev_lat_sum;
+ uint64_t prev_lat_samples;
};
enum {
@@ -49,6 +53,7 @@ enum {
__FIO_SS_DATA,
__FIO_SS_PCT,
__FIO_SS_BUFFER_FULL,
+ __FIO_SS_LAT,
};
enum {
@@ -60,9 +65,11 @@ enum {
FIO_SS_DATA = 1 << __FIO_SS_DATA,
FIO_SS_PCT = 1 << __FIO_SS_PCT,
FIO_SS_BUFFER_FULL = 1 << __FIO_SS_BUFFER_FULL,
+ FIO_SS_LAT = 1 << __FIO_SS_LAT,
FIO_SS_IOPS_SLOPE = FIO_SS_IOPS | FIO_SS_SLOPE,
FIO_SS_BW_SLOPE = FIO_SS_BW | FIO_SS_SLOPE,
+ FIO_SS_LAT_SLOPE = FIO_SS_LAT | FIO_SS_SLOPE,
};
#endif
diff --git a/t/fiotestlib.py b/t/fiotestlib.py
index 913cb605..2049e41e 100755
--- a/t/fiotestlib.py
+++ b/t/fiotestlib.py
@@ -13,6 +13,7 @@ import os
import sys
import json
import locale
+import shutil
import logging
import platform
import traceback
@@ -473,6 +474,8 @@ def run_fio_tests(test_list, test_env, args):
if test.passed:
result = "PASSED"
passed = passed + 1
+ if hasattr(args, 'cleanup') and args.cleanup:
+ shutil.rmtree(test_env['artifact_root'] + f"/{config['test_id']:04d}", ignore_errors=True)
else:
result = f"FAILED: {test.failure_reason}"
failed = failed + 1
diff --git a/t/run-fio-tests.py b/t/run-fio-tests.py
index 85112878..457d7f8c 100755
--- a/t/run-fio-tests.py
+++ b/t/run-fio-tests.py
@@ -1156,6 +1156,8 @@ def parse_args():
help='pass-through an argument to an executable test')
parser.add_argument('--nvmecdev', action='store', default=None,
help='NVMe character device for **DESTRUCTIVE** testing (e.g., /dev/ng0n1)')
+ parser.add_argument('-c', '--cleanup', action='store_true', default=False,
+ help='Delete artifacts for passing tests')
args = parser.parse_args()
return args
next reply other threads:[~2025-12-19 13:00 UTC|newest]
Thread overview: 1510+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-19 13:00 Jens Axboe [this message]
-- strict thread matches above, loose matches on Subject: below --
2026-05-13 12:00 Recent changes (master) Jens Axboe
2026-05-01 12:00 Jens Axboe
2026-04-29 12:00 Jens Axboe
2026-04-23 12:00 Jens Axboe
2026-04-18 12:00 Jens Axboe
2026-04-17 12:00 Jens Axboe
2026-04-08 12:00 Jens Axboe
2026-04-07 12:00 Jens Axboe
2026-04-02 12:00 Jens Axboe
2026-03-19 12:00 Jens Axboe
2026-03-17 12:00 Jens Axboe
2026-03-11 12:00 Jens Axboe
2026-03-10 12:00 Jens Axboe
2026-03-04 13:00 Jens Axboe
2026-03-03 13:00 Jens Axboe
2026-03-02 13:00 Jens Axboe
2026-02-25 13:00 Jens Axboe
2026-02-14 13:00 Jens Axboe
2026-02-10 13:00 Jens Axboe
2026-02-09 13:00 Jens Axboe
2026-02-06 13:00 Jens Axboe
2026-02-03 13:00 Jens Axboe
2026-01-31 13:00 Jens Axboe
2026-01-28 13:00 Jens Axboe
2026-01-24 13:00 Jens Axboe
2026-01-21 13:00 Jens Axboe
2026-01-17 13:00 Jens Axboe
2026-01-16 13:00 Jens Axboe
2026-01-12 13:00 Jens Axboe
2026-01-08 13:00 Jens Axboe
2025-12-30 13:00 Jens Axboe
2025-12-17 13:00 Jens Axboe
2025-12-14 13:00 Jens Axboe
2025-12-11 13:00 Jens Axboe
2025-12-09 13:00 Jens Axboe
2025-11-25 13:00 Jens Axboe
2025-11-19 13:00 Jens Axboe
2025-11-18 13:00 Jens Axboe
2025-11-15 13:00 Jens Axboe
2025-11-06 13:00 Jens Axboe
2025-11-01 12:00 Jens Axboe
2025-10-31 12:00 Jens Axboe
2025-10-30 12:00 Jens Axboe
2025-10-29 12:00 Jens Axboe
2025-10-16 12:00 Jens Axboe
2025-10-11 12:00 Jens Axboe
2025-10-10 12:00 Jens Axboe
2025-10-09 12:00 Jens Axboe
2025-10-06 12:00 Jens Axboe
2025-10-05 12:00 Jens Axboe
2025-10-02 12:00 Jens Axboe
2025-09-26 12:00 Jens Axboe
2025-09-24 12:00 Jens Axboe
2025-09-19 12:00 Jens Axboe
2025-09-18 12:00 Jens Axboe
2025-09-17 12:00 Jens Axboe
2025-09-09 12:00 Jens Axboe
2025-09-06 12:00 Jens Axboe
2025-09-05 12:00 Jens Axboe
2025-09-04 12:00 Jens Axboe
2025-08-27 12:00 Jens Axboe
2025-08-26 12:00 Jens Axboe
2025-08-23 12:00 Jens Axboe
2025-08-22 12:00 Jens Axboe
2025-08-21 12:00 Jens Axboe
2025-08-20 12:00 Jens Axboe
2025-08-19 12:00 Jens Axboe
2025-08-12 12:00 Jens Axboe
2025-08-10 12:00 Jens Axboe
2025-08-08 12:00 Jens Axboe
2025-08-06 12:00 Jens Axboe
2025-08-03 12:00 Jens Axboe
2025-08-01 12:00 Jens Axboe
2025-07-24 12:00 Jens Axboe
2025-07-23 12:00 Jens Axboe
2025-07-19 12:00 Jens Axboe
2025-07-17 12:00 Jens Axboe
2025-07-10 12:00 Jens Axboe
2025-07-09 12:00 Jens Axboe
2025-07-01 12:00 Jens Axboe
2025-06-24 12:00 Jens Axboe
2025-06-05 12:00 Jens Axboe
2025-06-03 12:00 Jens Axboe
2025-06-01 12:00 Jens Axboe
2025-05-24 12:00 Jens Axboe
2025-05-21 12:00 Jens Axboe
2025-05-17 12:00 Jens Axboe
2025-05-14 12:00 Jens Axboe
2025-05-10 12:00 Jens Axboe
2025-05-09 12:00 Jens Axboe
2025-05-08 12:00 Jens Axboe
2025-05-07 12:00 Jens Axboe
2025-04-16 12:00 Jens Axboe
2025-04-15 12:00 Jens Axboe
2025-04-08 12:00 Jens Axboe
2025-04-05 12:00 Jens Axboe
2025-03-20 12:00 Jens Axboe
2025-03-19 12:00 Jens Axboe
2025-03-08 13:00 Jens Axboe
2025-03-07 13:00 Jens Axboe
2025-03-06 13:00 Jens Axboe
2025-02-21 13:00 Jens Axboe
2025-02-19 13:00 Jens Axboe
2025-02-18 13:00 Jens Axboe
2025-02-15 13:00 Jens Axboe
2025-02-14 13:00 Jens Axboe
2025-01-31 13:00 Jens Axboe
2025-01-24 13:00 Jens Axboe
2025-01-23 13:00 Jens Axboe
2025-01-22 13:00 Jens Axboe
2024-12-17 13:00 Jens Axboe
2024-12-10 13:00 Jens Axboe
2024-12-05 13:00 Jens Axboe
2024-11-23 13:00 Jens Axboe
2024-11-06 13:00 Jens Axboe
2024-11-05 13:00 Jens Axboe
2024-10-29 12:00 Jens Axboe
2024-10-17 12:00 Jens Axboe
2024-10-09 12:00 Jens Axboe
2024-10-04 12:00 Jens Axboe
2024-10-03 12:00 Jens Axboe
2024-10-01 12:00 Jens Axboe
2024-09-28 12:00 Jens Axboe
2024-09-27 12:00 Jens Axboe
2024-09-17 12:00 Jens Axboe
2024-09-07 12:00 Jens Axboe
2024-09-06 12:00 Jens Axboe
2024-09-05 12:00 Jens Axboe
2024-09-04 12:00 Jens Axboe
2024-08-30 12:00 Jens Axboe
2024-08-29 12:00 Jens Axboe
2024-08-22 12:00 Jens Axboe
2024-08-17 12:00 Jens Axboe
2024-08-07 12:00 Jens Axboe
2024-08-06 12:00 Jens Axboe
2024-07-27 12:00 Jens Axboe
2024-07-18 12:00 Jens Axboe
2024-07-16 12:00 Jens Axboe
2024-07-13 12:00 Jens Axboe
2024-07-12 12:00 Jens Axboe
2024-06-29 12:00 Jens Axboe
2024-06-15 12:00 Jens Axboe
2024-06-13 12:00 Jens Axboe
2024-06-13 12:00 Jens Axboe
2024-06-12 12:00 Jens Axboe
2024-06-08 12:00 Jens Axboe
2024-06-07 12:00 Jens Axboe
2024-06-05 12:00 Jens Axboe
2024-06-04 12:00 Jens Axboe
2024-06-04 12:11 ` Niklas Cassel
2024-06-04 12:53 ` Vincent Fu
2024-06-01 12:00 Jens Axboe
2024-05-29 12:00 Jens Axboe
2024-05-25 12:00 Jens Axboe
2024-05-22 12:00 Jens Axboe
2024-05-01 12:00 Jens Axboe
2024-04-26 12:00 Jens Axboe
2024-04-25 12:00 Jens Axboe
2024-04-20 12:00 Jens Axboe
2024-04-19 12:00 Jens Axboe
2024-04-18 12:00 Jens Axboe
2024-04-17 12:00 Jens Axboe
2024-04-16 12:00 Jens Axboe
2024-04-03 12:00 Jens Axboe
2024-03-27 12:00 Jens Axboe
2024-03-26 12:00 Jens Axboe
2024-03-23 12:00 Jens Axboe
2024-03-22 12:00 Jens Axboe
2024-03-21 12:00 Jens Axboe
2024-03-19 12:00 Jens Axboe
2024-03-08 13:00 Jens Axboe
2024-03-06 13:00 Jens Axboe
2024-03-05 13:00 Jens Axboe
2024-02-28 13:00 Jens Axboe
2024-02-23 13:00 Jens Axboe
2024-02-17 13:00 Jens Axboe
2024-02-16 13:00 Jens Axboe
2024-02-15 13:00 Jens Axboe
2024-02-14 13:00 Jens Axboe
2024-02-13 13:00 Jens Axboe
2024-02-09 13:00 Jens Axboe
2024-02-08 13:00 Jens Axboe
2024-01-28 13:00 Jens Axboe
2024-01-26 13:00 Jens Axboe
2024-01-25 13:00 Jens Axboe
2024-01-24 13:00 Jens Axboe
2024-01-23 13:00 Jens Axboe
2024-01-19 13:00 Jens Axboe
2024-01-18 13:00 Jens Axboe
2024-01-18 13:00 Jens Axboe
2024-01-17 13:00 Jens Axboe
2023-12-30 13:00 Jens Axboe
2023-12-20 13:00 Jens Axboe
2023-12-16 13:00 Jens Axboe
2023-12-15 13:00 Jens Axboe
2023-12-13 13:00 Jens Axboe
2023-12-12 13:00 Jens Axboe
2023-11-20 13:00 Jens Axboe
2023-11-08 13:00 Jens Axboe
2023-11-07 13:00 Jens Axboe
2023-11-04 12:00 Jens Axboe
2023-11-03 12:00 Jens Axboe
2023-11-01 12:00 Jens Axboe
2023-10-26 12:00 Jens Axboe
2023-10-24 12:00 Jens Axboe
2023-10-23 12:00 Jens Axboe
2023-10-20 12:00 Jens Axboe
2023-10-17 12:00 Jens Axboe
2023-10-14 12:00 Jens Axboe
2023-10-07 12:00 Jens Axboe
2023-10-03 12:00 Jens Axboe
2023-09-30 12:00 Jens Axboe
2023-09-29 12:00 Jens Axboe
2023-09-27 12:00 Jens Axboe
2023-09-20 12:00 Jens Axboe
2023-09-16 12:00 Jens Axboe
2023-09-12 12:00 Jens Axboe
2023-09-03 12:00 Jens Axboe
2023-08-24 12:00 Jens Axboe
2023-08-17 12:00 Jens Axboe
2023-08-15 12:00 Jens Axboe
2023-08-04 12:00 Jens Axboe
2023-08-03 12:00 Jens Axboe
2023-08-01 12:00 Jens Axboe
2023-07-29 12:00 Jens Axboe
2023-07-28 12:00 Jens Axboe
2023-07-22 12:00 Jens Axboe
2023-07-21 12:00 Jens Axboe
2023-07-16 12:00 Jens Axboe
2023-07-15 12:00 Jens Axboe
2023-07-14 12:00 Jens Axboe
2023-07-06 12:00 Jens Axboe
2023-07-04 12:00 Jens Axboe
2023-06-22 12:00 Jens Axboe
2023-06-17 12:00 Jens Axboe
2023-06-10 12:00 Jens Axboe
2023-06-09 12:00 Jens Axboe
2023-06-02 12:00 Jens Axboe
2023-05-31 12:00 Jens Axboe
2023-05-25 12:00 Jens Axboe
2023-05-24 12:00 Jens Axboe
2023-05-20 12:00 Jens Axboe
2023-05-19 12:00 Jens Axboe
2023-05-18 12:00 Jens Axboe
2023-05-17 12:00 Jens Axboe
2023-05-16 12:00 Jens Axboe
2023-05-12 12:00 Jens Axboe
2023-05-11 12:00 Jens Axboe
2023-04-28 12:00 Jens Axboe
2023-04-27 12:00 Jens Axboe
2023-04-21 12:00 Jens Axboe
2023-04-14 12:00 Jens Axboe
2023-04-11 12:00 Jens Axboe
2023-04-08 12:00 Jens Axboe
2023-04-05 12:00 Jens Axboe
2023-04-01 12:00 Jens Axboe
2023-03-28 12:00 Jens Axboe
2023-03-22 12:00 Jens Axboe
2023-03-21 12:00 Jens Axboe
2023-03-16 12:00 Jens Axboe
2023-03-15 12:00 Jens Axboe
2023-03-08 13:00 Jens Axboe
2023-03-04 13:00 Jens Axboe
2023-03-03 13:00 Jens Axboe
2023-03-01 13:00 Jens Axboe
2023-02-28 13:00 Jens Axboe
2023-02-24 13:00 Jens Axboe
2023-02-22 13:00 Jens Axboe
2023-02-21 13:00 Jens Axboe
2023-02-18 13:00 Jens Axboe
2023-02-16 13:00 Jens Axboe
2023-02-15 13:00 Jens Axboe
2023-02-11 13:00 Jens Axboe
2023-02-10 13:00 Jens Axboe
2023-02-08 13:00 Jens Axboe
2023-02-07 13:00 Jens Axboe
2023-02-04 13:00 Jens Axboe
2023-02-01 13:00 Jens Axboe
2023-01-31 13:00 Jens Axboe
2023-01-26 13:00 Jens Axboe
2023-01-25 13:00 Jens Axboe
2023-01-24 13:00 Jens Axboe
2023-01-21 13:00 Jens Axboe
2023-01-19 13:00 Jens Axboe
2023-01-12 13:00 Jens Axboe
2022-12-23 13:00 Jens Axboe
2022-12-17 13:00 Jens Axboe
2022-12-16 13:00 Jens Axboe
2022-12-13 13:00 Jens Axboe
2022-12-03 13:00 Jens Axboe
2022-12-02 13:00 Jens Axboe
2022-12-01 13:00 Jens Axboe
2022-11-30 13:00 Jens Axboe
2022-11-29 13:00 Jens Axboe
2022-11-24 13:00 Jens Axboe
2022-11-19 13:00 Jens Axboe
2022-11-15 13:00 Jens Axboe
2022-11-08 13:00 Jens Axboe
2022-11-07 13:00 Jens Axboe
2022-11-05 12:00 Jens Axboe
2022-11-03 12:00 Jens Axboe
2022-11-02 12:00 Jens Axboe
2022-10-25 12:00 Jens Axboe
2022-10-22 12:00 Jens Axboe
2022-10-20 12:00 Jens Axboe
2022-10-19 12:00 Jens Axboe
2022-10-17 12:00 Jens Axboe
2022-10-16 12:00 Jens Axboe
2022-10-15 12:00 Jens Axboe
2022-10-08 12:00 Jens Axboe
2022-10-06 12:00 Jens Axboe
2022-10-05 12:00 Jens Axboe
2022-10-04 12:00 Jens Axboe
2022-09-29 12:00 Jens Axboe
2022-09-23 12:00 Jens Axboe
2022-09-20 12:00 Jens Axboe
2022-09-16 12:00 Jens Axboe
2022-09-14 12:00 Jens Axboe
2022-09-13 12:00 Jens Axboe
2022-09-07 12:00 Jens Axboe
2022-09-04 12:00 Jens Axboe
2022-09-03 12:00 Jens Axboe
2022-09-02 12:00 Jens Axboe
2022-09-01 12:00 Jens Axboe
2022-08-31 12:00 Jens Axboe
2022-08-30 12:00 Jens Axboe
2022-08-27 12:00 Jens Axboe
2022-08-26 12:00 Jens Axboe
2022-08-25 12:00 Jens Axboe
2022-08-24 12:00 Jens Axboe
2022-08-17 12:00 Jens Axboe
2022-08-16 12:00 Jens Axboe
2022-08-12 12:00 Jens Axboe
2022-08-11 12:00 Jens Axboe
2022-08-10 12:00 Jens Axboe
2022-08-08 12:00 Jens Axboe
2022-08-04 12:00 Jens Axboe
2022-08-03 12:00 Jens Axboe
2022-08-01 12:00 Jens Axboe
2022-07-29 12:00 Jens Axboe
2022-07-28 12:00 Jens Axboe
2022-07-23 12:00 Jens Axboe
2022-07-22 12:00 Jens Axboe
2022-07-20 12:00 Jens Axboe
2022-07-12 12:00 Jens Axboe
2022-07-08 12:00 Jens Axboe
2022-07-07 12:00 Jens Axboe
2022-07-06 12:00 Jens Axboe
2022-07-02 12:00 Jens Axboe
2022-06-24 12:00 Jens Axboe
2022-06-23 12:00 Jens Axboe
2022-06-20 12:00 Jens Axboe
2022-06-16 12:00 Jens Axboe
2022-06-14 12:00 Jens Axboe
2022-06-02 12:00 Jens Axboe
2022-06-01 12:00 Jens Axboe
2022-05-30 12:00 Jens Axboe
2022-05-26 12:00 Jens Axboe
2022-05-13 12:00 Jens Axboe
2022-05-02 12:00 Jens Axboe
2022-04-30 12:00 Jens Axboe
2022-04-18 12:00 Jens Axboe
2022-04-11 12:00 Jens Axboe
2022-04-09 12:00 Jens Axboe
2022-04-07 12:00 Jens Axboe
2022-04-06 12:00 Jens Axboe
2022-03-31 12:00 Jens Axboe
2022-03-30 12:00 Jens Axboe
2022-03-29 12:00 Jens Axboe
2022-03-25 12:00 Jens Axboe
2022-03-21 12:00 Jens Axboe
2022-03-16 12:00 Jens Axboe
2022-03-12 13:00 Jens Axboe
2022-03-11 13:00 Jens Axboe
2022-03-10 13:00 Jens Axboe
2022-03-09 13:00 Jens Axboe
2022-03-08 13:00 Jens Axboe
2022-02-27 13:00 Jens Axboe
2022-02-25 13:00 Jens Axboe
2022-02-22 13:00 Jens Axboe
2022-02-21 13:00 Jens Axboe
2022-02-19 13:00 Jens Axboe
2022-02-18 13:00 Jens Axboe
2022-02-16 13:00 Jens Axboe
2022-02-12 13:00 Jens Axboe
2022-02-09 13:00 Jens Axboe
2022-02-05 13:00 Jens Axboe
2022-02-04 13:00 Jens Axboe
2022-01-29 13:00 Jens Axboe
2022-01-27 13:00 Jens Axboe
2022-01-22 13:00 Jens Axboe
2022-01-21 13:00 Jens Axboe
2022-01-19 13:00 Jens Axboe
2022-01-18 13:00 Jens Axboe
2022-01-11 13:00 Jens Axboe
2022-01-10 13:00 Jens Axboe
2021-12-24 13:00 Jens Axboe
2021-12-19 13:00 Jens Axboe
2021-12-16 13:00 Jens Axboe
2021-12-15 13:00 Jens Axboe
2021-12-11 13:00 Jens Axboe
2021-12-10 13:00 Jens Axboe
2021-12-07 13:00 Jens Axboe
2021-12-03 13:00 Jens Axboe
2021-11-26 13:00 Jens Axboe
2021-11-25 13:00 Jens Axboe
2021-11-22 13:00 Jens Axboe
2021-11-21 13:00 Jens Axboe
2021-11-20 13:00 Jens Axboe
2021-11-18 13:00 Jens Axboe
2021-11-13 13:00 Jens Axboe
2021-11-11 13:00 Jens Axboe
2021-10-26 12:00 Jens Axboe
2021-10-23 12:00 Jens Axboe
2021-10-25 15:37 ` Rebecca Cran
2021-10-25 15:41 ` Jens Axboe
2021-10-25 15:42 ` Rebecca Cran
2021-10-25 15:43 ` Jens Axboe
2021-10-20 12:00 Jens Axboe
2021-10-19 12:00 Jens Axboe
2021-10-18 12:00 Jens Axboe
2021-10-16 12:00 Jens Axboe
2021-10-15 12:00 Jens Axboe
2021-10-14 12:00 Jens Axboe
2021-10-13 12:00 Jens Axboe
2021-10-12 12:00 Jens Axboe
2021-10-10 12:00 Jens Axboe
2021-10-08 12:00 Jens Axboe
2021-10-06 12:00 Jens Axboe
2021-10-05 12:00 Jens Axboe
2021-10-02 12:00 Jens Axboe
2021-10-01 12:00 Jens Axboe
2021-09-30 12:00 Jens Axboe
2021-09-29 12:00 Jens Axboe
2021-09-27 12:00 Jens Axboe
2021-09-26 12:00 Jens Axboe
2021-09-25 12:00 Jens Axboe
2021-09-24 12:00 Jens Axboe
2021-09-21 12:00 Jens Axboe
2021-09-17 12:00 Jens Axboe
2021-09-16 12:00 Jens Axboe
2021-09-14 12:00 Jens Axboe
2021-09-09 12:00 Jens Axboe
2021-09-06 12:00 Jens Axboe
2021-09-04 12:00 Jens Axboe
2021-09-04 12:00 ` Jens Axboe
2021-09-03 12:00 Jens Axboe
2021-08-29 12:00 Jens Axboe
2021-08-28 12:00 Jens Axboe
2021-08-27 12:00 Jens Axboe
2021-08-21 12:00 Jens Axboe
2021-08-19 12:00 Jens Axboe
2021-08-14 12:00 Jens Axboe
2021-08-12 12:00 Jens Axboe
2021-08-07 12:00 Jens Axboe
2021-08-05 12:00 Jens Axboe
2021-08-04 12:00 Jens Axboe
2021-08-03 12:00 Jens Axboe
2021-08-02 12:00 Jens Axboe
2021-07-29 12:00 Jens Axboe
2021-07-26 12:00 Jens Axboe
2021-07-16 12:00 Jens Axboe
2021-07-08 12:00 Jens Axboe
2021-07-02 12:00 Jens Axboe
2021-06-30 12:00 Jens Axboe
2021-06-21 12:00 Jens Axboe
2021-06-18 12:00 Jens Axboe
2021-06-15 12:00 Jens Axboe
2021-06-11 12:00 Jens Axboe
2021-06-09 12:00 Jens Axboe
2021-06-04 12:00 Jens Axboe
2021-05-28 12:00 Jens Axboe
2021-05-27 12:00 Jens Axboe
2021-05-26 12:00 Jens Axboe
2021-05-19 12:00 Jens Axboe
2021-05-15 12:00 Jens Axboe
2021-05-12 12:00 Jens Axboe
2021-05-11 12:00 Jens Axboe
2021-05-09 12:00 Jens Axboe
2021-05-07 12:00 Jens Axboe
2021-04-28 12:00 Jens Axboe
2021-04-26 12:00 Jens Axboe
2021-04-24 12:00 Jens Axboe
2021-04-23 12:00 Jens Axboe
2021-04-17 12:00 Jens Axboe
2021-04-16 12:00 Jens Axboe
2021-04-14 12:00 Jens Axboe
2021-04-13 12:00 Jens Axboe
2021-04-11 12:00 Jens Axboe
2021-03-31 12:00 Jens Axboe
2021-03-19 12:00 Jens Axboe
2021-03-18 12:00 Jens Axboe
2021-03-12 13:00 Jens Axboe
2021-03-11 13:00 Jens Axboe
2021-03-10 13:00 Jens Axboe
2021-03-09 13:00 Jens Axboe
2021-03-07 13:00 Jens Axboe
2021-02-22 13:00 Jens Axboe
2021-02-17 13:00 Jens Axboe
2021-02-15 13:00 Jens Axboe
2021-02-11 13:00 Jens Axboe
2021-01-30 13:00 Jens Axboe
2021-01-28 13:00 Jens Axboe
2021-01-27 13:00 Jens Axboe
2021-01-26 13:00 Jens Axboe
2021-01-24 13:00 Jens Axboe
2021-01-17 13:00 Jens Axboe
2021-01-16 13:00 Jens Axboe
2021-01-13 13:00 Jens Axboe
2021-01-10 13:00 Jens Axboe
2021-01-08 13:00 Jens Axboe
2021-01-07 13:00 Jens Axboe
2021-01-06 13:00 Jens Axboe
2020-12-30 13:00 Jens Axboe
2020-12-25 13:00 Jens Axboe
2020-12-18 13:00 Jens Axboe
2020-12-16 13:00 Jens Axboe
2020-12-08 13:00 Jens Axboe
2020-12-06 13:00 Jens Axboe
2020-12-05 13:00 Jens Axboe
2020-12-04 13:00 Jens Axboe
2020-11-28 13:00 Jens Axboe
2020-11-26 13:00 Jens Axboe
2020-11-23 13:00 Jens Axboe
2020-11-14 13:00 Jens Axboe
2020-11-13 13:00 Jens Axboe
2020-11-10 13:00 Jens Axboe
2020-11-06 13:00 Jens Axboe
2020-11-12 20:51 ` Rebecca Cran
2020-11-05 13:00 Jens Axboe
2020-11-02 13:00 Jens Axboe
2020-10-31 12:00 Jens Axboe
2020-10-29 12:00 Jens Axboe
2020-10-15 12:00 Jens Axboe
2020-10-14 12:00 Jens Axboe
2020-10-11 12:00 Jens Axboe
2020-10-10 12:00 Jens Axboe
2020-09-15 12:00 Jens Axboe
2020-09-12 12:00 Jens Axboe
2020-09-10 12:00 Jens Axboe
2020-09-09 12:00 Jens Axboe
2020-09-08 12:00 Jens Axboe
2020-09-07 12:00 Jens Axboe
2020-09-06 12:00 Jens Axboe
2020-09-04 12:00 Jens Axboe
2020-09-02 12:00 Jens Axboe
2020-09-01 12:00 Jens Axboe
2020-08-30 12:00 Jens Axboe
2020-08-29 12:00 Jens Axboe
2020-08-28 12:00 Jens Axboe
2020-08-23 12:00 Jens Axboe
2020-08-22 12:00 Jens Axboe
2020-08-20 12:00 Jens Axboe
2020-08-19 12:00 Jens Axboe
2020-08-18 12:00 Jens Axboe
2020-08-17 12:00 Jens Axboe
2020-08-15 12:00 Jens Axboe
2020-08-14 12:00 Jens Axboe
2020-08-13 12:00 Jens Axboe
2020-08-12 12:00 Jens Axboe
2020-08-11 12:00 Jens Axboe
2020-08-08 12:00 Jens Axboe
2020-08-02 12:00 Jens Axboe
2020-07-28 12:00 Jens Axboe
2020-07-27 12:00 Jens Axboe
2020-07-26 12:00 Jens Axboe
2020-07-25 12:00 Jens Axboe
2020-07-22 12:00 Jens Axboe
2020-07-21 12:00 Jens Axboe
2020-07-19 12:00 Jens Axboe
2020-07-18 12:00 Jens Axboe
2020-07-15 12:00 Jens Axboe
2020-07-14 12:00 Jens Axboe
2020-07-09 12:00 Jens Axboe
2020-07-05 12:00 Jens Axboe
2020-07-04 12:00 Jens Axboe
2020-07-03 12:00 Jens Axboe
2020-06-29 12:00 Jens Axboe
2020-06-25 12:00 Jens Axboe
2020-06-24 12:00 Jens Axboe
2020-06-22 12:00 Jens Axboe
2020-06-13 12:00 Jens Axboe
2020-06-10 12:00 Jens Axboe
2020-06-08 12:00 Jens Axboe
2020-06-06 12:00 Jens Axboe
2020-06-04 12:00 Jens Axboe
2020-06-03 12:00 Jens Axboe
2020-05-30 12:00 Jens Axboe
2020-05-29 12:00 Jens Axboe
2020-05-26 12:00 Jens Axboe
2020-05-25 12:00 Jens Axboe
2020-05-24 12:00 Jens Axboe
2020-05-22 12:00 Jens Axboe
2020-05-21 12:00 Jens Axboe
2020-05-20 12:00 Jens Axboe
2020-05-19 12:00 Jens Axboe
2020-05-15 12:00 Jens Axboe
2020-05-14 12:00 Jens Axboe
2020-05-12 12:00 Jens Axboe
2020-04-30 12:00 Jens Axboe
2020-04-22 12:00 Jens Axboe
2020-04-21 12:00 Jens Axboe
2020-04-18 12:00 Jens Axboe
2020-04-17 12:00 Jens Axboe
2020-04-16 12:00 Jens Axboe
2020-04-14 12:00 Jens Axboe
2020-04-09 12:00 Jens Axboe
2020-04-08 12:00 Jens Axboe
2020-04-07 12:00 Jens Axboe
2020-04-03 12:00 Jens Axboe
2020-04-01 12:00 Jens Axboe
2020-03-27 12:00 Jens Axboe
2020-03-18 12:00 Jens Axboe
2020-03-17 12:00 Jens Axboe
2020-03-16 12:00 Jens Axboe
2020-03-13 12:00 Jens Axboe
2020-03-04 13:00 Jens Axboe
2020-03-03 13:00 Jens Axboe
2020-03-02 13:00 Jens Axboe
2020-02-27 13:00 Jens Axboe
2020-02-25 13:00 Jens Axboe
2020-02-07 13:00 Jens Axboe
2020-02-06 13:00 Jens Axboe
2020-02-05 13:00 Jens Axboe
2020-01-29 13:00 Jens Axboe
2020-01-24 13:00 Jens Axboe
2020-01-23 13:00 Jens Axboe
2020-01-19 13:00 Jens Axboe
2020-01-17 13:00 Jens Axboe
2020-01-15 13:00 Jens Axboe
2020-01-14 13:00 Jens Axboe
2020-01-10 13:00 Jens Axboe
2020-01-07 13:00 Jens Axboe
2020-01-06 13:00 Jens Axboe
2020-01-05 13:00 Jens Axboe
2020-01-04 13:00 Jens Axboe
2019-12-26 13:00 Jens Axboe
2019-12-24 13:00 Jens Axboe
2019-12-22 13:00 Jens Axboe
2019-12-19 13:00 Jens Axboe
2019-12-17 13:00 Jens Axboe
2019-12-12 13:00 Jens Axboe
2019-12-07 13:00 Jens Axboe
2019-11-28 13:00 Jens Axboe
2019-11-27 13:00 Jens Axboe
2019-11-26 13:00 Jens Axboe
2019-11-15 13:00 Jens Axboe
2019-11-07 15:25 Jens Axboe
2019-11-07 13:00 Jens Axboe
2019-11-06 13:00 Jens Axboe
2019-11-04 13:00 Jens Axboe
2019-11-03 13:00 Jens Axboe
2019-10-30 12:00 Jens Axboe
2019-10-25 12:00 Jens Axboe
2019-10-22 12:00 Jens Axboe
2019-10-16 12:00 Jens Axboe
2019-10-15 12:00 Jens Axboe
2019-10-14 12:00 Jens Axboe
2019-10-09 12:00 Jens Axboe
2019-10-08 12:00 Jens Axboe
2019-10-07 12:00 Jens Axboe
2019-10-03 12:00 Jens Axboe
2019-10-02 12:00 Jens Axboe
2019-09-28 12:00 Jens Axboe
2019-09-26 12:00 Jens Axboe
2019-09-25 12:00 Jens Axboe
2019-09-24 12:00 Jens Axboe
2019-09-20 12:00 Jens Axboe
2019-09-14 12:00 Jens Axboe
2019-09-13 12:00 Jens Axboe
2019-09-06 12:00 Jens Axboe
2019-09-04 12:00 Jens Axboe
2019-08-30 12:00 Jens Axboe
2019-08-29 12:00 Jens Axboe
2019-08-16 12:00 Jens Axboe
2019-08-15 12:00 Jens Axboe
2019-08-15 14:27 ` Rebecca Cran
2019-08-15 14:28 ` Jens Axboe
2019-08-15 15:05 ` Rebecca Cran
2019-08-15 15:17 ` Jens Axboe
2019-08-15 15:35 ` Rebecca Cran
2019-08-09 12:00 Jens Axboe
2019-08-06 12:00 Jens Axboe
2019-08-04 12:00 Jens Axboe
2019-08-03 12:00 Jens Axboe
2019-08-01 12:00 Jens Axboe
2019-07-27 12:00 Jens Axboe
2019-07-13 12:00 Jens Axboe
2019-07-10 12:00 Jens Axboe
2019-07-02 12:00 Jens Axboe
2019-06-01 12:00 Jens Axboe
2019-05-24 12:00 Jens Axboe
2019-05-23 12:00 Jens Axboe
2019-05-21 12:00 Jens Axboe
2019-05-17 12:00 Jens Axboe
2019-05-10 12:00 Jens Axboe
2019-05-09 12:00 Jens Axboe
2019-05-09 12:47 ` Erwan Velu
2019-05-09 14:07 ` Jens Axboe
2019-05-09 15:47 ` Elliott, Robert (Servers)
2019-05-09 15:52 ` Sebastien Boisvert
2019-05-09 16:12 ` Elliott, Robert (Servers)
2019-05-09 15:57 ` Jens Axboe
2019-05-07 12:00 Jens Axboe
2019-04-26 12:00 Jens Axboe
2019-04-23 12:00 Jens Axboe
2019-04-20 12:00 Jens Axboe
2019-04-19 12:00 Jens Axboe
2019-04-18 12:00 Jens Axboe
2019-04-02 12:00 Jens Axboe
2019-03-26 12:00 Jens Axboe
2019-03-22 12:00 Jens Axboe
2019-03-12 12:00 Jens Axboe
2019-03-09 13:00 Jens Axboe
2019-03-08 13:00 Jens Axboe
2019-03-07 13:00 Jens Axboe
2019-03-01 13:00 Jens Axboe
2019-02-25 13:00 Jens Axboe
2019-02-24 13:00 Jens Axboe
2019-02-22 13:00 Jens Axboe
2019-02-12 13:00 Jens Axboe
2019-02-11 13:00 Jens Axboe
2019-02-09 13:00 Jens Axboe
2019-02-08 13:00 Jens Axboe
2019-02-05 13:00 Jens Axboe
2019-02-01 13:00 Jens Axboe
2019-01-30 13:00 Jens Axboe
2019-01-29 13:00 Jens Axboe
2019-01-25 13:00 Jens Axboe
2019-01-24 13:00 Jens Axboe
2019-01-17 13:00 Jens Axboe
2019-01-16 13:00 Jens Axboe
2019-01-15 13:00 Jens Axboe
2019-01-14 13:00 Jens Axboe
2019-01-13 13:00 Jens Axboe
2019-01-12 13:00 Jens Axboe
2019-01-11 13:00 Jens Axboe
2019-01-10 13:00 Jens Axboe
2019-01-09 13:00 Jens Axboe
2019-01-08 13:00 Jens Axboe
2019-01-06 13:00 Jens Axboe
2019-01-05 13:00 Jens Axboe
2018-12-31 13:00 Jens Axboe
2018-12-22 13:00 Jens Axboe
2018-12-20 13:00 Jens Axboe
2018-12-15 13:00 Jens Axboe
2018-12-14 13:00 Jens Axboe
2018-12-13 13:00 Jens Axboe
2018-12-11 13:00 Jens Axboe
2018-12-05 13:00 Jens Axboe
2018-12-02 13:00 Jens Axboe
2018-12-01 13:00 Jens Axboe
2018-11-30 13:00 Jens Axboe
2018-11-28 13:00 Jens Axboe
2018-11-27 13:00 Jens Axboe
2018-11-26 13:00 Jens Axboe
2018-11-25 13:00 Jens Axboe
2018-11-22 13:00 Jens Axboe
2018-11-21 13:00 Jens Axboe
2018-11-20 13:00 Jens Axboe
2018-11-16 13:00 Jens Axboe
2018-11-07 13:00 Jens Axboe
2018-11-03 12:00 Jens Axboe
2018-10-27 12:00 Jens Axboe
2018-10-24 12:00 Jens Axboe
2018-10-20 12:00 Jens Axboe
2018-10-19 12:00 Jens Axboe
2018-10-16 12:00 Jens Axboe
2018-10-09 12:00 Jens Axboe
2018-10-06 12:00 Jens Axboe
2018-10-05 12:00 Jens Axboe
2018-10-04 12:00 Jens Axboe
2018-10-02 12:00 Jens Axboe
2018-10-01 12:00 Jens Axboe
2018-09-30 12:00 Jens Axboe
2018-09-28 12:00 Jens Axboe
2018-09-27 12:00 Jens Axboe
2018-09-26 12:00 Jens Axboe
2018-09-23 12:00 Jens Axboe
2018-09-22 12:00 Jens Axboe
2018-09-21 12:00 Jens Axboe
2018-09-20 12:00 Jens Axboe
2018-09-18 12:00 Jens Axboe
2018-09-17 12:00 Jens Axboe
2018-09-13 12:00 Jens Axboe
2018-09-12 12:00 Jens Axboe
2018-09-11 12:00 Jens Axboe
2018-09-10 12:00 Jens Axboe
2018-09-09 12:00 Jens Axboe
2018-09-08 12:00 Jens Axboe
2018-09-07 12:00 Jens Axboe
2018-09-06 12:00 Jens Axboe
2018-09-04 12:00 Jens Axboe
2018-09-01 12:00 Jens Axboe
2018-08-31 12:00 Jens Axboe
2018-08-26 12:00 Jens Axboe
2018-08-25 12:00 Jens Axboe
2018-08-24 12:00 Jens Axboe
2018-08-23 12:00 Jens Axboe
2018-08-22 12:00 Jens Axboe
2018-08-21 12:00 Jens Axboe
2018-08-18 12:00 Jens Axboe
2018-08-17 12:00 Jens Axboe
2018-08-16 12:00 Jens Axboe
2018-08-15 12:00 Jens Axboe
2018-08-14 12:00 Jens Axboe
2018-08-13 12:00 Jens Axboe
2018-08-11 12:00 Jens Axboe
2018-08-10 12:00 Jens Axboe
2018-08-08 12:00 Jens Axboe
2018-08-06 12:00 Jens Axboe
2018-08-04 12:00 Jens Axboe
2018-08-03 12:00 Jens Axboe
2018-07-31 12:00 Jens Axboe
2018-07-27 12:00 Jens Axboe
2018-07-26 12:00 Jens Axboe
2018-07-25 12:00 Jens Axboe
2018-07-24 12:00 Jens Axboe
2018-07-13 12:00 Jens Axboe
2018-07-12 12:00 Jens Axboe
2018-07-11 12:00 Jens Axboe
2018-07-05 12:00 Jens Axboe
2018-06-30 12:00 Jens Axboe
2018-06-22 12:00 Jens Axboe
2018-06-19 12:00 Jens Axboe
2018-06-16 12:00 Jens Axboe
2018-06-13 12:00 Jens Axboe
2018-06-12 12:00 Jens Axboe
2018-06-09 12:00 Jens Axboe
2018-06-08 12:00 Jens Axboe
2018-06-06 12:00 Jens Axboe
2018-06-05 12:00 Jens Axboe
2018-06-02 12:00 Jens Axboe
2018-06-01 12:00 Jens Axboe
2018-05-26 12:00 Jens Axboe
2018-05-19 12:00 Jens Axboe
2018-05-17 12:00 Jens Axboe
2018-05-15 12:00 Jens Axboe
2018-04-27 12:00 Jens Axboe
2018-04-25 12:00 Jens Axboe
2018-04-21 12:00 Jens Axboe
2018-04-19 12:00 Jens Axboe
2018-04-18 12:00 Jens Axboe
2018-04-17 12:00 Jens Axboe
2018-04-15 12:00 Jens Axboe
2018-04-14 12:00 Jens Axboe
2018-04-11 12:00 Jens Axboe
2018-04-10 12:00 Jens Axboe
2018-04-09 12:00 Jens Axboe
2018-04-07 12:00 Jens Axboe
2018-04-05 12:00 Jens Axboe
2018-04-04 12:00 Jens Axboe
2018-03-31 12:00 Jens Axboe
2018-03-30 12:00 Jens Axboe
2018-03-24 12:00 Jens Axboe
2018-03-23 12:00 Jens Axboe
2018-03-22 12:00 Jens Axboe
2018-03-21 12:00 Jens Axboe
2018-03-20 12:00 Jens Axboe
2018-03-14 12:00 Jens Axboe
2018-03-13 12:00 Jens Axboe
2018-03-10 13:00 Jens Axboe
2018-03-08 13:00 Jens Axboe
2018-03-07 13:00 Jens Axboe
2018-03-06 13:00 Jens Axboe
2018-03-03 13:00 Jens Axboe
2018-03-02 13:00 Jens Axboe
2018-03-01 13:00 Jens Axboe
2018-02-28 13:00 Jens Axboe
2018-02-27 13:00 Jens Axboe
2018-02-21 13:00 Jens Axboe
2018-02-15 13:00 Jens Axboe
2018-02-13 13:00 Jens Axboe
2018-02-11 13:00 Jens Axboe
2018-02-09 13:00 Jens Axboe
2018-02-08 13:00 Jens Axboe
2018-01-26 13:00 Jens Axboe
2018-01-25 13:00 Jens Axboe
2018-01-17 13:00 Jens Axboe
2018-01-13 13:00 Jens Axboe
2018-01-11 13:00 Jens Axboe
2018-01-07 13:00 Jens Axboe
2018-01-06 13:00 Jens Axboe
2018-01-03 13:00 Jens Axboe
2017-12-30 13:00 Jens Axboe
2017-12-29 13:00 Jens Axboe
2017-12-28 13:00 Jens Axboe
2017-12-22 13:00 Jens Axboe
2017-12-20 13:00 Jens Axboe
2017-12-16 13:00 Jens Axboe
2017-12-15 13:00 Jens Axboe
2017-12-14 13:00 Jens Axboe
2017-12-09 13:00 Jens Axboe
2017-12-08 13:00 Jens Axboe
2017-12-07 13:00 Jens Axboe
2017-12-04 13:00 Jens Axboe
2017-12-03 13:00 Jens Axboe
2017-12-02 13:00 Jens Axboe
2017-12-01 13:00 Jens Axboe
2017-11-30 13:00 Jens Axboe
2017-11-29 13:00 Jens Axboe
2017-11-24 13:00 Jens Axboe
2017-11-23 13:00 Jens Axboe
2017-11-18 13:00 Jens Axboe
2017-11-20 15:00 ` Elliott, Robert (Persistent Memory)
2017-11-17 13:00 Jens Axboe
2017-11-16 13:00 Jens Axboe
2017-11-07 13:00 Jens Axboe
2017-11-04 12:00 Jens Axboe
2017-11-03 12:00 Jens Axboe
2017-11-02 12:00 Jens Axboe
2017-11-01 12:00 Jens Axboe
2017-10-31 12:00 Jens Axboe
2017-10-27 12:00 Jens Axboe
2017-10-26 12:00 Jens Axboe
2017-10-21 12:00 Jens Axboe
2017-10-18 12:00 Jens Axboe
2017-10-13 12:00 Jens Axboe
2017-10-12 12:00 Jens Axboe
2017-10-11 12:00 Jens Axboe
2017-10-10 12:00 Jens Axboe
2017-10-07 12:00 Jens Axboe
2017-10-04 12:00 Jens Axboe
2017-09-29 12:00 Jens Axboe
2017-09-28 12:00 Jens Axboe
2017-09-27 12:00 Jens Axboe
2017-09-21 12:00 Jens Axboe
2017-09-19 12:00 Jens Axboe
2017-09-15 12:00 Jens Axboe
2017-09-14 12:00 Jens Axboe
2017-09-13 12:00 Jens Axboe
2017-09-12 12:00 Jens Axboe
2017-09-06 12:00 Jens Axboe
2017-09-03 12:00 Jens Axboe
2017-09-02 12:00 Jens Axboe
2017-09-01 12:00 Jens Axboe
2017-08-31 12:00 Jens Axboe
2017-08-30 12:00 Jens Axboe
2017-08-29 12:00 Jens Axboe
2017-08-28 12:00 Jens Axboe
2017-08-24 12:00 Jens Axboe
2017-08-23 12:00 Jens Axboe
2017-08-18 12:00 Jens Axboe
2017-08-17 12:00 Jens Axboe
2017-08-15 12:00 Jens Axboe
2017-08-10 12:00 Jens Axboe
2017-08-09 12:00 Jens Axboe
2017-08-08 12:00 Jens Axboe
2017-08-02 12:00 Jens Axboe
2017-08-01 12:00 Jens Axboe
2017-07-28 12:00 Jens Axboe
2017-07-26 12:00 Jens Axboe
2017-07-21 12:00 Jens Axboe
2017-07-17 12:00 Jens Axboe
2017-07-15 12:00 Jens Axboe
2017-07-14 12:00 Jens Axboe
2017-07-13 12:00 Jens Axboe
2017-07-11 12:00 Jens Axboe
2017-07-08 12:00 Jens Axboe
2017-07-07 12:00 Jens Axboe
2017-07-05 12:00 Jens Axboe
2017-07-04 12:00 Jens Axboe
2017-07-03 12:00 Jens Axboe
2017-06-29 12:00 Jens Axboe
2017-06-28 12:00 Jens Axboe
2017-06-27 12:00 Jens Axboe
2017-06-26 12:00 Jens Axboe
2017-06-24 12:00 Jens Axboe
2017-06-23 12:00 Jens Axboe
2017-06-20 12:00 Jens Axboe
2017-06-19 12:00 Jens Axboe
2017-06-16 12:00 Jens Axboe
2017-06-15 12:00 Jens Axboe
2017-06-13 12:00 Jens Axboe
2017-06-09 12:00 Jens Axboe
2017-06-08 12:00 Jens Axboe
2017-06-06 12:00 Jens Axboe
2013-03-20 5:00 Jens Axboe
2017-11-05 13:00 ` Jens Axboe
2017-11-06 13:00 ` Jens Axboe
2017-11-08 13:00 ` Jens Axboe
2018-01-24 13:00 ` Jens Axboe
2018-01-25 13:00 ` Jens Axboe
2018-04-10 12:00 ` Jens Axboe
2018-05-03 12:00 ` Jens Axboe
2018-05-17 12:00 ` Jens Axboe
2018-08-31 12:00 ` Jens Axboe
2018-09-01 12:00 ` Jens Axboe
2019-05-22 12:00 ` Jens Axboe
2019-09-17 12:00 ` Jens Axboe
2019-09-25 12:00 ` Jens Axboe
2020-01-17 13:00 ` Jens Axboe
2020-03-21 12:00 ` Jens Axboe
2020-05-08 12:00 ` Jens Axboe
2020-05-21 12:00 ` Jens Axboe
2021-02-20 13:00 ` Jens Axboe
2021-04-20 12:00 ` Jens Axboe
2021-06-15 11:59 ` Jens Axboe
2021-06-29 12:00 ` Jens Axboe
2021-10-22 12:00 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251219130001.CD36C1BC0147@kernel.dk \
--to=axboe@kernel.dk \
--cc=fio@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.