aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linuxkpi/common
diff options
context:
space:
mode:
authorJean-Sébastien Pédron <dumbbell@FreeBSD.org>2022-12-01 13:58:27 +0000
committerEmmanuel Vadot <manu@FreeBSD.org>2022-12-01 13:58:27 +0000
commit18e411233722088400624f21b66eb6687ebe8861 (patch)
tree43827bb3bfc7c0d370839d482b66e52d66c3767b /sys/compat/linuxkpi/common
parent984b27d879e14d88834ddfb7b9f9a4c40a84c492 (diff)
downloadsrc-18e411233722088400624f21b66eb6687ebe8861.tar.gz
src-18e411233722088400624f21b66eb6687ebe8861.zip
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. Differential Revision: https://reviews.freebsd.org/D36965
Diffstat (limited to 'sys/compat/linuxkpi/common')
-rw-r--r--sys/compat/linuxkpi/common/include/linux/seqlock.h91
1 files 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 6e81e7a0fa45..4a5385f5e095 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_no_fence(&(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_no_fence(&(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)
{