The branch main has been updated by dumbbell (ports committer):

URL: 
https://cgit.FreeBSD.org/src/commit/?id=9491ea7c68221ca7bc5e369ebb57660886ef1b13

commit 9491ea7c68221ca7bc5e369ebb57660886ef1b13
Author:     Jean-Sébastien Pédron <dumbb...@freebsd.org>
AuthorDate: 2023-01-15 14:56:48 +0000
Commit:     Jean-Sébastien Pédron <dumbb...@freebsd.org>
CommitDate: 2023-01-25 21:26:54 +0000

    linuxkpi: Fix `atomic_long_sub()` overflow
    
    By (ab)using `atomic_long_add_return()`, `atomic_long_sub()` was making
    the atomic long overflow. Indeed the underlying FreeBSD atomic is based
    on an unsigned long.
    
    Reviewed by:    manu
    Approved by:    manu
    Differential Revision:  https://reviews.freebsd.org/D38090
---
 sys/compat/linuxkpi/common/include/asm/atomic-long.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sys/compat/linuxkpi/common/include/asm/atomic-long.h 
b/sys/compat/linuxkpi/common/include/asm/atomic-long.h
index f8bd9edfccf9..aeec6edd707d 100644
--- a/sys/compat/linuxkpi/common/include/asm/atomic-long.h
+++ b/sys/compat/linuxkpi/common/include/asm/atomic-long.h
@@ -41,7 +41,7 @@ typedef struct {
 } atomic_long_t;
 
 #define        atomic_long_add(i, v)           atomic_long_add_return((i), (v))
-#define        atomic_long_sub(i, v)           atomic_long_add_return(-(i), 
(v))
+#define        atomic_long_sub(i, v)           atomic_long_sub_return((i), (v))
 #define        atomic_long_inc_return(v)       atomic_long_add_return(1, (v))
 #define        atomic_long_inc_not_zero(v)     atomic_long_add_unless((v), 1, 
0)
 
@@ -51,6 +51,12 @@ atomic_long_add_return(long i, atomic_long_t *v)
        return i + atomic_fetchadd_long(&v->counter, i);
 }
 
+static inline long
+atomic_long_sub_return(long i, atomic_long_t *v)
+{
+       return atomic_fetchadd_long(&v->counter, -i) - i;
+}
+
 static inline void
 atomic_long_set(atomic_long_t *v, long i)
 {

Reply via email to