@@ -319,6 +319,99 @@ of the ASSERT_EXCLUSIVE_WRITER() is to allow KCSAN to check for a buggy
319319concurrent lockless write.
320320
321321
322+ Lock-Protected Writes With Heuristic Lockless Reads
323+ ---------------------------------------------------
324+
325+ For another example, suppose that the code can normally make use of
326+ a per-data-structure lock, but there are times when a global lock
327+ is required. These times are indicated via a global flag. The code
328+ might look as follows, and is based loosely on nf_conntrack_lock(),
329+ nf_conntrack_all_lock(), and nf_conntrack_all_unlock():
330+
331+ bool global_flag;
332+ DEFINE_SPINLOCK(global_lock);
333+ struct foo {
334+ spinlock_t f_lock;
335+ int f_data;
336+ };
337+
338+ /* All foo structures are in the following array. */
339+ int nfoo;
340+ struct foo *foo_array;
341+
342+ void do_something_locked(struct foo *fp)
343+ {
344+ /* This works even if data_race() returns nonsense. */
345+ if (!data_race(global_flag)) {
346+ spin_lock(&fp->f_lock);
347+ if (!smp_load_acquire(&global_flag)) {
348+ do_something(fp);
349+ spin_unlock(&fp->f_lock);
350+ return;
351+ }
352+ spin_unlock(&fp->f_lock);
353+ }
354+ spin_lock(&global_lock);
355+ /* global_lock held, thus global flag cannot be set. */
356+ spin_lock(&fp->f_lock);
357+ spin_unlock(&global_lock);
358+ /*
359+ * global_flag might be set here, but begin_global()
360+ * will wait for ->f_lock to be released.
361+ */
362+ do_something(fp);
363+ spin_unlock(&fp->f_lock);
364+ }
365+
366+ void begin_global(void)
367+ {
368+ int i;
369+
370+ spin_lock(&global_lock);
371+ WRITE_ONCE(global_flag, true);
372+ for (i = 0; i < nfoo; i++) {
373+ /*
374+ * Wait for pre-existing local locks. One at
375+ * a time to avoid lockdep limitations.
376+ */
377+ spin_lock(&fp->f_lock);
378+ spin_unlock(&fp->f_lock);
379+ }
380+ }
381+
382+ void end_global(void)
383+ {
384+ smp_store_release(&global_flag, false);
385+ spin_unlock(&global_lock);
386+ }
387+
388+ All code paths leading from the do_something_locked() function's first
389+ read from global_flag acquire a lock, so endless load fusing cannot
390+ happen.
391+
392+ If the value read from global_flag is true, then global_flag is
393+ rechecked while holding ->f_lock, which, if global_flag is now false,
394+ prevents begin_global() from completing. It is therefore safe to invoke
395+ do_something().
396+
397+ Otherwise, if either value read from global_flag is true, then after
398+ global_lock is acquired global_flag must be false. The acquisition of
399+ ->f_lock will prevent any call to begin_global() from returning, which
400+ means that it is safe to release global_lock and invoke do_something().
401+
402+ For this to work, only those foo structures in foo_array[] may be passed
403+ to do_something_locked(). The reason for this is that the synchronization
404+ with begin_global() relies on momentarily holding the lock of each and
405+ every foo structure.
406+
407+ The smp_load_acquire() and smp_store_release() are required because
408+ changes to a foo structure between calls to begin_global() and
409+ end_global() are carried out without holding that structure's ->f_lock.
410+ The smp_load_acquire() and smp_store_release() ensure that the next
411+ invocation of do_something() from do_something_locked() will see those
412+ changes.
413+
414+
322415Lockless Reads and Writes
323416-------------------------
324417
0 commit comments