[PATCH v2 0/2] Introduce in_range_incl() inclusive range check macro

Guru Das Srinagesh <[email protected]>
Newsgroups org.kernel.vger.linux-iio,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Extend the existing in_range() API to provide a user-friendly inclusive
range check and add one illustrative in-tree example of its use.

The in_range() API lends itself easily to callers who care about a
half-open range, but has no straightforward equivalent for callers that
want to check for an inclusive range. Such callers have to resort to
this pattern:

	in_range(val, start, (end - start + 1))

which is quite clunky and easy to mess up. Examples of such callers:

- fs/btrfs/extent-io-tree.c hand-computes the inclusive check by
  passing "state->end - state->start + 1" as in_range()'s len argument.
- drivers/md/dm-raid.c has its own file-local __within_range(v, min, max)
  helper, independently invented, with almost a dozen call sites in
  that one file.
- drivers/iio/imu/bmi270/bmi270_core.c has three "in_range(val, 0,
  MAX + 1)" checks in bmi270_write_event_value(), computing the +1 by
  hand for the same reason.

This series converts only bmi270_core.c as a first step, as an exemplar
for the usage of the new API.

Signed-off-by: Guru Das Srinagesh <[email protected]>
---
Changes in v2:
- (Andrew) Rename in_range_incl() to in_range_inclusive()
- (Sashiko) Use __UNIQUE_ID() to fix variable-shadowing bug introduced
  by choosing fixed tempval names ("__val", "__start", "__end"). The use
  of __UNIQUE_ID() is in line with other macros listed in minmax.h.
- (Sashiko) When @end is the type's max value, len overflows to 0, so
  in_range_inclusive(val, 0, UINT32_MAX) rejected every input.
- (Sashiko) Abandon idea of reusing in_range() to avoid integer
  promotion of the "+1" always routing sub-32-bit types to in_range64(),
  defeating the stated purpose of building on in_range().
- Solve both issues above with a simple, direct "val >= start && val <=
  end" instead: an in_range()-style (val-start)<=(end-start) trick was
  tried first, but that only works under forced-unsigned arithmetic
  (like in_range32()/in_range64() use); with typeof()'s original,
  possibly-signed type, it breaks silently instead.
- Verification: exhaustive sweep over all valid u8 (start, end, val)
  triples confirms in_range_inclusive() is correct (0 mismatches vs.
  2.8M for the abandoned approach). -O2 codegen checked on x86, x86_64,
  arm and arm64: branchless on all four, byte-identical to a raw
  comparison function on every target - no performance cost from the
  switch away from in_range().

Link to v1: https://patch.msgid.link/[email protected]

To: Alex Lanzano <[email protected]>
To: Jonathan Cameron <[email protected]>
To: David Lechner <[email protected]>
To: Nuno Sá <[email protected]>
To: Andy Shevchenko <[email protected]>
Cc: [email protected]
Cc: [email protected]

---
Guru Das Srinagesh (2):
      minmax: Add in_range_inclusive() for inclusive range checks
      iio: imu: bmi270: Use in_range_inclusive() in bmi270_write_event_value()

 drivers/iio/imu/bmi270/bmi270_core.c |  6 +++---
 include/linux/minmax.h               | 19 +++++++++++++++++++
 2 files changed, 22 insertions(+), 3 deletions(-)
---
base-commit: f5098b6bae761e346ebcd9da7f95622c04733cff
change-id: 20260815-minmax-in-range-incl-a25c242be676

Best regards,
--  
Guru Das Srinagesh <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.