Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

gdev: added asynchronous memcpy (not tested well)

gdev: added gref() and guref() API
cuda: added Stream Management
  • Loading branch information...
commit 3820d7634349c8d7333bb627cd2ab04d574a935d 1 parent 2046147
Shinpei Kato authored
View
38 common/gdev_api.c
@@ -1132,6 +1132,44 @@ int gshmctl(Ghandle h, int id, int cmd, void *buf)
}
/**
+ * gref():
+ * reference device virtual memory of handle @hsrc from handle @hdst.
+ * this API can be used alone - no need to call other gshm* APIs a priori.
+ */
+uint64_t gref(Ghandle hmaster, uint64_t addr, uint64_t size, Ghandle hslave)
+{
+ gdev_mem_t *mem, *new;
+
+ mem = gdev_mem_lookup(hmaster->vas, addr, GDEV_MEM_DEVICE);
+ if (!mem)
+ return 0;
+
+ new = gdev_shm_attach(hslave->vas, mem, size);
+ if (!new)
+ return 0;
+
+ return gdev_mem_getaddr(new);
+}
+
+/**
+ * gunref():
+ * unreference device virtual memory from the shared region.
+ */
+int gunref(Ghandle h, uint64_t addr)
+{
+ gdev_vas_t *vas = h->vas;
+ gdev_mem_t *mem;
+
+ mem = gdev_mem_lookup(vas, addr, GDEV_MEM_DEVICE);
+ if (!mem)
+ return -ENOENT;
+
+ gdev_shm_detach(mem);
+
+ return 0;
+}
+
+/**
* gphysget():
* get the physical (PCI) bus address associated with buffer pointer @p
*/
View
2  common/gdev_api.h
@@ -68,6 +68,8 @@ int gshmget(Ghandle h, int key, uint64_t size, int flags);
uint64_t gshmat(Ghandle h, int id, uint64_t addr, int flags);
int gshmdt(Ghandle h, uint64_t addr);
int gshmctl(Ghandle h, int id, int cmd, void *buf);
+uint64_t gref(Ghandle hmaster, uint64_t addr, uint64_t size, Ghandle hslave);
+int gunref(Ghandle h, uint64_t addr);
uint64_t gphysget(Ghandle h, void *p);
uint64_t gvirtget(Ghandle h, void *p);
View
28 common/gdev_ioctl_def.h
@@ -30,7 +30,12 @@
#define __GDEV_IOCTL_DEF_H__
/**
- * user-space ioctl commands:
+ * utility ioctl commands:
+ */
+#define GDEV_IOCTL_GET_HANDLE 0x10
+
+/**
+ * user-space ioctl commands for Gdev API:
*/
#define GDEV_IOCTL_GMALLOC 0x100
#define GDEV_IOCTL_GFREE 0x101
@@ -52,8 +57,14 @@
#define GDEV_IOCTL_GSHMAT 0x117
#define GDEV_IOCTL_GSHMDT 0x118
#define GDEV_IOCTL_GSHMCTL 0x119
-#define GDEV_IOCTL_GPHYSGET 0x120
-#define GDEV_IOCTL_GVIRTGET 0x121
+#define GDEV_IOCTL_GREF 0x120
+#define GDEV_IOCTL_GUNREF 0x121
+#define GDEV_IOCTL_GPHYSGET 0x122
+#define GDEV_IOCTL_GVIRTGET 0x123
+
+struct gdev_ioctl_handle {
+ uint64_t handle;
+};
struct gdev_ioctl_mem {
uint64_t addr;
@@ -105,6 +116,17 @@ struct gdev_ioctl_map {
uint64_t size;
};
+struct gdev_ioctl_ref {
+ uint64_t addr;
+ uint64_t size;
+ uint64_t handle_slave;
+ uint64_t addr_slave;
+};
+
+struct gdev_ioctl_unref {
+ uint64_t addr;
+};
+
struct gdev_ioctl_phys {
uint64_t addr;
uint64_t phys;
View
14 cuda/driver_api/context.c
@@ -97,7 +97,7 @@ CUresult cuCtxCreate(CUcontext *pctx, unsigned int flags, CUdevice dev)
struct CUctx_st *ctx;
struct gdev_cuda_info *cuda_info;
Ghandle handle;
- int minor = dev;
+ int minor = (int)dev;
if (!gdev_initialized)
return CUDA_ERROR_NOT_INITIALIZED;
@@ -156,6 +156,8 @@ CUresult cuCtxCreate(CUcontext *pctx, unsigned int flags, CUdevice dev)
/* we will trace # of kernels. */
ctx->launch_id = 0;
+ /* save the device ID. */
+ ctx->minor = minor;
gdev_ctx_current = ctx; /* set to the current context. */
*pctx = ctx;
@@ -313,7 +315,7 @@ CUresult cuCtxPopCurrent(CUcontext *pctx)
CUresult cuCtxSynchronize(void)
{
Ghandle handle;
- struct gdev_cuda_launch *l;
+ struct gdev_cuda_fence *f;
struct gdev_list *p;
if (!gdev_initialized)
@@ -327,17 +329,17 @@ CUresult cuCtxSynchronize(void)
handle = gdev_ctx_current->gdev_handle;
/* synchronize with all kernels. */
- gdev_list_for_each(l, &gdev_ctx_current->sync_list, list_entry) {
+ gdev_list_for_each(f, &gdev_ctx_current->sync_list, list_entry) {
/* if timeout is required, specify gdev_time value instead of NULL. */
- if (gsync(handle, l->id, NULL))
+ if (gsync(handle, f->id, NULL))
return CUDA_ERROR_UNKNOWN;
}
/* remove all lists. */
while ((p = gdev_list_head(&gdev_ctx_current->sync_list))) {
gdev_list_del(p);
- l = gdev_list_container(p);
- FREE(l);
+ f = gdev_list_container(p);
+ FREE(f);
}
if (gbarrier(handle))
View
7 cuda/driver_api/cuda.h
@@ -791,6 +791,13 @@ CUresult cuMemUnmap(void *buf);
/* Memory mapped address - Gdev extension */
CUresult cuMemGetPhysAddr(unsigned long long *addr, void *p);
+/* Stream Management */
+CUresult cuStreamCreate(CUstream *phStream, unsigned int Flags);
+CUresult cuStreamDestroy(CUstream hStream);
+CUresult cuStreamQuery(CUstream hStream);
+CUresult cuStreamSynchronize(CUstream hStream);
+CUresult cuStreamWaitEvent(CUstream hStream, CUevent hEvent, unsigned int Flags);
+
/* Inter-Process Communication (IPC) - Gdev extension */
CUresult cuShmGet(int *ptr, int key, size_t size, int flags);
CUresult cuShmAt(CUdeviceptr *dptr, int id, int flags);
View
11 cuda/driver_api/execution.c
@@ -146,7 +146,7 @@ CUresult cuLaunchGrid(CUfunction f, int grid_width, int grid_height)
struct CUmod_st *mod = func->mod;
struct CUctx_st *ctx = mod->ctx;
struct gdev_kernel *k;
- struct gdev_cuda_launch *l;
+ struct gdev_cuda_fence *fence;
Ghandle handle;
if (!gdev_initialized)
@@ -155,7 +155,7 @@ CUresult cuLaunchGrid(CUfunction f, int grid_width, int grid_height)
return CUDA_ERROR_INVALID_CONTEXT;
if (!func || grid_width <= 0 || grid_height <= 0)
return CUDA_ERROR_INVALID_VALUE;
- if (!(l = MALLOC(sizeof(*l))))
+ if (!(fence = (struct gdev_cuda_fence *)MALLOC(sizeof(*fence))))
return CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES;
k = &func->kernel;
@@ -169,10 +169,11 @@ CUresult cuLaunchGrid(CUfunction f, int grid_width, int grid_height)
handle = gdev_ctx_current->gdev_handle;
- if (glaunch(handle, k, &l->id))
+ if (glaunch(handle, k, &fence->id))
return CUDA_ERROR_LAUNCH_FAILED;
- gdev_list_init(&l->list_entry, l);
- gdev_list_add(&l->list_entry, &ctx->sync_list);
+ fence->addr_ref = 0; /* no address to unreference later. */
+ gdev_list_init(&fence->list_entry, fence);
+ gdev_list_add(&fence->list_entry, &ctx->sync_list);
return CUDA_SUCCESS;
}
View
9 cuda/driver_api/gdev_cuda.h
@@ -68,8 +68,9 @@ struct gdev_cuda_raw_func {
uint32_t local_size_neg;
};
-struct gdev_cuda_launch {
- uint32_t id; /* kernel ID returned by the launch function. */
+struct gdev_cuda_fence {
+ uint32_t id; /* fence ID returned by the Gdev API. */
+ uint64_t addr_ref; /* only used for asynchronous memcpy. */
struct gdev_list list_entry; /* entry to synchronization list. */
};
@@ -87,6 +88,7 @@ struct CUctx_st {
struct gdev_list sync_list;
struct gdev_cuda_info cuda_info;
int launch_id;
+ int minor;
};
struct CUmod_st {
@@ -126,6 +128,9 @@ struct CUevent_st {
};
struct CUstream_st {
+ Ghandle gdev_handle;
+ struct CUctx_st *ctx;
+ struct gdev_list sync_list; /* for gdev_cuda_fence.list_entry */
};
struct CUgraphicsResource_st {
View
103 cuda/driver_api/memory.c
@@ -201,8 +201,7 @@ CUresult cuMemFreeHost(void *p)
* CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED,
* CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE
*/
-CUresult cuMemcpyHtoD
-(CUdeviceptr dstDevice, const void *srcHost, unsigned int ByteCount)
+CUresult cuMemcpyHtoD(CUdeviceptr dstDevice, const void *srcHost, unsigned int ByteCount)
{
Ghandle handle;
const void *src_buf = srcHost;
@@ -244,12 +243,53 @@ CUresult cuMemcpyHtoD
* CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED,
* CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE
*/
-CUresult cuMemcpyHtoDAsync
-(CUdeviceptr dstDevice, const void *srcHost, unsigned int ByteCount,
- CUstream hStream)
+CUresult cuMemcpyHtoDAsync(CUdeviceptr dstDevice, const void *srcHost, unsigned int ByteCount, CUstream hStream)
{
- GDEV_PRINT("cuMemcpyHtoD: Not Implemented Yet\n");
+ Ghandle handle, handle_ref;
+ struct CUstream_st *stream = hStream;
+ const void *src_buf = srcHost;
+ uint64_t dst_addr = dstDevice;
+ uint64_t dst_addr_ref;
+ uint32_t size = ByteCount;
+ struct gdev_cuda_fence *fence;
+ uint32_t id;
+
+ if (!stream)
+ return cuMemcpyHtoD(dst_addr, src_buf, size);
+
+ if (!gdev_initialized)
+ return CUDA_ERROR_NOT_INITIALIZED;
+ if (!src_buf || !dst_addr || !size)
+ return CUDA_ERROR_INVALID_VALUE;
+ if (gdev_ctx_current != stream->ctx)
+ return CUDA_ERROR_INVALID_CONTEXT;
+
+ fence = (struct gdev_cuda_fence *)MALLOC(sizeof(*fence));
+ if (!fence)
+ return CUDA_ERROR_OUT_OF_MEMORY; /* this API shouldn't return it... */
+
+ handle = gdev_ctx_current->gdev_handle;
+ handle_ref = stream->gdev_handle;
+
+ if (!(dst_addr_ref = gref(handle, dst_addr, size, handle_ref)))
+ goto fail_gref;
+
+ if (gmemcpy_to_device_async(handle_ref, dst_addr_ref, src_buf, size, &id))
+ goto fail_gmemcpy;
+
+ fence->id = id;
+ fence->addr_ref = dst_addr_ref;
+ gdev_list_init(&fence->list_entry, fence);
+ gdev_list_add(&fence->list_entry, &stream->sync_list);
+
return CUDA_SUCCESS;
+
+fail_gmemcpy:
+ gunref(handle_ref, dst_addr_ref);
+fail_gref:
+ FREE(fence);
+
+ return CUDA_ERROR_UNKNOWN;
}
/**
@@ -266,8 +306,7 @@ CUresult cuMemcpyHtoDAsync
* CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED,
* CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE
*/
-CUresult cuMemcpyDtoH
-(void *dstHost, CUdeviceptr srcDevice, unsigned int ByteCount)
+CUresult cuMemcpyDtoH(void *dstHost, CUdeviceptr srcDevice, unsigned int ByteCount)
{
Ghandle handle;
void *dst_buf = dstHost;
@@ -309,11 +348,53 @@ CUresult cuMemcpyDtoH
* CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED,
* CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE
*/
-CUresult cuMemcpyDtoHAsync
-(void *dstHost, CUdeviceptr srcDevice, unsigned int ByteCount, CUstream hstream)
+CUresult cuMemcpyDtoHAsync(void *dstHost, CUdeviceptr srcDevice, unsigned int ByteCount, CUstream hStream)
{
- GDEV_PRINT("cuMemcpyDtoH: Not Implemented Yet\n");
+ Ghandle handle, handle_ref;
+ struct CUstream_st *stream = hStream;
+ void *dst_buf = dstHost;
+ uint64_t src_addr = srcDevice;
+ uint64_t src_addr_ref;
+ uint32_t size = ByteCount;
+ struct gdev_cuda_fence *fence;
+ uint32_t id;
+
+ if (!stream)
+ return cuMemcpyDtoH(dst_buf, src_addr, size);
+
+ if (!gdev_initialized)
+ return CUDA_ERROR_NOT_INITIALIZED;
+ if (!dst_buf || !src_addr || !size)
+ return CUDA_ERROR_INVALID_VALUE;
+ if (gdev_ctx_current != stream->ctx)
+ return CUDA_ERROR_INVALID_CONTEXT;
+
+ fence = (struct gdev_cuda_fence *)MALLOC(sizeof(*fence));
+ if (!fence)
+ return CUDA_ERROR_OUT_OF_MEMORY; /* this API shouldn't return it... */
+
+ handle = gdev_ctx_current->gdev_handle;
+ handle_ref = stream->gdev_handle;
+
+ if (!(src_addr_ref = gref(handle, src_addr, size, handle_ref)))
+ goto fail_gref;
+
+ if (gmemcpy_from_device_async(handle_ref, dst_buf, src_addr_ref, size, &id))
+ goto fail_gmemcpy;
+
+ fence->id = id;
+ fence->addr_ref = src_addr_ref;
+ gdev_list_init(&fence->list_entry, fence);
+ gdev_list_add(&fence->list_entry, &stream->sync_list);
+
return CUDA_SUCCESS;
+
+fail_gmemcpy:
+ gunref(handle_ref, src_addr_ref);
+fail_gref:
+ FREE(fence);
+
+ return CUDA_ERROR_UNKNOWN;
}
/**
View
181 cuda/driver_api/stream.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2011 Shinpei Kato
+ *
+ * Systems Research Lab, University of California at Santa Cruz
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "cuda.h"
+#include "gdev_cuda.h"
+#include "gdev_api.h"
+#include "gdev_list.h"
+
+/**
+ * Creates a stream and returns a handle in phStream. Flags is required to be 0.
+ *
+ * Parameters:
+ * phStream - Returned newly created stream
+ * Flags - Parameters for stream creation (must be 0)
+ *
+ * Returns:
+ * CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED,
+ * CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE,
+ * CUDA_ERROR_OUT_OF_MEMORY
+ */
+CUresult cuStreamCreate(CUstream *phStream, unsigned int Flags)
+{
+ CUresult res;
+ struct CUstream_st *stream;
+ Ghandle handle;
+ int minor;
+
+ if (!gdev_initialized)
+ return CUDA_ERROR_NOT_INITIALIZED;
+ if (!gdev_ctx_current)
+ return CUDA_ERROR_INVALID_CONTEXT;
+ if (!phStream || Flags != 0)
+ return CUDA_ERROR_INVALID_VALUE;
+
+ /* allocate a new stream. */
+ stream = (CUstream)MALLOC(sizeof(*stream));
+ if (!stream)
+ return CUDA_ERROR_OUT_OF_MEMORY;
+
+ /* create another channel for the stream. */
+ minor = gdev_ctx_current->minor;
+ if (!(handle = gopen(minor))) {
+ res = CUDA_ERROR_UNKNOWN;
+ goto fail_gopen;
+ }
+
+ stream->gdev_handle = handle;
+ stream->ctx = gdev_ctx_current;
+ gdev_list_init(&stream->sync_list, NULL);
+
+ *phStream = stream;
+
+ return CUDA_SUCCESS;
+
+fail_gopen:
+ return res;
+}
+
+/**
+ * Destroys the stream specified by hStream.
+ *
+ * In the case that the device is still doing work in the stream hStream when
+ * cuStreamDestroy() is called, the function will return immediately and the
+ * resources associated with hStream will be released automatically once the
+ * device has completed all work in hStream.
+ *
+ * Parameters:
+ * hStream - Stream to destroy
+ *
+ * Returns:
+ * CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED,
+ * CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE
+ */
+CUresult cuStreamDestroy(CUstream hStream)
+{
+ struct CUstream_st *stream = hStream;
+
+ if (!gdev_initialized)
+ return CUDA_ERROR_NOT_INITIALIZED;
+ if (gdev_ctx_current != stream->ctx)
+ return CUDA_ERROR_INVALID_CONTEXT;
+ if (!stream)
+ return CUDA_ERROR_INVALID_VALUE;
+
+ /* synchronize with the stream before destroying it. */
+ cuStreamSynchronize(stream);
+
+ if (gclose(stream->gdev_handle))
+ return CUDA_ERROR_UNKNOWN;
+
+ FREE(stream);
+
+ return CUDA_SUCCESS;
+}
+
+CUresult cuStreamQuery(CUstream hStream)
+{
+ GDEV_PRINT("cuStreamQuery: Not Implemented Yet\n");
+ return CUDA_SUCCESS;
+}
+
+/**
+ * Waits until the device has completed all operations in the stream specified
+ * by hStream. If the context was created with the CU_CTX_SCHED_BLOCKING_SYNC
+ * flag, the CPU thread will block until the stream is finished with all of its
+ * tasks.
+ *
+ * Parameters:
+ * hStream - Stream to wait for
+ *
+ * Returns:
+ * CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED,
+ * CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_HANDLE
+ */
+CUresult cuStreamSynchronize(CUstream hStream)
+{
+ Ghandle handle;
+ struct CUstream_st *stream = hStream;
+ struct gdev_cuda_fence *f;
+ struct gdev_list *p;
+
+ if (!gdev_initialized)
+ return CUDA_ERROR_NOT_INITIALIZED;
+ if (gdev_ctx_current != stream->ctx)
+ return CUDA_ERROR_INVALID_CONTEXT;
+
+ if (gdev_list_empty(&stream->sync_list))
+ return CUDA_SUCCESS;
+
+ handle = stream->gdev_handle;
+
+ /* synchronize with all stream's tasks. */
+ gdev_list_for_each(f, &stream->sync_list, list_entry) {
+ /* if timeout is required, specify gdev_time value instead of NULL. */
+ if (gsync(handle, f->id, NULL))
+ return CUDA_ERROR_UNKNOWN;
+ }
+
+ /* remove all lists. */
+ while ((p = gdev_list_head(&stream->sync_list))) {
+ gdev_list_del(p);
+ f = gdev_list_container(p);
+ if (f->addr_ref)
+ gunref(handle, f->addr_ref);
+ FREE(f);
+ }
+
+ if (gbarrier(handle))
+ return CUDA_ERROR_UNKNOWN;
+
+ return CUDA_SUCCESS;
+}
+
+CUresult cuStreamWaitEvent(CUstream hStream, CUevent hEvent, unsigned int Flags)
+{
+ GDEV_PRINT("cuStreamWaitEvent: Not Implemented Yet\n");
+ return CUDA_SUCCESS;
+}
View
2  cuda/kcuda/Makefile
@@ -1,5 +1,5 @@
TARGET = kcuda
-$(TARGET)-y := kcuda_drv.o init.o device.o version.o context.o module.o memory.o execution.o ipc.o gdev_cuda.o
+$(TARGET)-y := kcuda_drv.o init.o device.o version.o context.o module.o memory.o execution.o stream.o ipc.o gdev_cuda.o
GDEVDIR = /usr/local/gdev
GDEVINC = $(GDEVDIR)/include
GDEVETC = $(GDEVDIR)/etc
View
2  cuda/libcuda/Makefile
@@ -7,7 +7,7 @@ GDEVDIR = /usr/local/gdev
CFLAGS = -O3 -Wall -I $(GDEVDIR)/include
#OBJS = $(patsubst %.c,%.o,$(wildcard ./*.c))
-OBJS = init.o device.o version.o context.o module.o execution.o memory.o ipc.o gdev_cuda.o
+OBJS = init.o device.o version.o context.o module.o execution.o memory.o stream.o ipc.o gdev_cuda.o
CUDUMP_OBJS = cudump.o gdev_cuda.o
ZOMBIE = $(wildcard ./*~)
View
19 driver/gdev/gdev_drv.c
@@ -530,15 +530,30 @@ EXPORT_SYMBOL(gmalloc);
EXPORT_SYMBOL(gfree);
EXPORT_SYMBOL(gmalloc_dma);
EXPORT_SYMBOL(gfree_dma);
-EXPORT_SYMBOL(gmemcpy_from_device);
-EXPORT_SYMBOL(gmemcpy_user_from_device);
+EXPORT_SYMBOL(gmap);
+EXPORT_SYMBOL(gunmap);
EXPORT_SYMBOL(gmemcpy_to_device);
+EXPORT_SYMBOL(gmemcpy_to_device_async);
EXPORT_SYMBOL(gmemcpy_user_to_device);
+EXPORT_SYMBOL(gmemcpy_user_to_device_async);
+EXPORT_SYMBOL(gmemcpy_from_device);
+EXPORT_SYMBOL(gmemcpy_from_device_async);
+EXPORT_SYMBOL(gmemcpy_user_from_device);
+EXPORT_SYMBOL(gmemcpy_user_from_device_async);
EXPORT_SYMBOL(gmemcpy_in_device);
EXPORT_SYMBOL(glaunch);
EXPORT_SYMBOL(gsync);
+EXPORT_SYMBOL(gbarrier);
EXPORT_SYMBOL(gquery);
EXPORT_SYMBOL(gtune);
+EXPORT_SYMBOL(gshmget);
+EXPORT_SYMBOL(gshmat);
+EXPORT_SYMBOL(gshmdt);
+EXPORT_SYMBOL(gshmctl);
+EXPORT_SYMBOL(gref);
+EXPORT_SYMBOL(gunref);
+EXPORT_SYMBOL(gphysget);
+EXPORT_SYMBOL(gvirtget);
static int __init gdev_module_init(void)
{
View
6 driver/gdev/gdev_fops.c
@@ -85,6 +85,8 @@ static int gdev_ioctl
Ghandle handle = filp->private_data;
switch (cmd) {
+ case GDEV_IOCTL_GET_HANDLE: /* this is not Gdev API. */
+ return gdev_ioctl_get_handle(handle, arg);
case GDEV_IOCTL_GMALLOC:
return gdev_ioctl_gmalloc(handle, arg);
case GDEV_IOCTL_GFREE:
@@ -125,6 +127,10 @@ static int gdev_ioctl
return gdev_ioctl_gshmdt(handle, arg);
case GDEV_IOCTL_GSHMCTL:
return gdev_ioctl_gshmctl(handle, arg);
+ case GDEV_IOCTL_GREF:
+ return gdev_ioctl_gref(handle, arg);
+ case GDEV_IOCTL_GUNREF:
+ return gdev_ioctl_gunref(handle, arg);
case GDEV_IOCTL_GPHYSGET:
return gdev_ioctl_gphysget(handle, arg);
case GDEV_IOCTL_GVIRTGET:
View
41 driver/gdev/gdev_ioctl.c
@@ -33,6 +33,18 @@
#define GDEV_MEMCPY_USER_DIRECT
+int gdev_ioctl_get_handle(Ghandle handle, unsigned long arg)
+{
+ struct gdev_ioctl_handle h;
+
+ h.handle = (uint64_t)handle;
+
+ if (copy_to_user((void __user *)arg, &h, sizeof(h)))
+ return -EFAULT;
+
+ return 0;
+}
+
int gdev_ioctl_gmalloc(Ghandle handle, unsigned long arg)
{
struct gdev_ioctl_mem m;
@@ -421,6 +433,35 @@ int gdev_ioctl_gshmctl(Ghandle handle, unsigned long arg)
return gshmctl(handle, s.id, s.cmd, (void *)&ds);
}
+int gdev_ioctl_gref(Ghandle handle, unsigned long arg)
+{
+ struct gdev_ioctl_ref r;
+
+ if (copy_from_user(&r, (void __user *)arg, sizeof(r)))
+ return -EFAULT;
+
+ if (!(r.addr_slave = gref(handle, r.addr, r.size, (Ghandle)r.handle_slave)))
+ return -EINVAL;
+
+ if (copy_to_user((void __user *)arg, &r, sizeof(r)))
+ return -EFAULT;
+
+ return 0;
+}
+
+int gdev_ioctl_gunref(Ghandle handle, unsigned long arg)
+{
+ struct gdev_ioctl_unref r;
+
+ if (copy_from_user(&r, (void __user *)arg, sizeof(r)))
+ return -EFAULT;
+
+ if (gunref(handle, r.addr))
+ return -EINVAL;
+
+ return 0;
+}
+
int gdev_ioctl_gphysget(Ghandle handle, unsigned long arg)
{
struct gdev_ioctl_phys p;
View
4 driver/gdev/gdev_ioctl.h
@@ -32,6 +32,8 @@
#include "gdev_api.h"
#include "gdev_ioctl_def.h"
+int gdev_ioctl_get_handle(Ghandle handle, unsigned long arg);
+
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);
@@ -52,6 +54,8 @@ int gdev_ioctl_gshmget(Ghandle h, unsigned long arg);
int gdev_ioctl_gshmat(Ghandle h, unsigned long arg);
int gdev_ioctl_gshmdt(Ghandle h, unsigned long arg);
int gdev_ioctl_gshmctl(Ghandle h, unsigned long arg);
+int gdev_ioctl_gref(Ghandle h, unsigned long arg);
+int gdev_ioctl_gunref(Ghandle h, unsigned long arg);
int gdev_ioctl_gphysget(Ghandle h, unsigned long arg);
int gdev_ioctl_gvirtget(Ghandle h, unsigned long arg);
View
33 lib/kernel/gdev_lib.c
@@ -419,6 +419,39 @@ int gshmctl(struct gdev_handle *h, int id, int cmd, void *buf)
return 0;
}
+uint64_t gref(struct gdev_handle *hmaster, uint64_t addr, uint64_t size, struct gdev_handle *hslave)
+{
+ struct gdev_ioctl_ref r;
+ struct gdev_ioctl_handle h;
+ int fd_master = hmaster->fd;
+ int fd_slave = hslave->fd;
+ int ret;
+
+ if ((ret = ioctl(fd_slave, GDEV_IOCTL_GET_HANDLE, &h)))
+ return ret;
+
+ r.addr = addr;
+ r.size = size;
+ r.handle_slave = h.handle;
+ if ((ret = ioctl(fd_master, GDEV_IOCTL_GREF, &r)))
+ return ret;
+
+ return r.addr_slave;
+}
+
+int gunref(struct gdev_handle *h, uint64_t addr)
+{
+ struct gdev_ioctl_unref r;
+ int fd = h->fd;
+ int ret;
+
+ r.addr = addr;
+ if ((ret = ioctl(fd, GDEV_IOCTL_GUNREF, &r)))
+ return ret;
+
+ return 0;
+}
+
uint64_t gphysget(struct gdev_handle *h, void *p)
{
struct gdev_map_bo *bo;
Please sign in to comment.
Something went wrong with that request. Please try again.