We might have heard about queues in Nvme often. In fact whenever we hear Nvme, the word queues is bound to come with it since nothing is complete in the Nvme protocol without the queues, there are the basic building blocks of the protocol
We can envision queues as a conduit through which commands flow in and out, analogous to water moving through a pipe, with the commands waiting in line akin to the water inside
Queus plays a significant role in the performance optimization for devices which makes the use of Nvme protocol.
Further, these queues are based on Submission and Completion mechanism.
Commands are places by host in the submission queue. Let us consider host as a computer here
Responses will be placed in the associated completion queue by the controller. Controller is like a brain of the device, for e.g SSD
Further there are different types of queues : –
- Submission Queue (SQ): This queue is utilized by the host to dispatch commands.
- Completion Queue (CQ): In this queue, the device deposits completion entries after executing commands received from the Submission Queue (SQ). It contains the status of the commands from the SQ, indicating whether they were executed successfully or encountered errors.
- Admin SQ and CQ: These queues are designated for administrative tasks, housing commands from the admin command set. These commands pertain to tasks such as device initialization, command aborting, and namespace management.
- I/O SQ and CQ: Commands related to I/O operations, such as read and write operations between the host and the device, are placed in these queues
Now what is the depth of my Queue ?
Queue depth refers to the maximum number of outstanding commands that a storage device can manage concurrently. It signifies the upper limit of commands that can be queued by the NVMe controller at any given moment.
To illustrate, we can liken queue depth to a stack of pancakes, with commands lined up one after the other, being processed and placed on the plate.
Now lets talk about two very important terms – Head and Tail
Consider the depiction above as a queue, where each block represents a command in the queue. The tail indicates the next available element, while the head points to the next element to be removed from the queue.
The entity submitting the entries utilizes the Tail pointer to locate the next available queue slot. After placing the new entry into the open queue slot, the submitter increments the tail pointer. If the increment of the tail pointer exceeds the queue size, it cycles back to zero.
The recipient of the entries utilizes the current head entry pointer to locate the slot holding the next entry for consumption. After consuming the next entry from the queue, the recipient increments the head entry pointer. If the increment of the head entry pointer exceeds the size, it rolls back to zero.
So, you may ask now, are there any advantages of have a queue based mode, the answer is “yes” and there are many, some of them are
- Tasks can be performed concurrently, as NVMe permits the simultaneous creation of multiple Submission Queues (SQ) and Completion Queues (CQ), each capable of accommodating thousands of commands. For instance, there can be up to 65,535 I/O queues with a maximum of 64K outstanding commands.
- In contemporary systems with multiple cores, each core can possess its own autonomous queue, facilitating efficient utilization of the queues.
- Numerous operations within the NVMe device are handled independently by the controller, thereby alleviating the workload on the CPU.