A driver writes a command to a device's register to start a transfer, then immediately reads a status register to check the device is busy. Sometimes the status says "idle", as if the command never arrived. It did arrive, a moment later. The write had been posted: the driver was free to carry on before the write reached the device, and nothing guaranteed it had.
What does it mean for a write to be posted, and when is that a problem?
The obvious write waits for an acknowledgement: send the address and data, wait for "done", carry on. That is safe and slow: every write costs a round trip, which (lesson 5.1) a write does not otherwise need. So many protocols let writes go without an answer. That is fast, but the writer then knows nothing about when, or even whether, the write completed.
Posted | Non-posted | |
|---|---|---|
Response | None | A completion, with status (and data for a read) |
The requester continues | As soon as the write is handed off | After the completion arrives |
Cost per transaction | No round trip | One round trip |
Error reporting | No status to the requester; errors go elsewhere (an error log, an interrupt) | The status comes back with the completion |
Knows when it finished | No | Yes |
Used for | Memory writes, messages | Reads, configuration and I/O accesses, atomics |
Error reporting to the requester. If a posted write fails, the requester never hears. The error must be logged or signalled some other way.
Knowing when it landed. The requester cannot tell whether the write has reached the target. To be sure, it must follow up with a non-posted access that is ordered behind the write: classically, a read from the same device, which cannot complete until earlier posted writes to it have landed, if the protocol orders reads behind posted writes (Part 7).
Flow-control simplicity. A posted write that cannot be accepted cannot be refused with a status; it can only wait in a buffer, so buffers for posted writes need their own credits (lesson 4.6).
That follow-up read is why the opening driver should read back from the device after starting it, and why the protocol's ordering rules matter as much as the posting rule itself.
Configuration writes, which can change where a device sits in the address map. Software must know the change is done before it uses the new address.
Writes whose failure software must see at once, such as some I/O accesses.
Atomics, which return the old value (lesson 5.13).
Protocol | Posting |
|---|---|
PCI Express | Memory writes are posted. Configuration writes and reads are non-posted and get completions. Message-signalled interrupts are posted memory writes (lesson 5.15). |
AXI | Every write gets a response on the write response channel. An interconnect may answer early from a buffer (an early acknowledgement, lesson 7.4), which behaves much like posting. |
DCLink | Writes are non-posted: every WR gets a CPL. |
The opening story: a driver issued a posted write to start a device, then read the device's status through a different path that was not ordered behind the write. The status read overtook the write. Reading back from the same device, through the same path, would have flushed the write first. The general rule: after a posted write that matters, use a non-posted access that the protocol guarantees is ordered after it.
Posted: about the time to send them, plus one trip for the last to land. Non-posted, one at a time: about 100 round trips, roughly 100 µs.
Because the protocol does not let a read pass earlier posted writes on the same path; the read's completion cannot return until those writes have reached the device.
A posted write gets no response: no round trip, but no status and no knowledge of when it landed.
To be sure a posted write landed, follow it with a non-posted access the protocol orders behind it, such as a read from the same device.
Configuration accesses, reads and atomics are non-posted because the requester needs their result or their status.