Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

errseq: eliminate special limitation for macro MAX_ERRNO

Current errseq implementation depends on a very special precondition that
macro MAX_ERRNO must be (2^n - 1).

Eliminate the limitation by

- redefining macro ERRSEQ_SHIFT
- defining a new macro ERRNO_MASK instead of MAX_ERRNO for errno mask.

There is no plan to change the value of MAX_ERRNO, but this makes the
implementation more generic and eliminates the BUILD_BUG_ON().

Link: https://lkml.kernel.org/r/20250407-improve_errseq-v1-1-7b27cbeb8298@quicinc.com
Signed-off-by: Zijun Hu <quic_zijuhu@quicinc.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Zijun Hu and committed by
Andrew Morton
3eff6a3e ae5b3500

+7 -6
+7 -6
lib/errseq.c
··· 34 34 */ 35 35 36 36 /* The low bits are designated for error code (max of MAX_ERRNO) */ 37 - #define ERRSEQ_SHIFT ilog2(MAX_ERRNO + 1) 37 + #define ERRSEQ_SHIFT (ilog2(MAX_ERRNO) + 1) 38 38 39 39 /* This bit is used as a flag to indicate whether the value has been seen */ 40 40 #define ERRSEQ_SEEN (1 << ERRSEQ_SHIFT) 41 + 42 + /* Leverage macro ERRSEQ_SEEN to define errno mask macro here */ 43 + #define ERRNO_MASK (ERRSEQ_SEEN - 1) 41 44 42 45 /* The lowest bit of the counter */ 43 46 #define ERRSEQ_CTR_INC (1 << (ERRSEQ_SHIFT + 1)) ··· 63 60 { 64 61 errseq_t cur, old; 65 62 66 - /* MAX_ERRNO must be able to serve as a mask */ 67 - BUILD_BUG_ON_NOT_POWER_OF_2(MAX_ERRNO + 1); 68 63 69 64 /* 70 65 * Ensure the error code actually fits where we want it to go. If it ··· 80 79 errseq_t new; 81 80 82 81 /* Clear out error bits and set new error */ 83 - new = (old & ~(MAX_ERRNO|ERRSEQ_SEEN)) | -err; 82 + new = (old & ~(ERRNO_MASK | ERRSEQ_SEEN)) | -err; 84 83 85 84 /* Only increment if someone has looked at it */ 86 85 if (old & ERRSEQ_SEEN) ··· 149 148 150 149 if (likely(cur == since)) 151 150 return 0; 152 - return -(cur & MAX_ERRNO); 151 + return -(cur & ERRNO_MASK); 153 152 } 154 153 EXPORT_SYMBOL(errseq_check); 155 154 ··· 201 200 if (new != old) 202 201 cmpxchg(eseq, old, new); 203 202 *since = new; 204 - err = -(new & MAX_ERRNO); 203 + err = -(new & ERRNO_MASK); 205 204 } 206 205 return err; 207 206 }