Skip to content

dspqueue: use new callback signature for multidomain queue callbacks #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions inc/dspqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,20 @@ struct dspqueue_buffer {
*/
typedef void (*dspqueue_callback_t)(dspqueue_t queue, AEEResult error, void *context);

/**
* Callback function type for all queue callbacks
*
* @param queue Queue handle from dspqueue_create() / dspqueue_import()
* @param error Error code
* @param context Client-provided context pointer
* @param logical_id Logical id of domain in context which triggered
* callback
* @param effec_domain_id Effective domain id of remote session which
* triggered callback
*/
typedef void (*dspqueue_mdq_callback_t)(dspqueue_t queue, AEEResult error,
void *context, int logical_id, int effec_domain_id);

/* Struct to be used with DSPQUEUE_CREATE request */
typedef struct dspqueue_create_req {
/* [in]: Fastrpc multi-domain context */
Expand Down Expand Up @@ -158,13 +172,13 @@ typedef struct dspqueue_create_req {
* this callback can be called concurrently from multiple threads.
* Client is expected to consume each available response packet.
*/
dspqueue_callback_t packet_callback;
dspqueue_mdq_callback_t packet_callback;

/*
* [in]: Callback function called on unrecoverable errors.
* NULL to disable.
*/
dspqueue_callback_t error_callback;
dspqueue_mdq_callback_t error_callback;

/* [in]: Context pointer for callback functions */
void *callback_context;
Expand Down
12 changes: 12 additions & 0 deletions inc/dspqueue_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,18 @@ struct dspqueue_multidomain {

/* Array of queue ids - one for each domain */
uint64_t *dsp_ids;

/* Packet callback function pointer for multidomain queue */
dspqueue_mdq_callback_t packet_callback;

/* Error callback function pointer for multidomain queue */
dspqueue_mdq_callback_t error_callback;

/*
* When a single domain queue is a child queue of a multidomain queue,
* this field will be set to the parent queue handle.
*/
dspqueue_t *pq;
};

/* Signals IDs used with driver signaling. Update the signal allocations in dspsignal.h
Expand Down
3 changes: 3 additions & 0 deletions inc/fastrpc_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ typedef struct fastrpc_context {
/* Array of domains on which context is created */
unsigned int *domains;

/* Array of session ids on each domain */
unsigned int *session_ids;

/* Array of device fds opened for each session */
int *devs;

Expand Down
4 changes: 3 additions & 1 deletion inc/fastrpc_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ int ioctl_optimization(int dev, uint32_t max_concurrency);
* @param[in] req : type of context manage request
* @param[in] user_ctx : context generated in user
* @param[in] domain_ids : list of domains in context
* @param[in] session_ids : list of session ids on each domain
* @param[in] num_domain_ids : number of domains
* @param[in/out] ctx : kernel-generated context id. Output ptr
* for setup req and input value for
Expand All @@ -575,7 +576,8 @@ int ioctl_optimization(int dev, uint32_t max_concurrency);
* returns 0 on success
*/
int ioctl_mdctx_manage(int dev, int req, void *user_ctx,
unsigned int *domain_ids, unsigned int num_domain_ids, uint64_t *ctx);
unsigned int *domain_ids, unsigned int *session_ids,
unsigned int num_domain_ids, uint64_t *ctx);

const char* get_secure_domain_name(int domain_id);
int is_async_fastrpc_supported(void);
Expand Down
41 changes: 15 additions & 26 deletions inc/fastrpc_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,39 +189,28 @@ enum fastrpc_mdctx_manage_req {
FASTRPC_MDCTX_REMOVE,
};

/* Payload for FASTRPC_MDCTX_SETUP type */
struct fastrpc_ioctl_mdctx_setup {
/* ctx id in userspace */
__u64 user_ctx;
/* User-addr to list of domains on which context is being created */
__u64 domain_ids;
/* Number of domain ids */
__u32 num_domains;
/* User-addr where unique context generated by kernel is copied to */
__u64 ctx;
__u32 reserved[9];
};

/* Payload for FASTRPC_MDCTX_REMOVE type */
struct fastrpc_ioctl_mdctx_remove {
/* kernel-generated context id */
__u64 ctx;
__u32 reserved[8];
};

/* Payload for FASTRPC_INVOKE_MDCTX_MANAGE type */
struct fastrpc_ioctl_mdctx_manage {
/*
* Type of ctx manage request.
* One of "enum fastrpc_mdctx_manage_req"
*/
__u32 req;
/* To keep struct 64-bit aligned */
__u32 padding;
union {
struct fastrpc_ioctl_mdctx_setup setup;
struct fastrpc_ioctl_mdctx_remove remove;
};
/* ctx id in userspace */
__u64 user_ctx;
/* User-addr to list of domains on which context is being managed */
__u64 domain_ids;
/* User-addr to list of session ids of each domain */
__u64 session_ids;
/* Number of domain ids */
__u32 num_domains;
/*
* ctx setup req : user-addr where unique context generated by kernel
* is copied to
* ctx remove req : ctx id to be removed
*/
__u64 ctx;
__u32 reserved[8];
};

#endif // FASTRPC_INTERNAL_H
72 changes: 63 additions & 9 deletions src/dspqueue/dspqueue_cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//# undef NDEBUG
//#endif

#include "AEEQList.h" // Needed by fastrpc_mem.h
#include "AEEQList.h"
#include "dspqueue.h"
#include "dspqueue_rpc.h"
#include "dspqueue_shared.h"
Expand All @@ -37,6 +37,7 @@
#include <rpcmem_internal.h>
#include <stdatomic.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>

struct dspqueue {
Expand Down Expand Up @@ -864,7 +865,7 @@ AEEResult dspqueue_close(dspqueue_t queue) {
if (dq->dsp_error != AEE_ECONNRESET) {
for (i = 0; i < DSPQUEUE_NUM_SIGNALS; i++) {
nErr = dspsignal_cancel_wait(q->domain, QUEUE_SIGNAL(q->id, i));
if (nErr && nErr != AEE_EBADSTATE) {
if (nErr && nErr != AEE_EBADSTATE && nErr != AEE_ECONNRESET) {
goto bail;
}
}
Expand Down Expand Up @@ -917,7 +918,7 @@ AEEResult dspqueue_close(dspqueue_t queue) {
FARF(MEDIUM, "%s: Destroy signals", __func__);
for (i = 0; i < DSPQUEUE_NUM_SIGNALS; i++) {
nErr = dspsignal_destroy(q->domain, QUEUE_SIGNAL(q->id, i));
if (nErr && nErr != AEE_EBADSTATE) {
if (nErr && nErr != AEE_EBADSTATE && nErr != AEE_ECONNRESET) {
goto bail;
}
}
Expand Down Expand Up @@ -977,13 +978,60 @@ AEEResult dspqueue_export(dspqueue_t queue, uint64_t *queue_id) {
return AEE_SUCCESS;
}

/* Invoke packet / error callback for a multidomain queue */
static int dspqueue_multidomain_invoke_callback(dspqueue_t queue,
AEEResult error, void *context, bool err_cb) {
unsigned int ii = 0, effec_domain_id = UINT_MAX;
struct dspqueue *q = queue, *pq = q->mdq.pq;
struct dspqueue_multidomain *mdq = NULL;

// Parent queue pointer cannot be NULL in this callback
assert(pq);
mdq = &pq->mdq;

// Loop thru child queue handles until match is found for given handle
for (ii = 0; ii < mdq->num_domain_ids; ii++) {
if (mdq->queues[ii] == queue) {
effec_domain_id = mdq->effec_domain_ids[ii];
break;
}
}
assert(IS_VALID_EFFECTIVE_DOMAIN_ID(effec_domain_id));

// Invoke the client registered callback function
if (err_cb) {
assert(mdq->error_callback);
mdq->error_callback(pq, error, context, ii, effec_domain_id);
} else {
assert(mdq->packet_callback);
mdq->packet_callback(queue, error, context, ii, effec_domain_id);
}
return 0;
}

/* Internal error callback function for all multidomain queues */
static void dspqueue_multidomain_error_callback(dspqueue_t queue,
AEEResult error, void *context) {
dspqueue_multidomain_invoke_callback(queue, error, context, true);
}

/* Internal packet callback function for all multidomain queues */
static void dspqueue_multidomain_packet_callback(dspqueue_t queue,
AEEResult error, void *context) {
dspqueue_multidomain_invoke_callback(queue, error, context, false);
}

static int dspqueue_multidomain_create(dspqueue_create_req *create) {
int nErr = AEE_SUCCESS;
bool queue_mut = false;
unsigned int *effec_domain_ids = NULL;
unsigned int num_domain_ids = 0, size = 0;
struct dspqueue *q = NULL;
struct dspqueue *q = NULL, *cq = NULL;
struct dspqueue_multidomain *mdq = NULL;
dspqueue_callback_t mdq_err_cb = create->error_callback ?
dspqueue_multidomain_error_callback : NULL;
dspqueue_callback_t mdq_pkt_cb = create->packet_callback ?
dspqueue_multidomain_packet_callback : NULL;

VERIFY(AEE_SUCCESS == (nErr = fastrpc_context_get_domains(create->ctx,
&effec_domain_ids, &num_domain_ids)));
Expand All @@ -1006,6 +1054,8 @@ static int dspqueue_multidomain_create(dspqueue_create_req *create) {
mdq = &q->mdq;
mdq->is_mdq = true;
mdq->ctx = create->ctx;
mdq->packet_callback = create->packet_callback;
mdq->error_callback = create->error_callback;

VERIFYC(AEE_SUCCESS == (nErr = pthread_mutex_init(&q->mutex, NULL)),
AEE_ENOTINITIALIZED);
Expand All @@ -1027,13 +1077,18 @@ static int dspqueue_multidomain_create(dspqueue_create_req *create) {

// Create queue on each individual domain
for (unsigned int ii = 0; ii < num_domain_ids; ii++) {
cq = NULL;

VERIFY(AEE_SUCCESS == (nErr = dspqueue_create(effec_domain_ids[ii],
create->flags, create->req_queue_size, create->resp_queue_size,
create->packet_callback, create->error_callback,
create->callback_context, &mdq->queues[ii])));
mdq_pkt_cb, mdq_err_cb, create->callback_context, &cq)));
mdq->queues[ii] = cq;

// Assign the parent queue for the single-domain queue
cq->mdq.pq = q;

// Export queue and get queue id for that domain
VERIFY(AEE_SUCCESS == (nErr = dspqueue_export(mdq->queues[ii],
VERIFY(AEE_SUCCESS == (nErr = dspqueue_export(cq,
&mdq->dsp_ids[ii])));
}

Expand Down Expand Up @@ -1226,7 +1281,6 @@ static AEEResult send_signal(struct dspqueue *q, uint32_t signal_no) {
pthread_cond_signal(&dq->send_signal_cond);
pthread_mutex_unlock(&dq->send_signal_mutex);
}

bail:
if (nErr != AEE_SUCCESS) {
FARF(ERROR, "Error 0x%x: %s failed for queue %p signal %u", nErr, __func__,
Expand Down Expand Up @@ -2683,7 +2737,7 @@ static void *dspqueue_packet_callback_thread(void *arg) {

// Wait for a signal
nErr = wait_signal_locked(q, DSPQUEUE_SIGNAL_RESP_PACKET, NULL);
if (nErr == AEE_EINTERRUPTED || nErr == AEE_EBADSTATE) {
if (nErr == AEE_EINTERRUPTED || nErr == AEE_EBADSTATE || nErr == AEE_ECONNRESET ) {
FARF(HIGH, "Queue %u exit callback thread", (unsigned)q->id);
if (q->have_wait_counts) {
atomic_fetch_sub(wait_count, 1);
Expand Down
7 changes: 3 additions & 4 deletions src/dspsignal.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ AEEResult dspsignal_create(int domain, uint32_t id, uint32_t flags) {
}

AEEResult dspsignal_destroy(int domain, uint32_t id) {

AEEResult nErr = AEE_SUCCESS;
struct dspsignal_domain_signals *ds = NULL;

Expand All @@ -175,7 +174,6 @@ AEEResult dspsignal_destroy(int domain, uint32_t id) {
goto bail;
}
FARF(HIGH, "%s: Signal %u destroyed", __func__, id);

bail:
if (nErr != AEE_SUCCESS) {
FARF(ERROR, "Error 0x%x: %s failed (domain %d, ID %u) errno %s", nErr,
Expand Down Expand Up @@ -211,7 +209,6 @@ AEEResult dspsignal_signal(int domain, uint32_t id) {
}

AEEResult dspsignal_wait(int domain, uint32_t id, uint32_t timeout_usec) {

AEEResult nErr = AEE_SUCCESS;
struct dspsignal_domain_signals *ds = NULL;

Expand All @@ -231,6 +228,9 @@ AEEResult dspsignal_wait(int domain, uint32_t id, uint32_t timeout_usec) {
} else if (errno == EINTR) {
FARF(MEDIUM, "%s: Signal %u canceled", __func__, id);
return AEE_EINTERRUPTED;
} else if (errno == EPIPE ) {
FARF(MEDIUM, "%s: Signal %u, ssr on domain %d", __func__, id, domain);
return AEE_ECONNRESET;
} else {
nErr = convert_kernel_to_user_error(nErr, errno);
goto bail;
Expand All @@ -246,7 +246,6 @@ AEEResult dspsignal_wait(int domain, uint32_t id, uint32_t timeout_usec) {
}

AEEResult dspsignal_cancel_wait(int domain, uint32_t id) {

AEEResult nErr = AEE_SUCCESS;
struct dspsignal_domain_signals *ds = NULL;

Expand Down
Loading
Loading