From: sashiko-bot@kernel.org
To: "Stefan Haberland" <sth@linux.ibm.com>
Cc: "Heiko Carstens" <hca@linux.ibm.com>,
"Vasily Gorbik" <gor@linux.ibm.com>,
linux-s390@vger.kernel.org,
"Alexander Gordeev" <agordeev@linux.ibm.com>
Subject: Re: [PATCH v5 12/17] s390/dasd: Derive adaptive ESE fulltrack heuristic from ft_bias
Date: Fri, 31 Jul 2026 16:27:12 +0000 [thread overview]
Message-ID: <20260731162713.113A71F00AC4@smtp.kernel.org> (raw)
In-Reply-To: <20260731153842.1729627-13-sth@linux.ibm.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] The adaptive heuristic parameters are never initialized during device startup because `dasd_ft_bias_apply()` is called before the device's ESE capability is known, causing the heuristic to evaluate on every single I/O.
- [High] The NRF rate calculation can overflow a 32-bit signed integer, causing the heuristic to improperly remain in plain write mode during heavy unformatted I/O.
- [High] The lockless heuristic evaluation and sysfs updates fail to serialize state machine transitions, leading to state divergence where the device permanently sticks in fulltrack mode.
--
--- Patch [12]: [PATCH v5 12/17] s390/dasd: Derive adaptive ESE fulltrack heuristic from ft_bias ---
commit fc455715bb1f927b75206de59511e6f8a3abe72f
Author: Stefan Haberland <sth@linux.ibm.com>
s390/dasd: Derive adaptive ESE fulltrack heuristic from ft_bias
This patch turns the middle of the ft_bias range into an adaptive heuristic
that switches between fulltrack write and plain write depending on device
sparseness. It measures the NRF rate in short probe windows to determine
when to flip back to fulltrack write mode.
> diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
> index cc5a4791cb8f4..1df861f80c268 100644
> --- a/drivers/s390/block/dasd_eckd.c
> +++ b/drivers/s390/block/dasd_eckd.c
> @@ -2160,6 +2160,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
>
> /* default ESE fulltrack write aggressiveness from the module parameter */
> device->ft_bias = min_t(unsigned int, full_track_bias, DASD_FT_BIAS_MAX);
> - /* only the "always" endpoint forces fulltrack unconditionally here */
> - device->fulltrack = (device->ft_bias >= DASD_FT_BIAS_MAX) ? 1 : 0;
> + dasd_ft_bias_apply(device);
[Severity: High]
Does calling dasd_ft_bias_apply() here happen before the device's ESE
capability is known?
In dasd_eckd_check_characteristics(), dasd_ft_bias_apply() is called early.
This function relies on dasd_ese_adaptive(), which checks is_ese(). However,
is_ese() depends on private->vsq, which is populated later when
dasd_eckd_read_vol_info() is called.
Because vsq is empty at this point, dasd_ese_adaptive() returns false, and
the heuristic parameters (like ese_heu_start_interval and
ese_heu_probe_window) are left initialized to 0. Will this cause the
heuristic interval to pass immediately and the FSM to evaluate on every
single I/O?
[ ... ]
> @@ -3235,6 +3241,65 @@ static void clear_format_track(...)
> +static void dasd_ese_heuristic_tick(struct dasd_device *basedev)
> +{
[ ... ]
> + case DASD_ESE_HEU_PROBING:
> + case DASD_ESE_HEU_FT0_STABLE:
> + nrf = atomic_xchg(&basedev->ese_nrf_window, 0);
> + rate = nrf * 1000 / ios;
> + if (rate > (int)basedev->ese_heu_nrf_high) {
[Severity: High]
Can this rate calculation overflow a 32-bit signed integer?
During the FT0_STABLE state, the ios interval backs off up to max_interval
(500,000 IOs). If a workload performs large sequential writes into
unformatted space, an I/O can span multiple tracks, triggering multiple NRF
events.
If the number of formatted tracks reaches ~2,147,483 within the 500,000 IO
window, nrf * 1000 will exceed INT_MAX and overflow to a negative value.
Could this cause the check to evaluate to false and improperly keep the
device stuck in plain write mode during heavy unformatted I/O?
> + /* NRF rate high: device still sparse, ft1 is better */
> + basedev->fulltrack = 1;
> + basedev->ese_probe_state = DASD_ESE_HEU_FT1_ACTIVE;
> + basedev->ese_probe_interval = basedev->ese_heu_start_interval;
> + } else if (basedev->ese_probe_state == DASD_ESE_HEU_PROBING) {
> + /*
> + * NRF rate low: device mostly formatted, ft0 is faster.
> + * Re-probe frequently at first, then back off below.
> + */
> + basedev->ese_probe_state = DASD_ESE_HEU_FT0_STABLE;
> + basedev->ese_probe_interval = basedev->ese_heu_probe_window;
[Severity: High]
Can this lockless state transition race with a sysfs update and permanently
stick the device in fulltrack mode?
If a thread is transitioning from PROBING to FT0_STABLE (evaluating
basedev->ese_probe_state == DASD_ESE_HEU_PROBING as true) but is preempted
before writing the state, a concurrent sysfs update via
full_track_bias_store() -> dasd_ft_bias_apply() could reset the FSM:
drivers/s390/block/dasd_int.h:dasd_ft_bias_apply() {
...
device->ese_probe_state = DASD_ESE_HEU_FT1_ACTIVE;
device->fulltrack = 1;
...
}
When the preempted thread resumes, it would set ese_probe_state to
DASD_ESE_HEU_FT0_STABLE but leave fulltrack as 1. Since fulltrack = 1
suppresses NRF events, the measured rate stays at 0 and the FSM interval
backs off without ever resetting fulltrack to 0, completely defeating the
adaptive heuristic.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260731153842.1729627-1-sth@linux.ibm.com?part=12
next prev parent reply other threads:[~2026-07-31 16:27 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 15:38 [PATCH v5 00/17] s390/dasd: ESE thin-provisioning performance improvements Stefan Haberland
2026-07-31 15:38 ` [PATCH v5 01/17] s390/dasd: Propagate partial completion length across ERP recovery Stefan Haberland
2026-07-31 15:50 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 02/17] s390/dasd: Guard sysfs discipline callbacks against unallocated private data Stefan Haberland
2026-07-31 15:59 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 03/17] s390/dasd: Optimize max blocks per request for track alignment Stefan Haberland
2026-07-31 15:46 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 04/17] s390/dasd: Use GFP_KERNEL in dasd_alloc_device() Stefan Haberland
2026-07-31 15:52 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 05/17] s390/dasd: Add defines for the Extended Address Volume track address Stefan Haberland
2026-07-31 15:48 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 06/17] s390/dasd: Add infrastructure for ESE full-track write Stefan Haberland
2026-07-31 16:16 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 07/17] s390/dasd: Add range-based format-track collision detection Stefan Haberland
2026-07-31 16:11 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 08/17] s390/dasd: Extend prepare_itcw() to support WRITE_FULL_TRACK Stefan Haberland
2026-07-31 16:21 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 09/17] s390/dasd: Add dasd_eckd_build_cp_tpm_writefulltrack() Stefan Haberland
2026-07-31 16:13 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 10/17] s390/dasd: Use WRITE_FULL_TRACK in ESE format handler Stefan Haberland
2026-07-31 16:33 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 11/17] s390/dasd: Add full_track_bias to control fulltrack write mode Stefan Haberland
2026-07-31 16:28 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 12/17] s390/dasd: Derive adaptive ESE fulltrack heuristic from ft_bias Stefan Haberland
2026-07-31 16:27 ` sashiko-bot [this message]
2026-07-31 15:38 ` [PATCH v5 13/17] s390/dasd: Stamp a format label into newly formatted volumes Stefan Haberland
2026-07-31 16:35 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 14/17] s390/dasd: Detect ESE volumes from the on-disk format label Stefan Haberland
2026-07-31 16:43 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 15/17] s390/dasd: Report ESE capability and format mode at device online Stefan Haberland
2026-07-31 16:39 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 16/17] s390/dasd: Re-enable discard support for ESE volumes Stefan Haberland
2026-07-31 16:54 ` sashiko-bot
2026-07-31 15:38 ` [PATCH v5 17/17] s390/dasd: Read cached unit address and LSS in the CCW build path Stefan Haberland
2026-07-31 16:58 ` sashiko-bot
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=20260731162713.113A71F00AC4@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=agordeev@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=linux-s390@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=sth@linux.ibm.com \
/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.