[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]>