While porting the smp_mb() patch from LU-9210 to the linux clients
Neil asked that the smp_wb() be replaced with the full memory
barrier functions smp_store_release() and smp_load_acquire(). For
this case _sa_make_ready() sets the entry->se_state and
revalidate_statahead_dentry() tests the value of entry->se_state
after waiting on sai_waitq. This change will make it obvious which
variable was important, and would show the paired synchronization
points. An additional benefit is that code will work on platforms
that are not "total store order" TSO architectures like PowerPC.
Change-Id: I687177bf1697a21db624a289c136215af4d90506
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/33571
Tested-by: Jenkins
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
}
}
list_add(&entry->se_list, pos);
- entry->se_state = ret < 0 ? SA_ENTRY_INVA : SA_ENTRY_SUCC;
+ /*
+ * LU-9210: ll_statahead_interpet must be able to see this before
+ * we wake it up
+ */
+ smp_store_release(&entry->se_state, ret < 0 ? SA_ENTRY_INVA : SA_ENTRY_SUCC);
return (index == sai->sai_index_wait);
}
}
sai->sai_replied++;
- smp_mb();
if (waitq != NULL)
wake_up(waitq);
spin_unlock(&lli->lli_sa_lock);
}
}
- if (entry->se_state == SA_ENTRY_SUCC && entry->se_inode != NULL) {
+ /*
+ * We need to see the value that was set immediately before we
+ * were woken up.
+ */
+ if (smp_load_acquire(&entry->se_state) == SA_ENTRY_SUCC &&
+ entry->se_inode) {
struct inode *inode = entry->se_inode;
struct lookup_intent it = { .it_op = IT_GETATTR,
.it_lock_handle =