void fsverity_set_info(struct inode *inode, struct fsverity_info *vi)
 {
        /*
-        * Multiple processes may race to set ->i_verity_info, so use cmpxchg.
-        * This pairs with the READ_ONCE() in fsverity_get_info().
+        * Multiple tasks may race to set ->i_verity_info, so use
+        * cmpxchg_release().  This pairs with the smp_load_acquire() in
+        * fsverity_get_info().  I.e., here we publish ->i_verity_info with a
+        * RELEASE barrier so that other tasks can ACQUIRE it.
         */
-       if (cmpxchg(&inode->i_verity_info, NULL, vi) != NULL)
+       if (cmpxchg_release(&inode->i_verity_info, NULL, vi) != NULL) {
+               /* Lost the race, so free the fsverity_info we allocated. */
                fsverity_free_info(vi);
+               /*
+                * Afterwards, the caller may access ->i_verity_info directly,
+                * so make sure to ACQUIRE the winning fsverity_info.
+                */
+               (void)fsverity_get_info(inode);
+       }
 }
 
 void fsverity_free_info(struct fsverity_info *vi)
 
 
 static inline struct fsverity_info *fsverity_get_info(const struct inode *inode)
 {
-       /* pairs with the cmpxchg() in fsverity_set_info() */
-       return READ_ONCE(inode->i_verity_info);
+       /*
+        * Pairs with the cmpxchg_release() in fsverity_set_info().
+        * I.e., another task may publish ->i_verity_info concurrently,
+        * executing a RELEASE barrier.  We need to use smp_load_acquire() here
+        * to safely ACQUIRE the memory the other task published.
+        */
+       return smp_load_acquire(&inode->i_verity_info);
 }
 
 /* enable.c */