Commit 0a66735a authored by Swann Perarnau's avatar Swann Perarnau
Browse files

[refactor] remove generic functions from requests

This patch refactors dma request types to remove generic function
pointers from the library. This include modifying the linux_seq
implementation to:
- move the copy/move implementation to the dma ops
- remove one layer of indirection, as the request type no longer need
_data and _ops substructures.

Enforcing dma requests to have a fully qualified generic type, with
function pointers, will cause issues for future kinds of dma
implementation, that might require a different way of handling requests
altogether.

This work is driven by our current work on a parallel dma implementation.
parent a0f603df
...@@ -498,23 +498,12 @@ struct aml_binding_interleave_data { ...@@ -498,23 +498,12 @@ struct aml_binding_interleave_data {
#define AML_DMA_REQUEST_TYPE_COPY 0 #define AML_DMA_REQUEST_TYPE_COPY 0
#define AML_DMA_REQUEST_TYPE_MOVE 1 #define AML_DMA_REQUEST_TYPE_MOVE 1
struct aml_dma_request_data; struct aml_dma_request;
struct aml_dma_data; struct aml_dma_data;
struct aml_dma_request_ops {
int (*copy)(struct aml_dma_data *dma, struct aml_dma_request_data *req);
int (*move)(struct aml_dma_data *dma, struct aml_dma_request_data *req);
};
struct aml_dma_request {
struct aml_dma_request_ops *ops;
struct aml_dma_request_data *data;
};
struct aml_dma_ops { struct aml_dma_ops {
int (*create_request)(struct aml_dma_data *dma, int (*create_request)(struct aml_dma_data *dma,
struct aml_dma_request *req, int type, struct aml_dma_request **req, int type,
va_list args); va_list args);
int (*destroy_request)(struct aml_dma_data *dma, int (*destroy_request)(struct aml_dma_data *dma,
struct aml_dma_request *req); struct aml_dma_request *req);
...@@ -528,9 +517,9 @@ struct aml_dma { ...@@ -528,9 +517,9 @@ struct aml_dma {
}; };
int aml_dma_copy(struct aml_dma *dma, ...); int aml_dma_copy(struct aml_dma *dma, ...);
int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request *req, ...); int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request **req, ...);
int aml_dma_move(struct aml_dma *dma, ...); int aml_dma_move(struct aml_dma *dma, ...);
int aml_dma_async_move(struct aml_dma *dma, struct aml_dma_request *req, ...); int aml_dma_async_move(struct aml_dma *dma, struct aml_dma_request **req, ...);
int aml_dma_wait(struct aml_dma *dma, struct aml_dma_request *req); int aml_dma_wait(struct aml_dma *dma, struct aml_dma_request *req);
int aml_dma_cancel(struct aml_dma *dma, struct aml_dma_request *req); int aml_dma_cancel(struct aml_dma *dma, struct aml_dma_request *req);
...@@ -540,7 +529,9 @@ int aml_dma_cancel(struct aml_dma *dma, struct aml_dma_request *req); ...@@ -540,7 +529,9 @@ int aml_dma_cancel(struct aml_dma *dma, struct aml_dma_request *req);
* used as the only execution thread. * used as the only execution thread.
******************************************************************************/ ******************************************************************************/
struct aml_dma_request_linux_seq_data { extern struct aml_dma_ops aml_dma_linux_seq_ops;
struct aml_dma_request_linux_seq {
int type; int type;
void *dest; void *dest;
void *src; void *src;
...@@ -550,18 +541,20 @@ struct aml_dma_request_linux_seq_data { ...@@ -550,18 +541,20 @@ struct aml_dma_request_linux_seq_data {
int *nodes; int *nodes;
}; };
extern struct aml_dma_ops aml_dma_linux_seq_ops;
struct aml_dma_linux_seq_data { struct aml_dma_linux_seq_data {
size_t size; size_t size;
struct aml_dma_request_linux_seq_data *requests; struct aml_dma_request_linux_seq *requests;
}; };
struct aml_dma_linux_seq_ops { struct aml_dma_linux_seq_ops {
int (*do_copy)(struct aml_dma_linux_seq_data *dma,
struct aml_dma_request_linux_seq *req);
int (*do_move)(struct aml_dma_linux_seq_data *dma,
struct aml_dma_request_linux_seq *req);
int (*add_request)(struct aml_dma_linux_seq_data *dma, int (*add_request)(struct aml_dma_linux_seq_data *dma,
struct aml_dma_request_linux_seq_data **req); struct aml_dma_request_linux_seq **req);
int (*remove_request)(struct aml_dma_linux_seq_data *dma, int (*remove_request)(struct aml_dma_linux_seq_data *dma,
struct aml_dma_request_linux_seq_data **req); struct aml_dma_request_linux_seq **req);
}; };
struct aml_dma_linux_seq { struct aml_dma_linux_seq {
......
...@@ -15,16 +15,16 @@ int aml_dma_copy(struct aml_dma *dma, ...) ...@@ -15,16 +15,16 @@ int aml_dma_copy(struct aml_dma *dma, ...)
assert(dma != NULL); assert(dma != NULL);
va_list ap; va_list ap;
int ret; int ret;
struct aml_dma_request req; struct aml_dma_request *req;
va_start(ap, dma); va_start(ap, dma);
ret = dma->ops->create_request(dma->data, &req, ret = dma->ops->create_request(dma->data, &req,
AML_DMA_REQUEST_TYPE_COPY, ap); AML_DMA_REQUEST_TYPE_COPY, ap);
va_end(ap); va_end(ap);
ret = dma->ops->wait_request(dma->data, &req); ret = dma->ops->wait_request(dma->data, req);
return ret; return ret;
} }
int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request *req, ...) int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request **req, ...)
{ {
assert(dma != NULL); assert(dma != NULL);
assert(req != NULL); assert(req != NULL);
...@@ -40,19 +40,19 @@ int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request *req, ...) ...@@ -40,19 +40,19 @@ int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request *req, ...)
int aml_dma_move(struct aml_dma *dma, ...) int aml_dma_move(struct aml_dma *dma, ...)
{ {
assert(dma != NULL); assert(dma != NULL);
struct aml_dma_request req; struct aml_dma_request *req;
va_list ap; va_list ap;
int ret; int ret;
va_start(ap, dma); va_start(ap, dma);
ret = dma->ops->create_request(dma->data, &req, ret = dma->ops->create_request(dma->data, &req,
AML_DMA_REQUEST_TYPE_MOVE, ap); AML_DMA_REQUEST_TYPE_MOVE, ap);
va_end(ap); va_end(ap);
ret = dma->ops->wait_request(dma->data, &req); ret = dma->ops->wait_request(dma->data, req);
return ret; return ret;
} }
int aml_dma_async_move(struct aml_dma *dma, struct aml_dma_request *req, ...) int aml_dma_async_move(struct aml_dma *dma, struct aml_dma_request **req, ...)
{ {
assert(dma != NULL); assert(dma != NULL);
assert(req != NULL); assert(req != NULL);
......
...@@ -16,102 +16,88 @@ ...@@ -16,102 +16,88 @@
* Requests: * Requests:
******************************************************************************/ ******************************************************************************/
int aml_dma_request_linux_seq_copy(struct aml_dma_data *dma, int aml_dma_request_linux_seq_copy_init(struct aml_dma_request_linux_seq *req,
struct aml_dma_request_data *req)
{
assert(dma != NULL);
assert(req != NULL);
struct aml_dma_request_linux_seq_data *data =
(struct aml_dma_request_linux_seq_data*)req;
memcpy(data->dest, data->src, data->size);
return 0;
}
int aml_dma_request_linux_seq_move(struct aml_dma_data *dma,
struct aml_dma_request_data *req)
{
assert(dma != NULL);
assert(req != NULL);
struct aml_dma_request_linux_seq_data *data =
(struct aml_dma_request_linux_seq_data *)req;
int status[data->count];
int err;
err = move_pages(0, data->count, data->pages, data->nodes, status,
MPOL_MF_MOVE);
if(err)
{
perror("move_pages:");
return errno;
}
return 0;
}
struct aml_dma_request_ops aml_dma_request_linux_seq_ops = {
aml_dma_request_linux_seq_copy,
aml_dma_request_linux_seq_move,
};
int aml_dma_request_linux_seq_copy_init(struct aml_dma_request *r,
const struct aml_tiling *dt, const struct aml_tiling *dt,
void *dptr, int dtid, void *dptr, int dtid,
const struct aml_tiling *st, const struct aml_tiling *st,
const void *sptr, int stid) const void *sptr, int stid)
{ {
assert(r != NULL); assert(req != NULL);
struct aml_dma_request_linux_seq_data *data =
(struct aml_dma_request_linux_seq_data *)r->data;
data->type = AML_DMA_REQUEST_TYPE_MOVE; req->type = AML_DMA_REQUEST_TYPE_MOVE;
/* figure out pointers */ /* figure out pointers */
data->dest = aml_tiling_tilestart(dt, dptr, dtid); req->dest = aml_tiling_tilestart(dt, dptr, dtid);
data->src = aml_tiling_tilestart(st, sptr, stid); req->src = aml_tiling_tilestart(st, sptr, stid);
data->size = aml_tiling_tilesize(st, stid); req->size = aml_tiling_tilesize(st, stid);
/* TODO: assert size match */ /* TODO: assert size match */
return 0; return 0;
} }
int aml_dma_request_linux_seq_copy_destroy(struct aml_dma_request *r) int aml_dma_request_linux_seq_copy_destroy(struct aml_dma_request_linux_seq *r)
{ {
assert(r != NULL); assert(r != NULL);
return 0; return 0;
} }
int aml_dma_request_linux_seq_move_init(struct aml_dma_request *r, int aml_dma_request_linux_seq_move_init(struct aml_dma_request_linux_seq *req,
struct aml_area *darea, struct aml_area *darea,
const struct aml_tiling *tiling, const struct aml_tiling *tiling,
void *startptr, int tileid) void *startptr, int tileid)
{ {
assert(r != NULL); assert(req != NULL);
struct aml_binding *binding; struct aml_binding *binding;
struct aml_dma_request_linux_seq_data *data =
(struct aml_dma_request_linux_seq_data *)r->data;
data->type = AML_DMA_REQUEST_TYPE_MOVE; req->type = AML_DMA_REQUEST_TYPE_MOVE;
aml_area_binding(darea, &binding); aml_area_binding(darea, &binding);
data->count = aml_binding_nbpages(binding, tiling, startptr, tileid); req->count = aml_binding_nbpages(binding, tiling, startptr, tileid);
data->pages = calloc(data->count, sizeof(void *)); req->pages = calloc(req->count, sizeof(void *));
data->nodes = calloc(data->count, sizeof(int)); req->nodes = calloc(req->count, sizeof(int));
aml_binding_pages(binding, data->pages, tiling, startptr, tileid); aml_binding_pages(binding, req->pages, tiling, startptr, tileid);
aml_binding_nodes(binding, data->nodes, tiling, startptr, tileid); aml_binding_nodes(binding, req->nodes, tiling, startptr, tileid);
free(binding); free(binding);
return 0; return 0;
} }
int aml_dma_request_linux_seq_move_destroy(struct aml_dma_request *r) int aml_dma_request_linux_seq_move_destroy(struct aml_dma_request_linux_seq *req)
{ {
struct aml_dma_request_linux_seq_data *data = assert(req != NULL);
(struct aml_dma_request_linux_seq_data *)r->data; free(req->pages);
free(data->pages); free(req->nodes);
free(data->nodes);
return 0; return 0;
} }
/******************************************************************************* /*******************************************************************************
* Internal functions * Internal functions
******************************************************************************/ ******************************************************************************/
int aml_dma_linux_seq_do_copy(struct aml_dma_linux_seq_data *dma,
struct aml_dma_request_linux_seq *req)
{
assert(dma != NULL);
assert(req != NULL);
memcpy(req->dest, req->src, req->size);
return 0;
}
int aml_dma_linux_seq_do_move(struct aml_dma_linux_seq_data *dma,
struct aml_dma_request_linux_seq *req)
{
assert(dma != NULL);
assert(req != NULL);
int status[req->count];
int err;
err = move_pages(0, req->count, req->pages, req->nodes, status,
MPOL_MF_MOVE);
if(err)
{
perror("move_pages:");
return errno;
}
return 0;
}
int aml_dma_linux_seq_add_request(struct aml_dma_linux_seq_data *data, int aml_dma_linux_seq_add_request(struct aml_dma_linux_seq_data *data,
struct aml_dma_request_linux_seq_data **req) struct aml_dma_request_linux_seq **req)
{ {
for(int i = 0; i < data->size; i++) for(int i = 0; i < data->size; i++)
{ {
...@@ -126,7 +112,7 @@ int aml_dma_linux_seq_add_request(struct aml_dma_linux_seq_data *data, ...@@ -126,7 +112,7 @@ int aml_dma_linux_seq_add_request(struct aml_dma_linux_seq_data *data,
} }
int aml_dma_linux_seq_remove_request(struct aml_dma_linux_seq_data *data, int aml_dma_linux_seq_remove_request(struct aml_dma_linux_seq_data *data,
struct aml_dma_request_linux_seq_data **req) struct aml_dma_request_linux_seq **req)
{ {
/* TODO: assert that the pointer is in the right place */ /* TODO: assert that the pointer is in the right place */
(*req)->type = AML_DMA_REQUEST_TYPE_INVALID; (*req)->type = AML_DMA_REQUEST_TYPE_INVALID;
...@@ -134,6 +120,8 @@ int aml_dma_linux_seq_remove_request(struct aml_dma_linux_seq_data *data, ...@@ -134,6 +120,8 @@ int aml_dma_linux_seq_remove_request(struct aml_dma_linux_seq_data *data,
} }
struct aml_dma_linux_seq_ops aml_dma_linux_seq_inner_ops = { struct aml_dma_linux_seq_ops aml_dma_linux_seq_inner_ops = {
aml_dma_linux_seq_do_copy,
aml_dma_linux_seq_do_move,
aml_dma_linux_seq_add_request, aml_dma_linux_seq_add_request,
aml_dma_linux_seq_remove_request, aml_dma_linux_seq_remove_request,
}; };
...@@ -143,7 +131,7 @@ struct aml_dma_linux_seq_ops aml_dma_linux_seq_inner_ops = { ...@@ -143,7 +131,7 @@ struct aml_dma_linux_seq_ops aml_dma_linux_seq_inner_ops = {
******************************************************************************/ ******************************************************************************/
int aml_dma_linux_seq_create_request(struct aml_dma_data *d, int aml_dma_linux_seq_create_request(struct aml_dma_data *d,
struct aml_dma_request *r, struct aml_dma_request **r,
int type, va_list ap) int type, va_list ap)
{ {
assert(d != NULL); assert(d != NULL);
...@@ -151,14 +139,12 @@ int aml_dma_linux_seq_create_request(struct aml_dma_data *d, ...@@ -151,14 +139,12 @@ int aml_dma_linux_seq_create_request(struct aml_dma_data *d,
struct aml_dma_linux_seq *dma = struct aml_dma_linux_seq *dma =
(struct aml_dma_linux_seq *)d; (struct aml_dma_linux_seq *)d;
struct aml_dma_request_linux_seq_data *req; struct aml_dma_request_linux_seq *req;
/* find an available request slot */ /* find an available request slot */
dma->ops.add_request(&dma->data, &req); dma->ops.add_request(&dma->data, &req);
r->data = (struct aml_dma_request_data *)req;
/* init the request */ /* init the request */
r->ops = &aml_dma_request_linux_seq_ops;
if(type == AML_DMA_REQUEST_TYPE_COPY) if(type == AML_DMA_REQUEST_TYPE_COPY)
{ {
struct aml_tiling *dt, *st; struct aml_tiling *dt, *st;
...@@ -170,7 +156,7 @@ int aml_dma_linux_seq_create_request(struct aml_dma_data *d, ...@@ -170,7 +156,7 @@ int aml_dma_linux_seq_create_request(struct aml_dma_data *d,
st = va_arg(ap, struct aml_tiling *); st = va_arg(ap, struct aml_tiling *);
sptr = va_arg(ap, void *); sptr = va_arg(ap, void *);
stid = va_arg(ap, int); stid = va_arg(ap, int);
aml_dma_request_linux_seq_copy_init(r, dt, dptr, dtid, aml_dma_request_linux_seq_copy_init(req, dt, dptr, dtid,
st, sptr, stid); st, sptr, stid);
} }
else if(type == AML_DMA_REQUEST_TYPE_MOVE) else if(type == AML_DMA_REQUEST_TYPE_MOVE)
...@@ -179,8 +165,9 @@ int aml_dma_linux_seq_create_request(struct aml_dma_data *d, ...@@ -179,8 +165,9 @@ int aml_dma_linux_seq_create_request(struct aml_dma_data *d,
struct aml_tiling *st = va_arg(ap, struct aml_tiling *); struct aml_tiling *st = va_arg(ap, struct aml_tiling *);
void *sptr = va_arg(ap, void *); void *sptr = va_arg(ap, void *);
int stid = va_arg(ap, int); int stid = va_arg(ap, int);
aml_dma_request_linux_seq_move_init(r, darea, st, sptr, stid); aml_dma_request_linux_seq_move_init(req, darea, st, sptr, stid);
} }
*r = (struct aml_dma_request *)req;
return 0; return 0;
} }
...@@ -192,13 +179,13 @@ int aml_dma_linux_seq_destroy_request(struct aml_dma_data *d, ...@@ -192,13 +179,13 @@ int aml_dma_linux_seq_destroy_request(struct aml_dma_data *d,
struct aml_dma_linux_seq *dma = struct aml_dma_linux_seq *dma =
(struct aml_dma_linux_seq *)d; (struct aml_dma_linux_seq *)d;
struct aml_dma_request_linux_seq_data *req = struct aml_dma_request_linux_seq *req =
(struct aml_dma_request_linux_seq_data *)r->data; (struct aml_dma_request_linux_seq *)r;
if(req->type == AML_DMA_REQUEST_TYPE_COPY) if(req->type == AML_DMA_REQUEST_TYPE_COPY)
aml_dma_request_linux_seq_copy_destroy(r); aml_dma_request_linux_seq_copy_destroy(req);
else if(req->type == AML_DMA_REQUEST_TYPE_MOVE) else if(req->type == AML_DMA_REQUEST_TYPE_MOVE)
aml_dma_request_linux_seq_move_destroy(r); aml_dma_request_linux_seq_move_destroy(req);
dma->ops.remove_request(&dma->data, &req); dma->ops.remove_request(&dma->data, &req);
return 0; return 0;
...@@ -209,14 +196,15 @@ int aml_dma_linux_seq_wait_request(struct aml_dma_data *d, ...@@ -209,14 +196,15 @@ int aml_dma_linux_seq_wait_request(struct aml_dma_data *d,
{ {
assert(d != NULL); assert(d != NULL);
assert(r != NULL); assert(r != NULL);
struct aml_dma_request_linux_seq_data *req = struct aml_dma_linux_seq *dma = (struct aml_dma_linux_seq *)d;
(struct aml_dma_request_linux_seq_data *)r->data; struct aml_dma_request_linux_seq *req =
(struct aml_dma_request_linux_seq *)r;
/* execute */ /* execute */
if(req->type == AML_DMA_REQUEST_TYPE_COPY) if(req->type == AML_DMA_REQUEST_TYPE_COPY)
r->ops->copy(d, r->data); dma->ops.do_copy(&dma->data, req);
else if(req->type == AML_DMA_REQUEST_TYPE_MOVE) else if(req->type == AML_DMA_REQUEST_TYPE_MOVE)
r->ops->move(d, r->data); dma->ops.do_move(&dma->data, req);
/* destroy a completed request */ /* destroy a completed request */
aml_dma_linux_seq_destroy_request(d, r); aml_dma_linux_seq_destroy_request(d, r);
...@@ -262,7 +250,7 @@ int aml_dma_linux_seq_vinit(struct aml_dma *d, va_list ap) ...@@ -262,7 +250,7 @@ int aml_dma_linux_seq_vinit(struct aml_dma *d, va_list ap)
/* allocate request array */ /* allocate request array */
dma->data.size = va_arg(ap, size_t); dma->data.size = va_arg(ap, size_t);
dma->data.requests = calloc(dma->data.size, dma->data.requests = calloc(dma->data.size,
sizeof(struct aml_dma_request_linux_seq_data)); sizeof(struct aml_dma_request_linux_seq));
for(int i = 0; i < dma->data.size; i++) for(int i = 0; i < dma->data.size; i++)
dma->data.requests[i].type = AML_DMA_REQUEST_TYPE_INVALID; dma->data.requests[i].type = AML_DMA_REQUEST_TYPE_INVALID;
return 0; return 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment