Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

gdev: added ioctl functions for gmap() and gunmap()

gdev: fixed gmap() and gunmap() interfaces
cuda: fixed cuMemMap() and cuMemUnmap() interfaces
  • Loading branch information...
commit 474fa00623addce57b2b5cc345a11762e7fee139 1 parent 57f8b50
Shinpei Kato authored
View
14 common/gdev_api.c
@@ -778,23 +778,17 @@ uint64_t gfree_dma(struct gdev_handle *h, void *buf)
* gmap():
* map device memory to host DMA memory.
*/
-void *gmap(struct gdev_handle *h, uint64_t addr)
+void *gmap(struct gdev_handle *h, uint64_t addr, uint64_t size)
{
gdev_vas_t *vas = h->vas;
gdev_mem_t *mem;
- void *buf;
+ uint64_t offset;
if (!(mem = gdev_mem_lookup(vas, addr, GDEV_MEM_DEVICE)))
goto fail;
- buf = gdev_mem_get_buf(mem);
-
- /* if not mapped yet, map here. */
- if (!buf) {
- buf = gdev_mem_map(mem);
- }
-
- return buf;
+ offset = addr - gdev_mem_get_addr(mem);
+ return gdev_mem_map(mem, offset, size);
fail:
return NULL;
View
2  common/gdev_api.h
@@ -48,7 +48,7 @@ uint64_t gmalloc(Ghandle h, uint64_t size);
uint64_t gfree(Ghandle h, uint64_t addr);
void *gmalloc_dma(Ghandle h, uint64_t size);
uint64_t gfree_dma(Ghandle h, void *buf);
-void *gmap(Ghandle h, uint64_t addr);
+void *gmap(Ghandle h, uint64_t addr, uint64_t size);
int gunmap(Ghandle h, void *buf);
int gmemcpy_to_device(Ghandle h, uint64_t dst_addr, const void *src_buf, uint64_t size);
int gmemcpy_to_device_async(Ghandle h, uint64_t dst_addr, const void *src_buf, uint64_t size, uint32_t *id);
View
2  common/gdev_arch.h
@@ -77,7 +77,7 @@ gdev_mem_t *gdev_mem_alloc(gdev_vas_t *vas, uint64_t size, int type);
gdev_mem_t *gdev_mem_share(gdev_vas_t *vas, uint64_t size);
void gdev_mem_free(gdev_mem_t *mem);
void gdev_mem_gc(gdev_vas_t *vas);
-void *gdev_mem_map(gdev_mem_t *mem);
+void *gdev_mem_map(gdev_mem_t *mem, uint64_t offset, uint64_t size);
void gdev_mem_unmap(gdev_mem_t *mem);
gdev_mem_t *gdev_mem_lookup(gdev_vas_t *vas, uint64_t addr, int type);
void *gdev_mem_get_buf(gdev_mem_t *mem);
View
36 common/gdev_ioctl_def.h
@@ -36,20 +36,22 @@
#define GDEV_IOCTL_GFREE 0x101
#define GDEV_IOCTL_GMALLOC_DMA 0x102
#define GDEV_IOCTL_GFREE_DMA 0x103
-#define GDEV_IOCTL_GMEMCPY_TO_DEVICE 0x104
-#define GDEV_IOCTL_GMEMCPY_TO_DEVICE_ASYNC 0x105
-#define GDEV_IOCTL_GMEMCPY_FROM_DEVICE 0x106
-#define GDEV_IOCTL_GMEMCPY_FROM_DEVICE_ASYNC 0x107
-#define GDEV_IOCTL_GMEMCPY_IN_DEVICE 0x108
-#define GDEV_IOCTL_GLAUNCH 0x109
-#define GDEV_IOCTL_GSYNC 0x110
-#define GDEV_IOCTL_GBARRIER 0x111
-#define GDEV_IOCTL_GQUERY 0x112
-#define GDEV_IOCTL_GTUNE 0x113
-#define GDEV_IOCTL_GSHMGET 0x114
-#define GDEV_IOCTL_GSHMAT 0x115
-#define GDEV_IOCTL_GSHMDT 0x116
-#define GDEV_IOCTL_GSHMCTL 0x117
+#define GDEV_IOCTL_GMAP 0x104
+#define GDEV_IOCTL_GUNMAP 0x105
+#define GDEV_IOCTL_GMEMCPY_TO_DEVICE 0x106
+#define GDEV_IOCTL_GMEMCPY_TO_DEVICE_ASYNC 0x107
+#define GDEV_IOCTL_GMEMCPY_FROM_DEVICE 0x108
+#define GDEV_IOCTL_GMEMCPY_FROM_DEVICE_ASYNC 0x109
+#define GDEV_IOCTL_GMEMCPY_IN_DEVICE 0x110
+#define GDEV_IOCTL_GLAUNCH 0x111
+#define GDEV_IOCTL_GSYNC 0x112
+#define GDEV_IOCTL_GBARRIER 0x113
+#define GDEV_IOCTL_GQUERY 0x114
+#define GDEV_IOCTL_GTUNE 0x115
+#define GDEV_IOCTL_GSHMGET 0x116
+#define GDEV_IOCTL_GSHMAT 0x117
+#define GDEV_IOCTL_GSHMDT 0x118
+#define GDEV_IOCTL_GSHMCTL 0x119
struct gdev_ioctl_mem {
uint64_t addr;
@@ -95,4 +97,10 @@ struct gdev_ioctl_shm {
void *buf;
};
+struct gdev_ioctl_map {
+ uint64_t addr;
+ uint64_t buf;
+ uint64_t size;
+};
+
#endif
View
3  common/gdev_nvidia.h
@@ -187,6 +187,7 @@ struct gdev_mem {
uint64_t size; /* memory size */
int type; /* device or host dma? */
void *map; /* memory-mapped buffer */
+ int map_users; /* # of users referencing the map */
};
/**
@@ -233,7 +234,7 @@ void gdev_raw_swap_free(struct gdev_mem *mem);
struct gdev_mem *gdev_raw_mem_share(struct gdev_vas *vas, struct gdev_mem *mem, uint64_t *addr, uint64_t *size, void **map);
void gdev_raw_mem_unshare(struct gdev_mem *mem);
void *gdev_raw_mem_map(struct gdev_mem *mem);
-void gdev_raw_mem_unmap(struct gdev_mem *mem);
+void gdev_raw_mem_unmap(struct gdev_mem *mem, void *map);
uint32_t gdev_raw_read32(struct gdev_mem *mem, uint64_t addr);
void gdev_raw_write32(struct gdev_mem *mem, uint64_t addr, uint32_t val);
int gdev_raw_read(struct gdev_mem *mem, void *buf, uint64_t addr, uint32_t size);
View
25 common/gdev_nvidia_mem.c
@@ -40,7 +40,8 @@ void gdev_nvidia_mem_init(struct gdev_mem *mem, struct gdev_vas *vas, uint64_t a
mem->swap_mem = NULL;
mem->swap_buf = NULL;
mem->shm = NULL;
-
+ mem->map_users = 0;
+
gdev_list_init(&mem->list_entry_heap, (void *) mem);
gdev_list_init(&mem->list_entry_shm, (void *) mem);
}
@@ -223,16 +224,30 @@ void gdev_mem_gc(struct gdev_vas *vas)
}
/* map device memory to host DMA memory. */
-void *gdev_mem_map(struct gdev_mem *mem)
+void *gdev_mem_map(struct gdev_mem *mem, uint64_t offset, uint64_t size)
{
- mem->map = gdev_raw_mem_map(mem);
- return mem->map;
+ if (offset + size > mem->size)
+ return NULL;
+
+ /* @size is not really used here... */
+ if (mem->map_users == 0) {
+ mem->map = gdev_raw_mem_map(mem);
+ if (!mem->map)
+ return NULL;
+ }
+
+ mem->map_users++;
+ return mem->map + offset;
}
/* unmap device memory from host DMA memory. */
void gdev_mem_unmap(struct gdev_mem *mem)
{
- gdev_raw_mem_unmap(mem);
+ mem->map_users--;
+ if (mem->map_users == 0) {
+ gdev_raw_mem_unmap(mem, mem->map);
+ mem->map = NULL;
+ }
}
/* look up the memory object allocated at the specified address. */
View
5 cuda/driver_api/cuda.h
@@ -762,8 +762,9 @@ CUresult cuMemcpyDtoHAsync(void *dstHost, CUdeviceptr srcDevice, unsigned int By
CUresult cuMemcpyHtoD(CUdeviceptr dstDevice, const void *srcHost, unsigned int ByteCount);
CUresult cuMemcpyHtoDAsync(CUdeviceptr dstDevice, const void *srcHost, unsigned int ByteCount, CUstream hStream);
CUresult cuMemcpyDtoD(CUdeviceptr dstDevice, CUdeviceptr srcDevice, unsigned int ByteCount);
-CUresult cuMemMap(void **buf, CUdeviceptr dptr); /* Gdev extension */
-CUresult cuMemUnmap(void *buf); /* Gdev extension */
+/* Memory mapping - Gdev extension */
+CUresult cuMemMap(void **buf, CUdeviceptr dptr, unsigned int bytesize);
+CUresult cuMemUnmap(void *buf);
/* Inter-Process Communication (IPC) - Gdev extension */
CUresult cuShmGet(int *ptr, int key, size_t size, int flags);
View
6 cuda/driver_api/memory.c
@@ -364,7 +364,7 @@ CUresult cuMemcpyDtoD(CUdeviceptr dstDevice, CUdeviceptr srcDevice, unsigned int
* CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED,
* CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE
*/
-CUresult cuMemMap(void **buf, CUdeviceptr dptr)
+CUresult cuMemMap(void **buf, CUdeviceptr dptr, unsigned int bytesize)
{
Ghandle handle;
uint64_t addr = dptr;
@@ -374,12 +374,12 @@ CUresult cuMemMap(void **buf, CUdeviceptr dptr)
return CUDA_ERROR_NOT_INITIALIZED;
if (!gdev_ctx_current)
return CUDA_ERROR_INVALID_CONTEXT;
- if (!addr || !buf)
+ if (!addr || !buf || !bytesize)
return CUDA_ERROR_INVALID_VALUE;
handle = gdev_ctx_current->gdev_handle;
- if (!(map = gmap(handle, addr)))
+ if (!(map = gmap(handle, addr, bytesize)))
return CUDA_ERROR_UNKNOWN;
*buf = map;
View
13 driver/gdev/gdev_fops.c
@@ -92,6 +92,10 @@ static int gdev_ioctl
return gdev_ioctl_gmalloc_dma(handle, arg);
case GDEV_IOCTL_GFREE_DMA:
return gdev_ioctl_gfree_dma(handle, arg);
+ case GDEV_IOCTL_GMAP:
+ return gdev_ioctl_gmap(handle, arg);
+ case GDEV_IOCTL_GUNMAP:
+ return gdev_ioctl_gunmap(handle, arg);
case GDEV_IOCTL_GMEMCPY_TO_DEVICE:
return gdev_ioctl_gmemcpy_to_device(handle, arg);
case GDEV_IOCTL_GMEMCPY_TO_DEVICE_ASYNC:
@@ -153,10 +157,9 @@ static int gdev_mmap(struct file *filp, struct vm_area_struct *vma)
/* loop over all pages, map it page individually */
while (size > 0) {
pfn = vmalloc_to_pfn(vmalloc_area_ptr);
- if ((ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE,
- PAGE_SHARED)) < 0) {
+ ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED);
+ if (ret < 0)
return ret;
- }
start += PAGE_SIZE;
vmalloc_area_ptr += PAGE_SIZE;
size -= PAGE_SIZE;
@@ -165,8 +168,8 @@ static int gdev_mmap(struct file *filp, struct vm_area_struct *vma)
return 0;
}
else {
- return remap_pfn_range(vma, start, virt_to_phys(buf) >> PAGE_SHIFT,
- size, PAGE_SHARED);
+ unsigned long pfn = virt_to_phys(buf) >> PAGE_SHIFT;
+ return remap_pfn_range(vma, start, pfn, size, PAGE_SHARED);
}
}
View
29 driver/gdev/gdev_ioctl.c
@@ -97,6 +97,35 @@ int gdev_ioctl_gfree_dma(Ghandle handle, unsigned long arg)
return 0;
}
+int gdev_ioctl_gmap(Ghandle handle, unsigned long arg)
+{
+ struct gdev_ioctl_map m;
+
+ if (copy_from_user(&m, (void __user *)arg, sizeof(m)))
+ return -EFAULT;
+
+ if (!(m.buf = (uint64_t)gmap(handle, m.addr, m.size)))
+ return -ENOMEM;
+
+ if (copy_to_user((void __user *)arg, &m, sizeof(m)))
+ return -EFAULT;
+
+ return 0;
+}
+
+int gdev_ioctl_gunmap(Ghandle handle, unsigned long arg)
+{
+ struct gdev_ioctl_map m;
+
+ if (copy_from_user(&m, (void __user *)arg, sizeof(m)))
+ return -EFAULT;
+
+ if (gunmap(handle, (void*)m.buf))
+ return -ENOENT;
+
+ return 0;
+}
+
int gdev_ioctl_gmemcpy_to_device(Ghandle handle, unsigned long arg)
{
struct gdev_ioctl_dma dma;
View
2  driver/gdev/gdev_ioctl.h
@@ -36,7 +36,9 @@ int gdev_ioctl_gmalloc(Ghandle h, unsigned long arg);
int gdev_ioctl_gfree(Ghandle h, unsigned long arg);
int gdev_ioctl_gmalloc_dma(Ghandle h, unsigned long arg);
int gdev_ioctl_gfree_dma(Ghandle h, unsigned long arg);
+int gdev_ioctl_gmap(Ghandle handle, unsigned long arg);
int gdev_ioctl_gmemcpy_to_device(Ghandle h, unsigned long arg);
+int gdev_ioctl_gunmap(Ghandle handle, unsigned long arg);
int gdev_ioctl_gmemcpy_to_device_async(Ghandle h, unsigned long arg);
int gdev_ioctl_gmemcpy_from_device(Ghandle h, unsigned long arg);
int gdev_ioctl_gmemcpy_from_device_async(Ghandle h, unsigned long arg);
View
5 driver/pscnv/pscnv_gdev.c
@@ -599,14 +599,15 @@ void *gdev_raw_mem_map(struct gdev_mem *mem)
pscnv_vspace_unmap_node(bo->map1);
fail_map_user:
GDEV_PRINT("Failed to map host and device memory\n");
+
return NULL;
}
/* unmap device memory from host DMA memory. */
-void gdev_raw_mem_unmap(struct gdev_mem *mem)
+void gdev_raw_mem_unmap(struct gdev_mem *mem, void *map)
{
struct pscnv_bo *bo = mem->bo;
+ iounmap(map);
pscnv_vspace_unmap_node(bo->map1);
}
-
View
85 runtime/kernel/gdev_lib.c
@@ -40,7 +40,7 @@
struct gdev_map_bo {
uint64_t addr;
uint32_t size;
- void *map;
+ void *buf;
struct gdev_list list_entry;
};
@@ -101,16 +101,17 @@ uint64_t gfree(struct gdev_handle *h, uint64_t addr)
void *gmalloc_dma(struct gdev_handle *h, uint64_t size)
{
- void *map;
+ void *buf;
struct gdev_map_bo *bo;
struct gdev_ioctl_mem mem;
int fd = h->fd;
+ mem.addr = 0; /* will be set via ioctl() */
mem.size = size;
if (ioctl(fd, GDEV_IOCTL_GMALLOC_DMA, &mem))
goto fail_gmalloc_dma;
- map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mem.addr);
- if (map == MAP_FAILED)
+ buf = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mem.addr);
+ if (buf == MAP_FAILED)
goto fail_map;
bo = (struct gdev_map_bo*) malloc(sizeof(*bo));
@@ -119,10 +120,10 @@ void *gmalloc_dma(struct gdev_handle *h, uint64_t size)
gdev_list_init(&bo->list_entry, bo);
gdev_list_add(&bo->list_entry, &h->map_bo_list);
bo->addr = mem.addr;
- bo->size = mem.size;
- bo->map = map;
+ bo->size = size; /* could be different from mem.size */
+ bo->buf = buf;
- return map;
+ return buf;
fail_malloc:
munmap(map, size);
@@ -139,21 +140,83 @@ uint64_t gfree_dma(struct gdev_handle *h, void *buf)
int fd = h->fd;
gdev_list_for_each (bo, &h->map_bo_list, list_entry) {
- if (bo && (bo->map == buf)) {
+ if (bo && (bo->buf == buf)) {
goto free;
}
}
return 0;
free:
- munmap(bo->map, bo->size);
+ gdev_list_del(&bo->list_entry);
+ munmap(buf, bo->size);
mem.addr = bo->addr;
+
free(bo);
ioctl(fd, GDEV_IOCTL_GFREE_DMA, &mem);
return mem.size;
}
+void *gmap(struct gdev_handle *h, uint64_t addr, uint64_t size)
+{
+ struct gdev_ioctl_map map;
+ struct gdev_map_bo *bo;
+ void *buf;
+ int fd = h->fd;
+
+ map.addr = addr;
+ map.size = size;
+ map.buf = 0; /* will be set via ioctl() */
+ if (ioctl(fd, GDEV_IOCTL_GMAP, &mem))
+ goto fail_gmap;
+
+ buf = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr);
+ if (buf == MAP_FAILED)
+ goto fail_map;
+
+ bo = (struct gdev_map_bo*) malloc(sizeof(*bo));
+ if (!bo)
+ goto fail_malloc;
+ gdev_list_init(&bo->list_entry, bo);
+ gdev_list_add(&bo->list_entry, &h->map_bo_list);
+ bo->addr = map.buf; /* save buffer address but not device address */
+ bo->size = size;
+ bo->buf = buf;
+
+ return buf;
+
+fail_malloc:
+ munmap(buf, size);
+fail_map:
+ ioctl(fd, GDEV_IOCTL_GUNMAP, &map);
+fail_gmap:
+ return NULL;
+}
+
+int gunmap(struct gdev_handle *h, void *buf)
+{
+ struct gdev_map_bo *bo;
+ struct gdev_ioctl_map map;
+ int fd = h->fd;
+
+ gdev_list_for_each (bo, &h->map_bo_list, list_entry) {
+ if (bo && (bo->buf == buf)) {
+ goto unmap;
+ }
+ }
+ return -ENOENT;
+
+unmap:
+ gdev_list_del(&bo->list_entry);
+ munmap(buf, bo->size);
+ map.addr = 0; /* unused */
+ map.size = 0; /* unused */
+ map.buf = bo->addr; /* bo->addr holds kernel-space buffer pointer */
+ free(bo);
+
+ return ioctl(fd, GDEV_IOCTL_GUNMAP, &map);
+}
+
static int __gmemcpy_to_device(struct gdev_handle *h, uint64_t dst_addr, const void *src_buf, uint64_t size, uint32_t *id, int ioctl_cmd)
{
struct gdev_map_bo *bo;
@@ -161,7 +224,7 @@ static int __gmemcpy_to_device(struct gdev_handle *h, uint64_t dst_addr, const v
int fd = h->fd;
gdev_list_for_each (bo, &h->map_bo_list, list_entry) {
- if (bo && (bo->map == src_buf))
+ if (bo && (bo->buf == src_buf))
break;
}
@@ -193,7 +256,7 @@ static int __gmemcpy_from_device(struct gdev_handle *h, void *dst_buf, uint64_t
int fd = h->fd;
gdev_list_for_each (bo, &h->map_bo_list, list_entry) {
- if (bo && (bo->map == dst_buf))
+ if (bo && (bo->buf == dst_buf))
break;
}
View
10 runtime/user/pscnv/pscnv_gdev.c
@@ -398,14 +398,14 @@ void *gdev_raw_mem_map(struct gdev_mem *mem)
int fd = bo->fd;
int vid = bo->vid;
uint32_t handle = bo->handle;
- uint32_t size = bo->size;
+ uint64_t size = bo->size;
uint64_t map_handle;
void *map;
pscnv_vm_map(fd, vid, handle, &map_handle);
map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map_handle);
- if ((void*)map == MAP_FAILED)
+ if (map == MAP_FAILED)
goto fail;
return map;
@@ -416,15 +416,15 @@ void *gdev_raw_mem_map(struct gdev_mem *mem)
}
/* unmap device memory from host DMA memory. */
-void gdev_raw_mem_unmap(struct gdev_mem *mem)
+void gdev_raw_mem_unmap(struct gdev_mem *mem, void *map)
{
struct pscnv_ib_bo *bo = mem->bo;
int fd = bo->fd;
int vid = bo->vid;
uint32_t handle = bo->handle;
- uint32_t size = bo->size;
+ uint64_t size = bo->size;
- munmap(mem->map, size);
+ munmap(map, size);
pscnv_vm_unmap(fd, vid, handle);
}
View
6 test/cuda/common/vmmap.c
@@ -92,7 +92,7 @@ int cuda_test_madd(unsigned int n, char *path)
printf("cuMemAlloc (a) failed\n");
return -1;
}
- res = cuMemMap((void**)&a_buf, a_dev);
+ res = cuMemMap((void**)&a_buf, a_dev, n*n * sizeof(unsigned int));
if (res != CUDA_SUCCESS) {
printf("cuMemMap (a) failed\n");
return -1;
@@ -104,7 +104,7 @@ int cuda_test_madd(unsigned int n, char *path)
printf("cuMemAlloc (b) failed\n");
return -1;
}
- res = cuMemMap((void**)&b_buf, b_dev);
+ res = cuMemMap((void**)&b_buf, b_dev, n*n * sizeof(unsigned int));
if (res != CUDA_SUCCESS) {
printf("cuMemMap (b) failed\n");
return -1;
@@ -116,7 +116,7 @@ int cuda_test_madd(unsigned int n, char *path)
printf("cuMemAlloc (c) failed\n");
return -1;
}
- res = cuMemMap((void**)&c_buf, c_dev);
+ res = cuMemMap((void**)&c_buf, c_dev, n*n * sizeof(unsigned int));
if (res != CUDA_SUCCESS) {
printf("cuMemMap (c) failed\n");
return -1;
Please sign in to comment.
Something went wrong with that request. Please try again.