@@ -263,32 +263,32 @@ static inline void raw_write_seqcount_end(seqcount_t *s)
263
263
* atomically, avoiding compiler optimizations; b) to document which writes are
264
264
* meant to propagate to the reader critical section. This is necessary because
265
265
* neither writes before and after the barrier are enclosed in a seq-writer
266
- * critical section that would ensure readers are aware of ongoing writes.
266
+ * critical section that would ensure readers are aware of ongoing writes::
267
267
*
268
- * seqcount_t seq;
269
- * bool X = true, Y = false;
268
+ * seqcount_t seq;
269
+ * bool X = true, Y = false;
270
270
*
271
- * void read(void)
272
- * {
273
- * bool x, y;
271
+ * void read(void)
272
+ * {
273
+ * bool x, y;
274
274
*
275
- * do {
276
- * int s = read_seqcount_begin(&seq);
275
+ * do {
276
+ * int s = read_seqcount_begin(&seq);
277
277
*
278
- * x = X; y = Y;
278
+ * x = X; y = Y;
279
279
*
280
- * } while (read_seqcount_retry(&seq, s));
280
+ * } while (read_seqcount_retry(&seq, s));
281
281
*
282
- * BUG_ON(!x && !y);
282
+ * BUG_ON(!x && !y);
283
283
* }
284
284
*
285
285
* void write(void)
286
286
* {
287
- * WRITE_ONCE(Y, true);
287
+ * WRITE_ONCE(Y, true);
288
288
*
289
- * raw_write_seqcount_barrier(seq);
289
+ * raw_write_seqcount_barrier(seq);
290
290
*
291
- * WRITE_ONCE(X, false);
291
+ * WRITE_ONCE(X, false);
292
292
* }
293
293
*/
294
294
static inline void raw_write_seqcount_barrier (seqcount_t * s )
@@ -325,64 +325,68 @@ static inline int raw_read_seqcount_latch(seqcount_t *s)
325
325
* Very simply put: we first modify one copy and then the other. This ensures
326
326
* there is always one copy in a stable state, ready to give us an answer.
327
327
*
328
- * The basic form is a data structure like:
328
+ * The basic form is a data structure like::
329
329
*
330
- * struct latch_struct {
331
- * seqcount_t seq;
332
- * struct data_struct data[2];
333
- * };
330
+ * struct latch_struct {
331
+ * seqcount_t seq;
332
+ * struct data_struct data[2];
333
+ * };
334
334
*
335
335
* Where a modification, which is assumed to be externally serialized, does the
336
- * following:
336
+ * following::
337
337
*
338
- * void latch_modify(struct latch_struct *latch, ...)
339
- * {
340
- * smp_wmb(); <- Ensure that the last data[1] update is visible
341
- * latch->seq++;
342
- * smp_wmb(); <- Ensure that the seqcount update is visible
338
+ * void latch_modify(struct latch_struct *latch, ...)
339
+ * {
340
+ * smp_wmb(); // Ensure that the last data[1] update is visible
341
+ * latch->seq++;
342
+ * smp_wmb(); // Ensure that the seqcount update is visible
343
343
*
344
- * modify(latch->data[0], ...);
344
+ * modify(latch->data[0], ...);
345
345
*
346
- * smp_wmb(); <- Ensure that the data[0] update is visible
347
- * latch->seq++;
348
- * smp_wmb(); <- Ensure that the seqcount update is visible
346
+ * smp_wmb(); // Ensure that the data[0] update is visible
347
+ * latch->seq++;
348
+ * smp_wmb(); // Ensure that the seqcount update is visible
349
349
*
350
- * modify(latch->data[1], ...);
351
- * }
350
+ * modify(latch->data[1], ...);
351
+ * }
352
352
*
353
- * The query will have a form like:
353
+ * The query will have a form like::
354
354
*
355
- * struct entry *latch_query(struct latch_struct *latch, ...)
356
- * {
357
- * struct entry *entry;
358
- * unsigned seq, idx;
355
+ * struct entry *latch_query(struct latch_struct *latch, ...)
356
+ * {
357
+ * struct entry *entry;
358
+ * unsigned seq, idx;
359
359
*
360
- * do {
361
- * seq = raw_read_seqcount_latch(&latch->seq);
360
+ * do {
361
+ * seq = raw_read_seqcount_latch(&latch->seq);
362
362
*
363
- * idx = seq & 0x01;
364
- * entry = data_query(latch->data[idx], ...);
363
+ * idx = seq & 0x01;
364
+ * entry = data_query(latch->data[idx], ...);
365
365
*
366
- * smp_rmb();
367
- * } while (seq != latch->seq);
366
+ * smp_rmb();
367
+ * } while (seq != latch->seq);
368
368
*
369
- * return entry;
370
- * }
369
+ * return entry;
370
+ * }
371
371
*
372
372
* So during the modification, queries are first redirected to data[1]. Then we
373
373
* modify data[0]. When that is complete, we redirect queries back to data[0]
374
374
* and we can modify data[1].
375
375
*
376
- * NOTE: The non-requirement for atomic modifications does _NOT_ include
377
- * the publishing of new entries in the case where data is a dynamic
378
- * data structure.
376
+ * NOTE:
377
+ *
378
+ * The non-requirement for atomic modifications does _NOT_ include
379
+ * the publishing of new entries in the case where data is a dynamic
380
+ * data structure.
381
+ *
382
+ * An iteration might start in data[0] and get suspended long enough
383
+ * to miss an entire modification sequence, once it resumes it might
384
+ * observe the new entry.
379
385
*
380
- * An iteration might start in data[0] and get suspended long enough
381
- * to miss an entire modification sequence, once it resumes it might
382
- * observe the new entry.
386
+ * NOTE:
383
387
*
384
- * NOTE: When data is a dynamic data structure; one should use regular RCU
385
- * patterns to manage the lifetimes of the objects within.
388
+ * When data is a dynamic data structure; one should use regular RCU
389
+ * patterns to manage the lifetimes of the objects within.
386
390
*/
387
391
static inline void raw_write_seqcount_latch (seqcount_t * s )
388
392
{
0 commit comments