diff --git a/freebsd/amd64/include/atomic.h b/freebsd/amd64/include/atomic.h index 87f7b8e82..fefb7944b 100644 --- a/freebsd/amd64/include/atomic.h +++ b/freebsd/amd64/include/atomic.h @@ -227,6 +227,34 @@ atomic_fcmpset_##TYPE(volatile u_##TYPE *dst, u_##TYPE *expect, u_##TYPE src) \ return (res); \ } +#ifdef FSTACK +/* + * The atomic_fcmpset_int above run error sometimes, + * it's return value is 0 while CAS success, and then loop long time. + * And no reason found yet. + * + * But use the function can fix it. + * This function copied from DPDK's rte_atomic.h + */ +static __inline int \ +atomic_fcmpset_int32(volatile u_int *dst, u_int *expect, u_int src) \ +{ \ + u_char res; \ + \ + __asm __volatile( \ + " " MPLOCKED " " \ + "cmpxchgl %[src], %[dst];" \ + "sete %[res];" \ + : [res] "=a" (res), /* output */ \ + [dst] "=m" (*dst) \ + : [src] "r" (src), /* input */ \ + "a" (*expect), \ + "m" (*dst) \ + : "memory"); /* no-clobber list */ \ + return (res); \ +} +#endif + ATOMIC_CMPSET(char); ATOMIC_CMPSET(short); ATOMIC_CMPSET(int); diff --git a/freebsd/kern/kern_descrip.c b/freebsd/kern/kern_descrip.c index 8fc39d295..f69d3d05b 100644 --- a/freebsd/kern/kern_descrip.c +++ b/freebsd/kern/kern_descrip.c @@ -3136,6 +3136,16 @@ fget_unlocked_seq(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, * if anything goes wrong. In practice this only happens when userspace is * racing with itself. */ +#ifdef FSTACK +/* + * Note: If loop dead in this function, + * Maybe CAS run not correctly in `refcount_acquire_if_not_zero`, + * You can try modify `atomic_fcmpset_int` to `atomic_fcmpset_int32` + * in function `refcount_acquire_if_gt` of `refcount.h` + * + * See also `atomic_fcmpset_int32` in `freebsd/amd64/include/atomic.h` + */ +#endif int fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, struct file **fpp) @@ -5137,7 +5147,7 @@ ff_getmaxfd(void) { struct thread *td = curthread; return getmaxfd(td); - + } #endif diff --git a/freebsd/sys/refcount.h b/freebsd/sys/refcount.h index c320316a8..83bf7dc9d 100644 --- a/freebsd/sys/refcount.h +++ b/freebsd/sys/refcount.h @@ -117,6 +117,15 @@ refcount_acquire_checked(volatile u_int *count) * This functions returns non-zero if the refcount was * incremented. Else zero is returned. */ +#ifdef FSTACK +/* + * Note: If loop dead in this function, + * Maybe CAS that atomic_fcmpset_int run not correctly in this function, + * You can try modify `atomic_fcmpset_int` to `atomic_fcmpset_int32`. + * + * See also `atomic_fcmpset_int32` in `freebsd/amd64/include/atomic.h` + */ +#endif static __inline __result_use_check bool refcount_acquire_if_gt(volatile u_int *count, u_int n) {