Patent Description:
In most cases, before using this pointer, the compute device converts the pointer to the local virtual address space with the memory management unit (MMU) page table mapping. This renders the sharing of the pointer itself or of structures containing pointers inefficient and challenging.

<CIT>) discloses a system and method of device assignment including receiving, by a supervisor, an assignment request to assign a device to a first application and a second application. The first application is associated with a first memory and the second application is associated with a second memory. The supervisor sends bus address offsets to each of the applications and updates an I/O mapping with the bus address offsets.

In the following description, numerous specific details are set forth to provide a thorough understanding of the methods and mechanisms presented herein. However, one having ordinary skill in the art should recognize that the various implementations may be practiced without these specific details. In some instances, well-known structures, components, signals, computer program instructions, and techniques have not been shown in detail to avoid obscuring the approaches described herein. For example, the dimensions of some of the elements may be exaggerated relative to other elements.

Systems, apparatuses, and methods for implementing a unified kernel virtual address space for heterogeneous computing are disclosed herein. In one implementation, a system includes at least a first subsystem running a first kernel, an input/output memory management unit (IOMMU), and a second subsystem running a second kernel. In one implementation, the IOMMU creates a unified kernel address space allowing the first and second subsystems to share memory buffers at the kernel level. In order to share a memory buffer between the two subsystems, the first subsystem allocates a block of memory in part of the system memory controlled by the first subsystem. A first mapping is created from a first logical address of the first kernel address space of the first subsystem to the block of memory. Then, the IOMMU creates a second mapping to map the physical address of that block of memory from a second logical address of the second kernel address space of the second subsystem. These mappings allow the first and second subsystems to share buffer pointers in the kernel address space which reference the block of memory.

Referring now to <FIG>, a block diagram of one implementation of a computing system <NUM> is shown. In one implementation, computing system <NUM> includes at least first subsystem <NUM>, second subsystem <NUM>, input/output (I/O) interface(s) <NUM>, input/output memory management unit (IOMMU) <NUM>, memory subsystem <NUM>, and peripheral device(s) <NUM>. In other implementations, computing system <NUM> can include other components and/or computing system <NUM> can be arranged differently.

In one implementation, first and second subsystems <NUM> and <NUM> have different kernel address spaces, but a unified kernel address space is created by IOMMU <NUM> for the first and second subsystems <NUM> and <NUM>. The unified kernel address space allows the first and second subsystems <NUM> and <NUM> to pass pointers between each other and share buffers. For first subsystem <NUM> and second subsystem <NUM>, their respective kernel address space includes kernel logical addresses and kernel virtual addresses. On some architectures, a kernel logical address and its associated physical address differ by a constant offset. Kernel virtual addresses do not necessarily have a linear, one-to-one mapping to physical addresses that characterize kernel logical addresses. All kernel logical addresses are kernel virtual addresses, but kernel virtual addresses are not necessarily kernel logical addresses.

In one implementation, each of first subsystem <NUM> and second subsystem <NUM> includes one or more processors which execute an operating system. The processor(s) also execute one or more software programs in various implementations. The processor(s) of first subsystem <NUM> and second subsystem <NUM> include any number and type of processing units (e.g., central processing unit (CPU), graphics processing unit (GPU), digital signal processor (DSP), field programmable gate array (FPGA), application specific integrated circuit (ASIC)). Also, first subsystem <NUM> includes memory management unit (MMU) <NUM> and second subsystem <NUM> includes MMU <NUM>, with each MMU handling virtual to physical address translations for its corresponding subsystem. While first and second subsystems <NUM> and <NUM> have different kernel address spaces, a unified kernel address space is created by IOMMU <NUM> for the first and second subsystems <NUM> and <NUM>, allowing the first and second subsystems <NUM> and <NUM> to pass pointers back and forth and share buffers in memory subsystem <NUM>.

Memory subsystem <NUM> includes any number and type of memory devices. For example, the type of memory in memory subsystem <NUM> can include high-bandwidth memory (HBM), non-volatile memory (NVM), Dynamic Random Access Memory (DRAM), Static Random Access Memory (SRAM), NAND Flash memory, NOR flash memory, Ferroelectric Random Access Memory (FeRAM), or others. I/O interfaces <NUM> are representative of any number and type of I/O interfaces (e.g., peripheral component interconnect (PCI) bus, PCI-Extended (PCI-X), PCIE (PCI Express) bus, gigabit Ethernet (GBE) bus, universal serial bus (USB)). Various types of peripheral devices <NUM> can be coupled to I/O interfaces <NUM>. Such peripheral devices <NUM> include (but are not limited to) displays, keyboards, mice, printers, scanners, joysticks or other types of game controllers, media recording devices, external storage devices, network interface cards, and so forth.

In one implementation, in order to create a memory space that is shared between first subsystem <NUM> and second subsystem <NUM>, a block of memory is allocated in a part of system memory managed by first subsystem <NUM>. After the initial block of memory is allocated, the proper I/O virtual address (VA) is assigned to the second subsystem <NUM>. In one implementation, an IOMMU mapping is created from the kernel address space of second subsystem <NUM> to the physical address of the block of memory. In this implementation, IOMMU <NUM> performs the virtual address mapping for the second subsystem <NUM> to the block of memory. Then, when additional memory is allocated, the heap allocate function is called, and the address is mapped based on the same I/O VA address that was earlier created. Then, a message is sent to the second subsystem <NUM> notifying the second subsystem <NUM> of the unified address.

In various implementations, computing system <NUM> is a computer, laptop, mobile device, game console, server, streaming device, wearable device, or any of various other types of computing systems or devices. It is noted that the number of components of computing system <NUM> varies from implementation to implementation. In other implementations, there are more or fewer of each component than the number shown in <FIG>. It is also noted that in other implementations, computing system <NUM> includes other components not shown in <FIG>. Additionally, in other implementations, computing system <NUM> is structured in other ways than shown in <FIG>.

Turning now to <FIG>, a diagram of one implementation of creating a unified kernel virtual address space for heterogeneous computing is shown. The dashed vertical lines from the top of <FIG>, from left to right, are representative of a first subsystem <NUM>, a MMU <NUM> of the first subsystem <NUM>, a device driver <NUM> executing on the first subsystem <NUM>, a shared region <NUM> of memory, an IOMMU <NUM>, a MMU <NUM> of a second subsystem <NUM>, and the second subsystem <NUM>. It is assumed for the purposes of this discussion that first subsystem <NUM> has a first operating system, that second subsystem <NUM> has a second operating system, and that the second operating system is different from the first operating system. It is also assumed for the purposes of this discussion that the first subsystem <NUM> and the second subsystem <NUM> are part of a heterogeneous computing system. In one implementation, for this heterogeneous computing system, first subsystem <NUM> and second subsystem <NUM> are each performing some portion of a workload, and in order to perform the workload, first subsystem <NUM> and second subsystem <NUM> share buffer pointers and buffers between each other. The diagram of <FIG> illustrates one example of allocating memory to be shared between first subsystem <NUM> and second subsystem <NUM>.

In one implementation, a first step <NUM> is performed by device driver <NUM> to create a heap (i.e., a shared memory region). As used herein, the term "heap" is defined as a virtual memory pool that is mapped to a physical memory pool. Next, in step <NUM>, a desired size of the heap is allocated in the physical memory subsystem. In step <NUM>, a mapping from the kernel to the heap is created. In one implementation, when the carveout heap is first created, a new flag indicates if the heap should come from the kernel logical address space. For example, the kmalloc function returns memory in the kernel logical address space. In one implementation, for a Linux® operating system, the memory manager manages the buffer allocated for the heap using the Linux genpool library. In this implementation, when a buffer is allocated, the buffer is marked in the internal pool and the physical address is returned. The carveout heap then wraps this physical address with the buffer and sg_table descriptors. In one implementation, when the buffer is mapped in the kernel address space, the heap_map_kernel function maps the buffer using kmap instead of vmap in step <NUM>. The function kmap maps the buffer to a given virtual address based on a logical mapping. The selection of kmap or vmap is controlled by a new flag given during carveout heap creation. Alternatively, the heap is created together with the kernel mapping using the genpool library, the carveout application programming interface (API), and the new flag. In this case, the kernel map returns the pre-mapped address. User mode mapping will still be applied on the fly. For second subsystem <NUM>, any shared memory buffer allocated by first subsystem <NUM> is managed similar to the carveout heap wrapped genpool. The new API allows the addition of an external buffer to the carveout heap. Local tasks on second subsystem <NUM> allocate from this carveout heap using the same API. After step <NUM>, the allocation of the shared memory region is complete.

Next, in step <NUM>, an input/output (I/O) virtual address is allocated by IOMMU <NUM> for the shared memory region. Then, in step <NUM>, a contiguous block of DMA address space is reserved for the shared memory region. Next, in step <NUM>, the shared memory region is mapped by IOMMU <NUM> to the kernel address space of second subsystem <NUM>. It is noted that the IOMMU mapping should not be freed until the device driver <NUM> has been shutdown. The mapping from the kernel address space of first subsystem <NUM> to the shared memory region is invalidated in step <NUM>. Then, in step <NUM>, the kernel address space mapping is freed by executing a memory release function.

Referring now to <FIG>, a diagram of one implementation of sharing buffers between two separate subsystems is shown. The dashed vertical lines extending down from the top of <FIG>, from left to right, are representative of a first subsystem <NUM>, a MMU <NUM> of the first subsystem <NUM>, a device driver <NUM> executing on the first subsystem <NUM>, a shared region <NUM> of memory, an IOMMU <NUM>, a MMU <NUM> of a second subsystem <NUM>, and the second subsystem <NUM>. It is assumed for the purposes of this discussion that first subsystem <NUM> has a first operating system, second subsystem <NUM> has a second operating system, and the second operating system is different from the first operating system.

For loop exchange <NUM>, a block of memory is allocated and a mapping from the kernel address space of first subsystem <NUM> to the physical address of the memory block is created by device driver <NUM>. The mapping is then maintained by MMU <NUM>. The memory block can be assigned to second subsystem <NUM> exclusively, shared between first subsystem <NUM> and second subsystem <NUM>, or assigned to first subsystem <NUM> exclusively. Then, a message is sent from first subsystem <NUM> to second subsystem <NUM> with the address and size of the block of memory. In one implementation, the message can be sent out-of-band. After the message is received by second subsystem <NUM>, a mapping from the kernel address space of second subsystem <NUM> to the physical address of the memory block is created and maintained by MMU <NUM>. For loop exchange <NUM>, data is exchanged between first subsystem <NUM> and second subsystem <NUM> using the shared region <NUM>. With the unified kernel virtual address, the buffer pointers <NUM>st_SS_buf and <NUM>nd_SS_buf are the same and can be freely exchanged between first subsystem <NUM> and second subsystem <NUM> and further partitioned using the genpool library.

Turning now to <FIG>, a diagram of one implementation of mapping regions of memory to multiple kernel address spaces is shown. In one implementation, a heterogeneous computing system (e.g., system <NUM> of <FIG>) includes multiple different subsystems with their own independent operating systems. The vertically oriented rectangular blocks shown in <FIG> are representative of the address spaces for the different components of the heterogeneous computing system. From left to right, the address spaces shown in <FIG> are: first subsystem virtual address space <NUM>, physical memory space <NUM>, device memory space <NUM>, and second subsystem virtual address space <NUM>.

In one implementation, first subsystem virtual address space <NUM> includes shared region <NUM> which is mapped to memory block <NUM> and memory block <NUM> of physical memory space <NUM>. In one implementation, the mappings of shared region <NUM> to memory block <NUM> and memory block <NUM> are created and maintained by first subsystem MMU <NUM>. In order to allow shared region <NUM> to be shared with the second subsystem, memory block <NUM> and memory block <NUM> are mapped to shared region <NUM> of device memory space <NUM> by IOMMU <NUM>. Then, shared region <NUM> is mapped to shared region <NUM> of second subsystem virtual address space <NUM> by second subsystem MMU <NUM>. Through this mapping scheme, the first subsystem and the second subsystem are able to share buffer pointers with each other in their kernel address space.

Referring now to <FIG>, one implementation of a method <NUM> for creating a unified kernel virtual address space is shown. For purposes of discussion, the steps in this implementation and those of <FIG> are shown in sequential order. However, it is noted that in various implementations of the described methods, one or more of the elements described are performed concurrently, in a different order than shown, or are omitted entirely. Other additional elements are also performed as desired. Any of the various systems or apparatuses described herein are configured to implement method <NUM>.

A first subsystem allocates a block of memory at a first physical address in a physical address space corresponding to a memory subsystem (block <NUM>). In one implementation, the first subsystem executes a first operating system with a first kernel address space. Next, the first subsystem creates a mapping of a first logical address in the first kernel address space to the first physical address (block <NUM>). It is noted that the first logical address space of the first kernel address space is a first linear offset from the first physical address. Then, an IOMMU creates an IOMMU mapping of a second logical address in a second kernel address space to the first physical address (block <NUM>). In one implementation, the second kernel address space is associated with a second subsystem. It is noted that the second logical address space of the second kernel address space is a second linear offset from the first physical address.

Next, the first subsystem conveys a buffer pointer to the second subsystem, where the buffer pointer points to the first logical address (block <NUM>). Then, the second subsystem generates an access request with the buffer pointer and conveys the access request to the IOMMU (block <NUM>). Next, the IOMMU translates a virtual address of the buffer pointer to the first physical address using the previously created IOMMU mapping (block <NUM>). Then, the second subsystem accesses the block of memory at the first physical address (block <NUM>). After block <NUM>, method <NUM> ends.

Turning now to <FIG>, one implementation of a method <NUM> for enabling a common shared region in multiple kernel address spaces is shown. A first subsystem allocates a block of memory at a first physical address in a physical address space corresponding to a memory subsystem (block <NUM>). It is assumed for the purposes of this discussion that the system described by method <NUM> includes the first subsystem and a second subsystem. It is also assumed that the first subsystem executes a first operating system with a first kernel address space and the second subsystem executes a second operating system with a second kernel address space. The first subsystem creates a mapping of a first logical address in the first kernel address space to the first physical address, where the first logical address in the first kernel address space is a first offset away from the first physical address (block <NUM>).

Next, an IOMMU selects a device address that is a second offset away from the first logical address in the second kernel address space (block <NUM>). Then, the IOMMU creates an IOMMU mapping of the selected device address in the device address space to the first physical address (block <NUM>). The IOMMU mapping enables a common shared region in both the first kernel address space and the second kernel address space for use by both the first subsystem and the second subsystem (block <NUM>). After block <NUM>, method <NUM> ends.

Referring now to <FIG>, one implementation of a method <NUM> for enabling buffer pointer sharing between two different subsystems is shown. A first subsystem maps a first region of a first kernel address space to a second region in physical address space (block <NUM>). In one implementation, the physical address space corresponds to a system memory controlled by the first subsystem. Next, an IOMMU maps a third region of a second kernel address space to a fourth region in a device address space (block <NUM>). It is assumed for the purposes of this discussion that the second kernel address space corresponds to a second subsystem which is different from the first subsystem. Then, the IOMMU maps the fourth region in the device address space to the second region in the physical address space to cause addresses in the first and third regions to point to matching (i.e., identical) addresses in the second region (block <NUM>). The first subsystem and second subsystem are able to share buffer pointers in the first or second kernel address spaces that reference the second region in physical address space (block <NUM>). After block <NUM>, method <NUM> ends.

Claim 1:
A system, comprising:
a memory subsystem;
a first subsystem (<NUM>) with a first kernel address space;
a second subsystem (<NUM>) with a second kernel address space; and
an input/output memory management unit, IOMMU, (<NUM>);
wherein the system is configured to:
allocate (<NUM>), by the first subsystem, a block of memory at a first physical address in a physical address space corresponding to the memory subsystem; characterised in that the system is further configured to:
create (<NUM>), by the first subsystem, a mapping of a first logical address in the first kernel address space to the first physical address, wherein the first logical address in the first kernel address space is a first offset away from the first physical address;
select (<NUM>), by the IOMMU (<NUM>), a device address that is a second offset away from the first logical address in the second kernel address space;
create (<NUM>) an IOMMU mapping of the selected device address in the device address space to the first physical address; and
enable (<NUM>), with the IOMMU mapping, a common shared region in both the first kernel address space and the second kernel address space for use by both the first subsystem and the second subsystem.