I thought I kind of understood how pserialize(9) works, but the manual confused me:
mutex_enter(&writer_psz_lock); /* * Perform the updates (e.g. remove data items from a list). */ ... pserialize_perform(object->psz); /* * At this point it is safe to destroy old data items. */ mutex_exit(&writer_psz_lock); My understanding is that, writers can update data structures between mutex_enter() and pserialize_perform(), but that operation must be done atomically, because at that point readers are still reading the protected data. In pserialize_perform(), context switches are made on all CPUs. After pserialize_perform(), all readers on all CPUs see the update data. The data old data item is safely destroyed. In the TAILQ case, where readers iterate a list by TAILQ_FOREACH(), TAILQ_REMOVE() is safely used as the update operation, because: - Readers only see tqe_next in TAILQ_FOREACH(), and - Pointer assignment (done in TAILQ_REMOVE()) is atomic. If this is correct, pserialize(9) should be updated to be clearer; probably this TAILQ example is worth being added there.