* linux-next: manual merge of the tip tree with the modules tree
@ 2015-06-20 8:35 Stephen Rothwell
2015-06-20 8:55 ` Peter Zijlstra
0 siblings, 1 reply; 2+ messages in thread
From: Stephen Rothwell @ 2015-06-20 8:35 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Peter Zijlstra,
Rusty Russell
Cc: linux-next, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 4721 bytes --]
Hi all,
Today's linux-next merge of the tip tree got a conflict in:
include/linux/seqlock.h
between commit:
7fc26327b756 ("seqlock: Introduce raw_read_seqcount_latch()")
from the modules tree and commit:
c4bfa3f5f906 ("seqcount: Introduce raw_write_seqcount_barrier()")
from the tip tree.
I fixed it up (see below) and can carry the fix as necessary (no action
is required).
--
Cheers,
Stephen Rothwell sfr@canb•auug.org.au
diff --cc include/linux/seqlock.h
index 890c7ef709d5,486e685a226a..000000000000
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@@ -234,87 -233,50 +234,128 @@@ static inline void raw_write_seqcount_e
s->sequence++;
}
+ /**
+ * raw_write_seqcount_barrier - do a seq write barrier
+ * @s: pointer to seqcount_t
+ *
+ * This can be used to provide an ordering guarantee instead of the
+ * usual consistency guarantee. It is one wmb cheaper, because we can
+ * collapse the two back-to-back wmb()s.
+ *
+ * seqcount_t seq;
+ * bool X = true, Y = false;
+ *
+ * void read(void)
+ * {
+ * bool x, y;
+ *
+ * do {
+ * int s = read_seqcount_begin(&seq);
+ *
+ * x = X; y = Y;
+ *
+ * } while (read_seqcount_retry(&seq, s));
+ *
+ * BUG_ON(!x && !y);
+ * }
+ *
+ * void write(void)
+ * {
+ * Y = true;
+ *
+ * raw_write_seqcount_barrier(seq);
+ *
+ * X = false;
+ * }
+ */
+ static inline void raw_write_seqcount_barrier(seqcount_t *s)
+ {
+ s->sequence++;
+ smp_wmb();
+ s->sequence++;
+ }
+
-/*
+static inline int raw_read_seqcount_latch(seqcount_t *s)
+{
+ return lockless_dereference(s->sequence);
+}
+
+/**
* raw_write_seqcount_latch - redirect readers to even/odd copy
* @s: pointer to seqcount_t
+ *
+ * The latch technique is a multiversion concurrency control method that allows
+ * queries during non-atomic modifications. If you can guarantee queries never
+ * interrupt the modification -- e.g. the concurrency is strictly between CPUs
+ * -- you most likely do not need this.
+ *
+ * Where the traditional RCU/lockless data structures rely on atomic
+ * modifications to ensure queries observe either the old or the new state the
+ * latch allows the same for non-atomic updates. The trade-off is doubling the
+ * cost of storage; we have to maintain two copies of the entire data
+ * structure.
+ *
+ * Very simply put: we first modify one copy and then the other. This ensures
+ * there is always one copy in a stable state, ready to give us an answer.
+ *
+ * The basic form is a data structure like:
+ *
+ * struct latch_struct {
+ * seqcount_t seq;
+ * struct data_struct data[2];
+ * };
+ *
+ * Where a modification, which is assumed to be externally serialized, does the
+ * following:
+ *
+ * void latch_modify(struct latch_struct *latch, ...)
+ * {
+ * smp_wmb(); <- Ensure that the last data[1] update is visible
+ * latch->seq++;
+ * smp_wmb(); <- Ensure that the seqcount update is visible
+ *
+ * modify(latch->data[0], ...);
+ *
+ * smp_wmb(); <- Ensure that the data[0] update is visible
+ * latch->seq++;
+ * smp_wmb(); <- Ensure that the seqcount update is visible
+ *
+ * modify(latch->data[1], ...);
+ * }
+ *
+ * The query will have a form like:
+ *
+ * struct entry *latch_query(struct latch_struct *latch, ...)
+ * {
+ * struct entry *entry;
+ * unsigned seq, idx;
+ *
+ * do {
+ * seq = lockless_dereference(latch->seq);
+ *
+ * idx = seq & 0x01;
+ * entry = data_query(latch->data[idx], ...);
+ *
+ * smp_rmb();
+ * } while (seq != latch->seq);
+ *
+ * return entry;
+ * }
+ *
+ * So during the modification, queries are first redirected to data[1]. Then we
+ * modify data[0]. When that is complete, we redirect queries back to data[0]
+ * and we can modify data[1].
+ *
+ * NOTE: The non-requirement for atomic modifications does _NOT_ include
+ * the publishing of new entries in the case where data is a dynamic
+ * data structure.
+ *
+ * An iteration might start in data[0] and get suspended long enough
+ * to miss an entire modification sequence, once it resumes it might
+ * observe the new entry.
+ *
+ * NOTE: When data is a dynamic data structure; one should use regular RCU
+ * patterns to manage the lifetimes of the objects within.
*/
static inline void raw_write_seqcount_latch(seqcount_t *s)
{
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: linux-next: manual merge of the tip tree with the modules tree
2015-06-20 8:35 linux-next: manual merge of the tip tree with the modules tree Stephen Rothwell
@ 2015-06-20 8:55 ` Peter Zijlstra
0 siblings, 0 replies; 2+ messages in thread
From: Peter Zijlstra @ 2015-06-20 8:55 UTC (permalink / raw)
To: Stephen Rothwell
Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Rusty Russell,
linux-next, linux-kernel
On Sat, Jun 20, 2015 at 06:35:58PM +1000, Stephen Rothwell wrote:
> Hi all,
>
> Today's linux-next merge of the tip tree got a conflict in:
>
> include/linux/seqlock.h
>
> between commit:
>
> 7fc26327b756 ("seqlock: Introduce raw_read_seqcount_latch()")
>
> from the modules tree and commit:
>
> c4bfa3f5f906 ("seqcount: Introduce raw_write_seqcount_barrier()")
>
> from the tip tree.
>
> I fixed it up (see below) and can carry the fix as necessary (no action
> is required).
Oh my that's unfortunate, those two patches just touching at the edge.
Resolution looks good.
Thanks.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-06-20 8:55 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-20 8:35 linux-next: manual merge of the tip tree with the modules tree Stephen Rothwell
2015-06-20 8:55 ` Peter Zijlstra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox