-static void rseq_fallback_unlock(struct rseq_lock *rlock, int cpu_at_start)
-{
- /*
- * Concurrent rseq arriving before we set state back to RESTART
- * grab the lock. Those arriving after we set state back to
- * RESTART will perform restartable critical sections. The next
- * owner of the lock will take take of making sure it prevents
- * concurrent restartable sequences from completing. We may be
- * writing from another CPU, so update the state with a store
- * release semantic to ensure restartable sections will see our
- * side effect (writing to *p) before they enter their
- * restartable critical section.
- *
- * In cases where we observe that we are on the right CPU after the
- * critical section, program order ensures that following restartable
- * critical sections will see our stores, so we don't have to use
- * store-release or membarrier.
- *
- * Use sys_membarrier when available to remove the memory barrier
- * implied by smp_load_acquire().
- */
- barrier();
- if (likely(rseq_current_cpu() == cpu_at_start)) {
- ACCESS_ONCE(rlock->state) = RSEQ_LOCK_STATE_RESTART;
- } else {
- if (!has_fast_acquire_release() && rseq_has_sys_membarrier) {
- if (membarrier(MEMBARRIER_CMD_SHARED, 0))
- abort();
- ACCESS_ONCE(rlock->state) = RSEQ_LOCK_STATE_RESTART;
- } else {
- /*
- * Store with release semantic to ensure
- * restartable sections will see our side effect
- * (writing to *p) before they enter their
- * restartable critical section. Matches
- * smp_load_acquire() in rseq_start().
- */
- smp_store_release(&rlock->state,
- RSEQ_LOCK_STATE_RESTART);
- }