git: 84839d66d583 - stable/13 - linuxkpi: Add `seqcount_mutex_t` support in <linux/seqlock.h>
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 07 Jan 2023 19:16:56 UTC
The branch stable/13 has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=84839d66d583ad97603eba210d42f993445a1e5c commit 84839d66d583ad97603eba210d42f993445a1e5c Author: Jean-Sébastien Pédron <dumbbell@FreeBSD.org> AuthorDate: 2022-12-01 13:58:27 +0000 Commit: Vladimir Kondratyev <wulf@FreeBSD.org> CommitDate: 2023-01-07 12:30:18 +0000 linuxkpi: Add `seqcount_mutex_t` support in <linux/seqlock.h> To achieve that, the header uses the C11 type generic selection keyboard _Generic() because the macros are supposed to work with seqcount_t and seqcount_mutex_t. (cherry picked from commit 18e411233722088400624f21b66eb6687ebe8861) --- sys/compat/linuxkpi/common/include/linux/seqlock.h | 91 +++++++++++++++++++--- 1 file changed, 81 insertions(+), 10 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/seqlock.h b/sys/compat/linuxkpi/common/include/linux/seqlock.h index 2f4892525e8a..c520de90eca8 100644 --- a/sys/compat/linuxkpi/common/include/linux/seqlock.h +++ b/sys/compat/linuxkpi/common/include/linux/seqlock.h @@ -33,8 +33,11 @@ #include <sys/systm.h> #include <sys/lock.h> #include <sys/mutex.h> +#include <sys/rwlock.h> #include <sys/seqc.h> +#include <linux/mutex.h> + struct lock_class_key; struct seqcount { @@ -48,6 +51,12 @@ struct seqlock { }; typedef struct seqlock seqlock_t; +struct seqcount_mutex { + struct mutex *seqm_lock; + struct seqcount seqm_count; +}; +typedef struct seqcount_mutex seqcount_mutex_t; + static inline void __seqcount_init(struct seqcount *seqcount, const char *name __unused, struct lock_class_key *key __unused) @@ -57,37 +66,99 @@ __seqcount_init(struct seqcount *seqcount, const char *name __unused, #define seqcount_init(seqcount) __seqcount_init(seqcount, NULL, NULL) static inline void -write_seqcount_begin(struct seqcount *seqcount) +seqcount_mutex_init(struct seqcount_mutex *seqcount, struct mutex *mutex) +{ + seqcount->seqm_lock = mutex; + seqcount_init(&seqcount->seqm_count); +} + +#define write_seqcount_begin(s) \ + _Generic(*(s), \ + struct seqcount: lkpi_write_seqcount_begin, \ + struct seqcount_mutex: lkpi_write_seqcount_mutex_begin \ + )(s) + +static inline void +lkpi_write_seqcount_begin(struct seqcount *seqcount) { seqc_sleepable_write_begin(&seqcount->seqc); } static inline void -write_seqcount_end(struct seqcount *seqcount) +lkpi_write_seqcount_mutex_begin(struct seqcount_mutex *seqcount) +{ + mutex_lock(seqcount->seqm_lock); + lkpi_write_seqcount_begin(&seqcount->seqm_count); +} + +#define write_seqcount_end(s) \ + _Generic(*(s), \ + struct seqcount: lkpi_write_seqcount_end, \ + struct seqcount_mutex: lkpi_write_seqcount_mutex_end \ + )(s) + +static inline void +lkpi_write_seqcount_end(struct seqcount *seqcount) { seqc_sleepable_write_end(&seqcount->seqc); } -/* - * XXX: Are predicts from inline functions still not honored by clang? - */ -#define __read_seqcount_retry(seqcount, gen) \ - (!seqc_consistent_nomb(&(seqcount)->seqc, gen)) -#define read_seqcount_retry(seqcount, gen) \ - (!seqc_consistent(&(seqcount)->seqc, gen)) +static inline void +lkpi_write_seqcount_mutex_end(struct seqcount_mutex *seqcount) +{ + lkpi_write_seqcount_end(&seqcount->seqm_count); + mutex_unlock(seqcount->seqm_lock); +} + +#define read_seqcount_begin(s) \ + _Generic(*(s), \ + struct seqcount: lkpi_read_seqcount_begin, \ + struct seqcount_mutex: lkpi_read_seqcount_mutex_begin \ + )(s) static inline unsigned -read_seqcount_begin(const struct seqcount *seqcount) +lkpi_read_seqcount_begin(const struct seqcount *seqcount) { return (seqc_read(&seqcount->seqc)); } +static inline unsigned +lkpi_read_seqcount_mutex_begin(const struct seqcount_mutex *seqcount) +{ + return (lkpi_read_seqcount_begin(&seqcount->seqm_count)); +} + static inline unsigned raw_read_seqcount(const struct seqcount *seqcount) { return (seqc_read_any(&seqcount->seqc)); } +/* + * XXX: Are predicts from inline functions still not honored by clang? + */ +#define __read_seqcount_retry(seqcount, gen) \ + (!seqc_consistent_nomb(&(seqcount)->seqc, gen)) +#define read_seqcount_retry(s, old) \ + _Generic(*(s), \ + struct seqcount: lkpi_read_seqcount_retry, \ + struct seqcount_mutex: lkpi_read_seqcount_mutex_retry \ + )(s, old) + +static inline int +lkpi_read_seqcount_retry( + const struct seqcount *seqcount, unsigned int old) +{ + return (!seqc_consistent(&seqcount->seqc, old)); +} + +static inline int +lkpi_read_seqcount_mutex_retry( + const struct seqcount_mutex *seqcount, unsigned int old) +{ + return (!seqc_consistent(&seqcount->seqm_count.seqc, old)); +} + static inline void seqlock_init(struct seqlock *seqlock) {