Skip to content
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

Make P2A channel queues optional #26

Open
wants to merge 2 commits into
base: main
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
14 changes: 10 additions & 4 deletions include/librpmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,12 @@ struct rpmi_transport {

/** Endianness of the messages transferred through this transport */
rpmi_bool_t is_be;

/**
* Is P2A channel available (in case of shmem based transport
* is p2a req and a2p ack queues)
*/
rpmi_bool_t is_p2a_channel;

/** Slot (or max message) size in transport queues */
rpmi_size_t slot_size;
Expand Down Expand Up @@ -505,15 +511,15 @@ enum rpmi_error rpmi_transport_dequeue(struct rpmi_transport *trans,
*
* @param[in] name name of the shared memory transport instance
* @param[in] slot_size size of message slot for queues in shared memory
* @param[in] a2p_queue_size size of A2P request and P2A acknowledgement queues
* @param[in] p2a_queue_size size of P2A request and A2P acknowledgement queues
* @param[in] a2p_req_queue_size size of A2P request and P2A acknowledgement queues
* @param[in] p2a_req_queue_size size of P2A request and A2P acknowledgement queues
* @param[in] shmem pointer to a RPMI shared memory instance
* @return pointer to RPMI transport upon success and NULL upon failure
*/
struct rpmi_transport *rpmi_transport_shmem_create(const char *name,
rpmi_uint32_t slot_size,
rpmi_uint32_t a2p_queue_size,
rpmi_uint32_t p2a_queue_size,
rpmi_uint32_t a2p_req_queue_size,
rpmi_uint32_t p2a_req_queue_size,
struct rpmi_shmem *shmem);

/**
Expand Down
12 changes: 12 additions & 0 deletions lib/rpmi_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ enum rpmi_error rpmi_transport_enqueue(struct rpmi_transport *trans,
return RPMI_ERR_INVAL;
}

if (!trans->is_p2a_channel && qtype >= RPMI_QUEUE_P2A_REQ) {
DPRINTF("%s: %s: p2a channel not available, invalid qtype %d\n",
__func__, trans->name, qtype);
return RPMI_ERR_INVAL;
}

if (!trans->enqueue) {
DPRINTF("%s: %s: enqueue operation not supported for qtype %d\n",
__func__, trans->name, qtype);
Expand Down Expand Up @@ -134,6 +140,12 @@ enum rpmi_error rpmi_transport_dequeue(struct rpmi_transport *trans,
return RPMI_ERR_INVAL;
}

if (!trans->is_p2a_channel && qtype >= RPMI_QUEUE_P2A_REQ) {
DPRINTF("%s: %s: p2a channel not available, invalid qtype %d\n",
__func__, trans->name, qtype);
return RPMI_ERR_INVAL;
}

if (!trans->dequeue) {
DPRINTF("%s: %s: dequeue operation not supported for qtype %d\n",
__func__, trans->name, qtype);
Expand Down
69 changes: 49 additions & 20 deletions lib/rpmi_transport_shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ struct rpmi_transport_shmem_queue {

struct rpmi_transport_shmem {
struct rpmi_shmem *shmem;
struct rpmi_transport_shmem_queue queues[RPMI_QUEUE_MAX];
rpmi_uint32_t queue_count;
struct rpmi_transport_shmem_queue *queues;
struct rpmi_transport trans;
};

Expand Down Expand Up @@ -167,8 +168,8 @@ static enum rpmi_error shmem_dequeue(struct rpmi_transport *trans,

struct rpmi_transport *rpmi_transport_shmem_create(const char *name,
rpmi_uint32_t slot_size,
rpmi_uint32_t a2p_queue_size,
rpmi_uint32_t p2a_queue_size,
rpmi_uint32_t a2p_req_queue_size,
rpmi_uint32_t p2a_req_queue_size,
struct rpmi_shmem *shmem)
{
struct rpmi_transport_shmem_queue *shqueue;
Expand All @@ -184,19 +185,35 @@ struct rpmi_transport *rpmi_transport_shmem_create(const char *name,
if ((slot_size & (slot_size - 1)) || slot_size < RPMI_SLOT_SIZE_MIN)
return NULL;

/* Make sure queue sizes are multiples of slot size */
if ((a2p_queue_size & (slot_size - 1)) ||
(p2a_queue_size & (slot_size - 1)))
return NULL;

/* Make sure queue sizes are not less than minimum required size */
if (a2p_queue_size < LIBRPMI_TRANSPORT_SHMEM_QUEUE_MIN_SIZE(slot_size) ||
p2a_queue_size < LIBRPMI_TRANSPORT_SHMEM_QUEUE_MIN_SIZE(slot_size))
return NULL;

/* Shared memory size MUST be enough to accommodate all queues */
if (rpmi_shmem_size(shmem) < (2 * (a2p_queue_size + p2a_queue_size)))
return NULL;
/* all four queue are present */
if (p2a_req_queue_size) {
/* Make sure queue sizes are multiples of slot size */
if ((a2p_req_queue_size & (slot_size - 1)) ||
(p2a_req_queue_size & (slot_size - 1)))
return NULL;

/* Make sure queue sizes are not less than minimum required size */
if (a2p_req_queue_size < LIBRPMI_TRANSPORT_SHMEM_QUEUE_MIN_SIZE(slot_size) ||
p2a_req_queue_size < LIBRPMI_TRANSPORT_SHMEM_QUEUE_MIN_SIZE(slot_size))
return NULL;

/* Shared memory size MUST be enough to accommodate all queues */
if (rpmi_shmem_size(shmem) < (2 * (a2p_req_queue_size + p2a_req_queue_size)))
return NULL;
}
else { /* only a2p req and p2a ack queue */
/* Make sure queue sizes are multiples of slot size */
if (a2p_req_queue_size & (slot_size - 1))
return NULL;

/* Make sure queue sizes are not less than minimum required size */
if (a2p_req_queue_size < LIBRPMI_TRANSPORT_SHMEM_QUEUE_MIN_SIZE(slot_size))
return NULL;

/* Shared memory size MUST be enough to accommodate all queues */
if (rpmi_shmem_size(shmem) < (2 * a2p_req_queue_size))
return NULL;
}

/* Fill the shared memory with zeros */
if (rpmi_shmem_fill(shmem, 0, 0, rpmi_shmem_size(shmem)))
Expand All @@ -208,13 +225,19 @@ struct rpmi_transport *rpmi_transport_shmem_create(const char *name,
return NULL;

shtrans->shmem = shmem;
for (i = 0; i < RPMI_QUEUE_MAX; i++) {
shtrans->queue_count = p2a_req_queue_size? RPMI_QUEUE_MAX : 2;

shtrans->queues = rpmi_env_zalloc(sizeof(*shtrans->queues) * shtrans->queue_count);
if (!shtrans->queues)
return NULL;

for (i = 0; i < shtrans->queue_count; i++) {
shqueue = &shtrans->queues[i];
shqueue->queue_type = i;
if (i == RPMI_QUEUE_A2P_REQ || i == RPMI_QUEUE_P2A_ACK)
shqueue->queue_size = a2p_queue_size;
else
shqueue->queue_size = p2a_queue_size;
shqueue->queue_size = a2p_req_queue_size;
else if (p2a_req_queue_size)
shqueue->queue_size = p2a_req_queue_size;
if (i)
shqueue->queue_base = shtrans->queues[i - 1].queue_base +
shtrans->queues[i - 1].queue_size;
Expand All @@ -227,6 +250,7 @@ struct rpmi_transport *rpmi_transport_shmem_create(const char *name,
trans->name = name;
trans->is_be = false;
trans->slot_size = slot_size;
trans->is_p2a_channel = p2a_req_queue_size ? true : false;
trans->is_empty = shmem_is_empty;
trans->is_full = shmem_is_full;
trans->enqueue = shmem_enqueue;
Expand All @@ -239,9 +263,14 @@ struct rpmi_transport *rpmi_transport_shmem_create(const char *name,

void rpmi_transport_shmem_destroy(struct rpmi_transport *trans)
{
struct rpmi_transport_shmem *shtrans;

if (!trans)
return;

shtrans = trans->priv;

rpmi_env_free_lock(trans->lock);
rpmi_env_free(shtrans->queues);
rpmi_env_free(trans->priv);
}