ipc_service: static_vrings: Move to one WQ per instance

Instead of having one single WQ per backend, move to one WQ per
instance instead and add a new "zephyr,priority" property in the DT to
set the WQ priority of the instance. Fix the sample as well.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
Carlo Caione 2022-03-15 14:41:19 +01:00 committed by Carles Cufí
commit 92d8329d5b
5 changed files with 61 additions and 13 deletions

View file

@ -28,3 +28,18 @@ properties:
mbox-names: mbox-names:
description: MBOX channel names (must be called "tx" and "rx") description: MBOX channel names (must be called "tx" and "rx")
required: true required: true
zephyr,priority:
type: array
required: false
description: |
WQ priority for the instance. This property is an array composed by the
priority level and the type of priority (PRIO_COOP for cooperative or
PRIO_PREEMPT for preemptive).
For example for a thread priority K_PRIO_COOP(1) in DT we have
priority = <1 PRIO_COOP>;
or for K_PRIO_PREEMPT(2)
priority = <2 PRIO_PREEMPT>;
When this property is missing a default priority of 0 is assumed.

View file

@ -0,0 +1,14 @@
/*
* Copyright (c) 2022 Carlo Caione <ccaione@baylibre.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDING_IPC_SERVICE_STATIC_VRINGS_H
#define __DT_BINDING_IPC_SERVICE_STATIC_VRINGS_H
#include <sys/util_macro.h>
#define PRIO_COOP BIT(0)
#define PRIO_PREEMPT BIT(1)
#endif /* __DT_BINDING_IPC_SERVICE_STATIC_VRINGS_H */

View file

@ -4,6 +4,8 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <dt-bindings/ipc_service/static_vrings.h>
/ { / {
chosen { chosen {
/delete-property/ zephyr,ipc_shm; /delete-property/ zephyr,ipc_shm;
@ -42,6 +44,7 @@
mboxes = <&mbox 2>, <&mbox 3>; mboxes = <&mbox 2>, <&mbox 3>;
mbox-names = "tx", "rx"; mbox-names = "tx", "rx";
role = "host"; role = "host";
zephyr,priority = <1 PRIO_COOP>;
status = "okay"; status = "okay";
}; };
}; };

View file

@ -4,6 +4,8 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <dt-bindings/ipc_service/static_vrings.h>
/ { / {
chosen { chosen {
/delete-property/ zephyr,ipc_shm; /delete-property/ zephyr,ipc_shm;
@ -40,6 +42,7 @@
mboxes = <&mbox 2>, <&mbox 3>; mboxes = <&mbox 2>, <&mbox 3>;
mbox-names = "rx", "tx"; mbox-names = "rx", "tx";
role = "remote"; role = "remote";
zephyr,priority = <2 PRIO_PREEMPT>;
status = "okay"; status = "okay";
}; };
}; };

View file

@ -15,20 +15,21 @@
#include <ipc/ipc_rpmsg.h> #include <ipc/ipc_rpmsg.h>
#include <drivers/mbox.h> #include <drivers/mbox.h>
#include <dt-bindings/ipc_service/static_vrings.h>
#include "ipc_rpmsg_static_vrings.h" #include "ipc_rpmsg_static_vrings.h"
#define DT_DRV_COMPAT zephyr_ipc_openamp_static_vrings #define DT_DRV_COMPAT zephyr_ipc_openamp_static_vrings
#define WQ_PRIORITY K_HIGHEST_APPLICATION_THREAD_PRIO #define NUM_INSTANCES DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)
#define WQ_STACK_SIZE CONFIG_IPC_SERVICE_BACKEND_RPMSG_WQ_STACK_SIZE #define WQ_STACK_SIZE CONFIG_IPC_SERVICE_BACKEND_RPMSG_WQ_STACK_SIZE
#define STATE_READY (0) #define STATE_READY (0)
#define STATE_BUSY (1) #define STATE_BUSY (1)
#define STATE_INITED (2) #define STATE_INITED (2)
K_KERNEL_STACK_DEFINE(mbox_stack, WQ_STACK_SIZE); K_THREAD_STACK_ARRAY_DEFINE(mbox_stack, NUM_INSTANCES, WQ_STACK_SIZE);
static struct k_work_q mbox_wq;
struct backend_data_t { struct backend_data_t {
/* RPMsg */ /* RPMsg */
@ -37,8 +38,11 @@ struct backend_data_t {
/* Static VRINGs */ /* Static VRINGs */
struct ipc_static_vrings vr; struct ipc_static_vrings vr;
/* General */ /* MBOX WQ */
struct k_work mbox_work; struct k_work mbox_work;
struct k_work_q mbox_wq;
/* General */
unsigned int role; unsigned int role;
atomic_t state; atomic_t state;
}; };
@ -49,6 +53,9 @@ struct backend_config_t {
size_t shm_size; size_t shm_size;
struct mbox_channel mbox_tx; struct mbox_channel mbox_tx;
struct mbox_channel mbox_rx; struct mbox_channel mbox_rx;
unsigned int wq_prio_type;
unsigned int wq_prio;
unsigned int id;
}; };
static void rpmsg_service_unbind(struct rpmsg_endpoint *ep) static void rpmsg_service_unbind(struct rpmsg_endpoint *ep)
@ -262,14 +269,20 @@ static void mbox_callback(const struct device *instance, uint32_t channel,
{ {
struct backend_data_t *data = user_data; struct backend_data_t *data = user_data;
k_work_submit_to_queue(&mbox_wq, &data->mbox_work); k_work_submit_to_queue(&data->mbox_wq, &data->mbox_work);
} }
static int mbox_init(const struct device *instance) static int mbox_init(const struct device *instance)
{ {
const struct backend_config_t *conf = instance->config; const struct backend_config_t *conf = instance->config;
struct backend_data_t *data = instance->data; struct backend_data_t *data = instance->data;
int err; int prio, err;
prio = (conf->wq_prio_type == PRIO_COOP) ? K_PRIO_COOP(conf->wq_prio) :
K_PRIO_PREEMPT(conf->wq_prio);
k_work_queue_init(&data->mbox_wq);
k_work_queue_start(&data->mbox_wq, mbox_stack[conf->id], WQ_STACK_SIZE, prio, NULL);
k_work_init(&data->mbox_work, mbox_callback_process); k_work_init(&data->mbox_work, mbox_callback_process);
@ -458,19 +471,12 @@ static int backend_init(const struct device *instance)
{ {
const struct backend_config_t *conf = instance->config; const struct backend_config_t *conf = instance->config;
struct backend_data_t *data = instance->data; struct backend_data_t *data = instance->data;
static bool wq_started;
data->role = conf->role; data->role = conf->role;
k_mutex_init(&data->rpmsg_inst.mtx); k_mutex_init(&data->rpmsg_inst.mtx);
atomic_set(&data->state, STATE_READY); atomic_set(&data->state, STATE_READY);
if (!wq_started) {
k_work_queue_start(&mbox_wq, mbox_stack, K_KERNEL_STACK_SIZEOF(mbox_stack),
WQ_PRIORITY, NULL);
wq_started = true;
}
return 0; return 0;
} }
@ -481,6 +487,13 @@ static int backend_init(const struct device *instance)
.shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, memory_region)), \ .shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, memory_region)), \
.mbox_tx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), tx), \ .mbox_tx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), tx), \
.mbox_rx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), rx), \ .mbox_rx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), rx), \
.wq_prio = COND_CODE_1(DT_INST_NODE_HAS_PROP(i, zephyr_priority), \
(DT_INST_PROP_BY_IDX(i, zephyr_priority, 0)), \
(0)), \
.wq_prio_type = COND_CODE_1(DT_INST_NODE_HAS_PROP(i, zephyr_priority), \
(DT_INST_PROP_BY_IDX(i, zephyr_priority, 1)), \
(PRIO_PREEMPT)), \
.id = i, \
}; \ }; \
\ \
static struct backend_data_t backend_data_##i; \ static struct backend_data_t backend_data_##i; \