Skip to content

Commit

Permalink
gdev: added ioctl functions for gmap() and gunmap()
Browse files Browse the repository at this point in the history
gdev: fixed gmap() and gunmap() interfaces
cuda: fixed cuMemMap() and cuMemUnmap() interfaces
  • Loading branch information
Shinpei Kato committed Feb 10, 2012
1 parent 57f8b50 commit 474fa00
Show file tree
Hide file tree
Showing 15 changed files with 180 additions and 63 deletions.
14 changes: 4 additions & 10 deletions common/gdev_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion common/gdev_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion common/gdev_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
36 changes: 22 additions & 14 deletions common/gdev_ioctl_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -95,4 +97,10 @@ struct gdev_ioctl_shm {
void *buf;
};

struct gdev_ioctl_map {
uint64_t addr;
uint64_t buf;
uint64_t size;
};

#endif
3 changes: 2 additions & 1 deletion common/gdev_nvidia.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
};

/**
Expand Down Expand Up @@ -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);
Expand Down
25 changes: 20 additions & 5 deletions common/gdev_nvidia_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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. */
Expand Down
5 changes: 3 additions & 2 deletions cuda/driver_api/cuda.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions cuda/driver_api/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
13 changes: 8 additions & 5 deletions driver/gdev/gdev_fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
}

Expand Down
29 changes: 29 additions & 0 deletions driver/gdev/gdev_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions driver/gdev/gdev_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions driver/pscnv/pscnv_gdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Loading

0 comments on commit 474fa00

Please sign in to comment.