maxkabakov - Fotolia
The Storage Networking Industry Association developed the NVM Programming Model to address the proliferation of non-volatile memory functionality and technologies. The specification provides NVM producers and consumers with a standards-based approach to building storage and memory system architectures. To this end, the spec defines recommended behavior for software that interfaces with NVM devices.
SNIA's most recent NVM Programming Model specification, version 1.2, published in 2017 doesn't describe a specific API. Instead, the specification recommends how interactions should be carried out between user space and OS kernel components that support NVM. The goal is to enable common NVM behavior across multiple OS interfaces that interact with NVM devices, such as SSDs, PCI cards and other solid-state non-volatile devices, including those accessed as memory.
The specification focuses on software elements that expose NVM as a hardware abstraction in the OS kernel -- such as a volume -- or data abstraction to user space applications -- such as a file. The specification describes how to discover, connect to and use NVM media, including behaviors that enable software to access and recover data.
NVM programming modes
SNIA organized the specification around four NVM programming modes that describe recommended behavior for NVM programming interfaces. The four modes address block storage, file storage, persistent memory volumes and PM files.
NVM.BLOCK. The first programming mode, NVM.BLOCK, is specific to software that accesses NVM block storage devices. A device might be exposed through one or more volumes, with each volume providing a range of logically contiguous blocks. OS components, such as file systems, can use the NVM.BLOCK mode to discover and access block storage features. Applications able to interact directly with block storage can also use this mode. In either scenario, the NVM device requires an NVM block-capable driver that provides the command interface to the device.
NVM.FILE. The second programming mode, NVM.FILE, also applies to software accessing NVM block storage devices or their volumes. This mode is specific to applications that can't interface directly with block storage and instead rely on native file I/O behavior to access storage through a file system. The approach is common to many applications. The file system interfaces with the NVM block-capable driver using the NVM.BLOCK mode, which in turn enables access to the NVM device.
NVM.PM.VOLUME. The third mode is NVM.PM.VOLUME, which is specific to OS components that access persistent memory volumes. These components can include file systems or pseudo-block devices, whose functionality is based on PM access. The mode serves as a software abstraction layer for PM devices, profiling attributes such as the physical address ranges associated with each volume. Similar to the NVM.BLOCK mode, the NVM.PM.VOLUME mode requires a PM-capable driver.
NVM.PM.FILE. The final mode is NVM.PM.FILE. It enables user space applications to directly access NVM devices as memory. For example, a PM-aware file system might export an API based on the NVM.PM.FILE mode. The API can then be consumed by user space applications to access the file system, which, in turn, access the PM devices via an NVM PM-capable driver. The NVM.PM.FILE mode defines actions such as mapping PM files to virtual memory addresses or syncing portions of PM files to the persistence domain (the point at which data is in a persistent state).
For each mode, the specification defines actions, attributes and use cases that detail the mode's behavior. Each action and attribute is classified as either mandatory or optional. If mandatory, it must be included in the software to be considered NVM Programming Model-compliant.
An action refers to an operation that represents or interacts with an NVM device. An action is either specific to a mode or part of the COMMON domain, which means it applies to multiple modes. All actions are identified with three-part names:
The <context> component is always NVM, and the <mode> component is the name of a mode, unless it is part of the COMMON domain, in which case, the COMMON keyword is used. The <verb> component refers to the specific action. For example, the NVM.BLOCK mode includes NVM.BLOCK.ATOMIC_WRITE, a mandatory action for ensuring consistent behavior during a power failure condition.
Attributes provide information about an NVM device's properties and capabilities. Like actions, attributes are identified with three-part names:
The <context> and <mode> components are the same as actions. The <noun> component represents the name of the property or capability. For example, the NVM.BLOCK mode includes the mandatory attribute NVM.BLOCK.EXISTS_CAPABLE, which indicates whether the device supports the NVM.BLOCK.EXISTS action.
A use case describes a scenario that accomplishes a goal. Each use case identifies its purpose and context, along with triggers and preconditions that explain when the use case applies. The use case also describes inputs, outputs, events and actions, and it provides references to related information.
For example, the NVM.BLOCK mode includes a use case for implementing flash-based NVM as a data cache. The use case describes how flash's fast random I/O performance and non-volatility make it a good candidate as a data cache and then explains how the cache manager can use the solid-state cache to improve performance and maintain persistence.
Complying with the standards
To achieve compliance, an NVM interface must provide documentation that maps NVM Programming Model actions and attributes to their counterparts in the implementation. However, integrating the standard shouldn't affect other aspects of the implementation. The goal is to use NVM media as effectively as possible, while enhancing interoperability across storage systems. To this end, the NVM Programming Model provides recommended behavior for NVM programming interfaces, without describing a specific API or deprecating existing modes of NVM access.