All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Stefan Haberland" <sth@linux.ibm.com>
Cc: "Vasily Gorbik" <gor@linux.ibm.com>,
	linux-s390@vger.kernel.org, "Heiko Carstens" <hca@linux.ibm.com>,
	"Alexander Gordeev" <agordeev@linux.ibm.com>
Subject: Re: [PATCH v7 14/19] s390/dasd: Derive adaptive ESE fulltrack heuristic from ft_bias
Date: Sat, 01 Aug 2026 18:17:51 +0000	[thread overview]
Message-ID: <20260801181752.4AA881F00AC4@smtp.kernel.org> (raw)
In-Reply-To: <20260801180033.3679412-15-sth@linux.ibm.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] sysfs attribute `ese_heuristic_state` incorrectly reports 'fulltrack active' for non-ESE devices.
- [Medium] Flawed lockless synchronization in `dasd_ese_heuristic_tick` allows multiple threads to bypass the early return, resulting in spurious state transitions based on tiny probe windows.
--

--- Patch [14]: [PATCH v7 14/19] s390/dasd: Derive adaptive ESE fulltrack heuristic from ft_bias ---
commit e1b43c6c6e91c681aa16c723f5cbd3e86ae30516
Author: Stefan Haberland <sth@linux.ibm.com>

s390/dasd: Derive adaptive ESE fulltrack heuristic from ft_bias

Turn the middle of the ft_bias range (1..99) into an adaptive heuristic
that switches between fulltrack write (ft1) and plain write ft0 depending
on how sparse the device still is.

A sparse device benefits from fulltrack writes (it avoids the format/retry
cycle); once enough tracks are formatted the per-write overhead of
ft1 outweighs that. An state machine  measures the NRF rate in short ft0
probe windows and flips back to ft1 when it is high
(FT1_ACTIVE -> PROBING -> FT0_STABLE, with a backing-off reprobe interval).

> diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
> index 035c022255b68..50301e545bbe8 100644
> --- a/drivers/s390/block/dasd_devmap.c
> +++ b/drivers/s390/block/dasd_devmap.c

[ ... ]

> @@ -1668,6 +1674,41 @@ static ssize_t full_track_bias_store(struct device *dev,
>  
>  static DEVICE_ATTR_RW(full_track_bias);
>  
> +static const char * const dasd_ese_heu_state_names[] = {
> +	[DASD_ESE_HEU_FT1_ACTIVE] = "fulltrack active",
> +	[DASD_ESE_HEU_PROBING]    = "probing",
> +	[DASD_ESE_HEU_FT0_STABLE] = "fulltrack inactive",
> +};
> +
> +/* read-only: current full-track mode / adaptive FSM state, for observability */
> +static ssize_t
> +ese_heuristic_state_show(struct device *dev, struct device_attribute *attr,
> +			 char *buf)
> +{
> +	struct dasd_device *device;
> +	unsigned int state;
> +	int len;
> +
> +	device = dasd_device_from_cdev(to_ccwdev(dev));
> +	if (IS_ERR(device))
> +		return -ENODEV;
> +	if (device->ft_bias == 0) {
> +		len = sysfs_emit(buf, "fulltrack deactivated\n");
> +	} else if (device->ft_bias >= DASD_FT_BIAS_MAX) {
> +		len = sysfs_emit(buf, "fulltrack permanent active\n");
> +	} else {
> +		state = device->ese_probe_state;
> +		if (state < ARRAY_SIZE(dasd_ese_heu_state_names))
> +			len = sysfs_emit(buf, "%s\n", dasd_ese_heu_state_names[state]);
> +		else
> +			len = sysfs_emit(buf, "unknown\n");
> +	}

[Severity: Medium]
Will this incorrectly report "fulltrack active" for non-ESE devices?

If ft_bias is set in the adaptive range (which defaults to 50), this falls
into the else block and reads ese_probe_state. For standard non-ESE
devices, dasd_ft_bias_apply() initializes this state to
DASD_ESE_HEU_FT1_ACTIVE (0). 

Should this check dasd_ese_adaptive(device) before printing the state to
avoid exposing misleading observability statistics to user space?

> +	dasd_put_device(device);
> +	return len;
> +}
> +
> +static DEVICE_ATTR_RO(ese_heuristic_state);

[ ... ]

> diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
> index 0247e9a6d7929..dc30c4395b0cc 100644
> --- a/drivers/s390/block/dasd_eckd.c
> +++ b/drivers/s390/block/dasd_eckd.c

[ ... ]

> @@ -3230,6 +3239,69 @@ static void clear_format_track(struct dasd_format_entry *format,
>  	spin_unlock_irqrestore(&block->format_lock, flags);
>  }
>  
> +/*
> + * Adaptive ft_bias heuristic, called once per IO from dasd_eckd_build_cp().
> + * Probes the device formatting state by briefly switching to ft0 and measuring
> + * the NRF rate; parameters are derived from ft_bias.
> + */
> +static void dasd_ese_heuristic_tick(struct dasd_device *basedev)
> +{
> +	int ios, nrf, rate;
> +
> +	if (atomic_inc_return(&basedev->ese_io_cnt) < (int)basedev->ese_probe_interval)
> +		return;
> +
> +	/*
> +	 * One wins the race to evaluate, the rest see ios == 0 after the
> +	 * xchg and return early, preventing redundant state transitions.
> +	 */
> +	ios = atomic_xchg(&basedev->ese_io_cnt, 0);
> +	if (ios <= 0)
> +		return;

[Severity: Medium]
Is it possible for multiple threads to bypass the early return and cause
spurious state transitions?

If multiple threads concurrently evaluate
atomic_inc_return(&basedev->ese_io_cnt) < interval and see a value >= interval,
they both proceed. The first thread zeroes the counter via atomic_xchg.

If another I/O increments the counter to 1 before the second thread performs
its atomic_xchg, the second thread will read 1, bypass the ios <= 0 check,
and evaluate the heuristic using ios = 1.

Could this lead to the ESE heuristic state machine evaluating on tiny probe
windows, causing thrashing between FT0 and FT1 under concurrent I/O submission?

> +
> +	switch (basedev->ese_probe_state) {
> +	case DASD_ESE_HEU_FT1_ACTIVE:

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260801180033.3679412-1-sth@linux.ibm.com?part=14

  reply	other threads:[~2026-08-01 18:17 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-01 18:00 [PATCH v7 00/19] s390/dasd: ESE thin-provisioning performance improvements Stefan Haberland
2026-08-01 18:00 ` [PATCH v7 01/19] s390/dasd: Do not complete a failed ESE read as successful Stefan Haberland
2026-08-01 18:30   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 02/19] s390/dasd: Propagate partial completion length across ERP recovery Stefan Haberland
2026-08-01 18:21   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 03/19] s390/dasd: Guard sysfs discipline callbacks against unallocated private data Stefan Haberland
2026-08-01 18:29   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 04/19] s390/dasd: Snapshot intrc before freeing the request block Stefan Haberland
2026-08-01 18:18   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 05/19] s390/dasd: Optimize max blocks per request for track alignment Stefan Haberland
2026-08-01 18:05   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 06/19] s390/dasd: Use GFP_KERNEL in dasd_alloc_device() Stefan Haberland
2026-08-01 18:15   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 07/19] s390/dasd: Add defines for the Extended Address Volume track address Stefan Haberland
2026-08-01 18:05   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 08/19] s390/dasd: Add infrastructure for ESE full-track write Stefan Haberland
2026-08-01 18:21   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 09/19] s390/dasd: Add range-based format-track collision detection Stefan Haberland
2026-08-01 18:23   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 10/19] s390/dasd: Extend prepare_itcw() to support WRITE_FULL_TRACK Stefan Haberland
2026-08-01 18:28   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 11/19] s390/dasd: Add dasd_eckd_build_cp_tpm_writefulltrack() Stefan Haberland
2026-08-01 18:17   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 12/19] s390/dasd: Use WRITE_FULL_TRACK in ESE format handler Stefan Haberland
2026-08-01 18:33   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 13/19] s390/dasd: Add full_track_bias to control fulltrack write mode Stefan Haberland
2026-08-01 18:20   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 14/19] s390/dasd: Derive adaptive ESE fulltrack heuristic from ft_bias Stefan Haberland
2026-08-01 18:17   ` sashiko-bot [this message]
2026-08-01 18:00 ` [PATCH v7 15/19] s390/dasd: Stamp a format label into newly formatted volumes Stefan Haberland
2026-08-01 18:26   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 16/19] s390/dasd: Detect ESE volumes from the on-disk format label Stefan Haberland
2026-08-01 18:39   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 17/19] s390/dasd: Report ESE capability and format mode at device online Stefan Haberland
2026-08-01 18:22   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 18/19] s390/dasd: Re-enable discard support for ESE volumes Stefan Haberland
2026-08-01 18:46   ` sashiko-bot
2026-08-01 18:00 ` [PATCH v7 19/19] s390/dasd: Read cached unit address and LSS in the CCW build path Stefan Haberland
2026-08-01 18:50   ` 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=20260801181752.4AA881F00AC4@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.