Better: rcu_read_lock(); do { pgtbl = d->cur_pgtbl; smp_rmb(); root = d->cur_root; smp_rmb();
/* d->cur_pgtbl == d->next_pgtbl only during an update. */ } while (pgtbl == d->next_pgtbl); ... rcu_read_unlock(); And in the writer: old_pgtbl = d->cur_pgtbl; /* Point to the new page table, tell readers cur_root is invalid. */ smp_wmb(); d->cur_pgtbl = d->next_pgtbl; /* Write the root before updating the page table. */ smp_wmb(); d->cur_root = d->next_root; /* Write cur_root before telling readers it is valid. */ smp_wmb(); d->next_pgtbl = NULL; /* Drop reference once readers will be done with it. */ call_rcu(page_table_unref, old_pgtbl, rcu); Paolo