]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
errseq: eliminate special limitation for macro MAX_ERRNO
authorZijun Hu <quic_zijuhu@quicinc.com>
Mon, 7 Apr 2025 11:44:16 +0000 (19:44 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 12 May 2025 00:54:06 +0000 (17:54 -0700)
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>
lib/errseq.c

index 93e9b94358dc63dcc911fd45a01ccf38d2104ecf..13a2581c5a878445f8a089d0d34e901f77a9e074 100644 (file)
  */
 
 /* The low bits are designated for error code (max of MAX_ERRNO) */
-#define ERRSEQ_SHIFT           ilog2(MAX_ERRNO + 1)
+#define ERRSEQ_SHIFT           (ilog2(MAX_ERRNO) + 1)
 
 /* This bit is used as a flag to indicate whether the value has been seen */
 #define ERRSEQ_SEEN            (1 << ERRSEQ_SHIFT)
 
+/* Leverage macro ERRSEQ_SEEN to define errno mask macro here */
+#define ERRNO_MASK             (ERRSEQ_SEEN - 1)
+
 /* The lowest bit of the counter */
 #define ERRSEQ_CTR_INC         (1 << (ERRSEQ_SHIFT + 1))
 
@@ -60,8 +63,6 @@ errseq_t errseq_set(errseq_t *eseq, int err)
 {
        errseq_t cur, old;
 
-       /* MAX_ERRNO must be able to serve as a mask */
-       BUILD_BUG_ON_NOT_POWER_OF_2(MAX_ERRNO + 1);
 
        /*
         * Ensure the error code actually fits where we want it to go. If it
@@ -79,7 +80,7 @@ errseq_t errseq_set(errseq_t *eseq, int err)
                errseq_t new;
 
                /* Clear out error bits and set new error */
-               new = (old & ~(MAX_ERRNO|ERRSEQ_SEEN)) | -err;
+               new = (old & ~(ERRNO_MASK | ERRSEQ_SEEN)) | -err;
 
                /* Only increment if someone has looked at it */
                if (old & ERRSEQ_SEEN)
@@ -148,7 +149,7 @@ int errseq_check(errseq_t *eseq, errseq_t since)
 
        if (likely(cur == since))
                return 0;
-       return -(cur & MAX_ERRNO);
+       return -(cur & ERRNO_MASK);
 }
 EXPORT_SYMBOL(errseq_check);
 
@@ -200,7 +201,7 @@ int errseq_check_and_advance(errseq_t *eseq, errseq_t *since)
                if (new != old)
                        cmpxchg(eseq, old, new);
                *since = new;
-               err = -(new & MAX_ERRNO);
+               err = -(new & ERRNO_MASK);
        }
        return err;
 }