Skip to content

Commit ecdc7e6

Browse files
committed
ipc: use notifications allocated by sources
Changes implementation of notifications allocation. Instead of using common empty list of messages let's switch to allocating message per source of notification. This way we won't have problem with memory and lack of empty messages and also we will be able to optimize memory. Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
1 parent 176af65 commit ecdc7e6

File tree

20 files changed

+84
-398
lines changed

20 files changed

+84
-398
lines changed

src/audio/detect_test.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ struct comp_data {
6969
struct kpb_event_data event_data;
7070
struct kpb_client client_data;
7171

72-
struct ipc_msg msg; /**< host notification */
72+
struct sof_ipc_comp_event event;
73+
struct ipc_msg *msg; /**< host notification */
7374

7475
void (*detect_func)(struct comp_dev *dev,
7576
const struct audio_stream *source, uint32_t frames);
@@ -105,19 +106,10 @@ static inline bool detector_is_sample_width_supported(enum sof_ipc_frame sf)
105106
static void notify_host(const struct comp_dev *dev)
106107
{
107108
struct comp_data *cd = comp_get_drvdata(dev);
108-
struct sof_ipc_comp_event event;
109109

110110
comp_info(dev, "notify_host()");
111111

112-
event.event_type = SOF_CTRL_EVENT_KD;
113-
event.num_elems = 0;
114-
115-
ipc_build_comp_event(&event, dev_comp_type(dev), dev_comp_id(dev));
116-
ipc_prepare_host_message(&cd->msg, event.rhdr.hdr.cmd, &event,
117-
sizeof(event));
118-
119-
/* Send IPC message right away to wake host up ASAP */
120-
ipc_platform_send_msg(&cd->msg);
112+
ipc_msg_send(cd->msg, &cd->event, true);
121113
}
122114

123115
static void notify_kpb(const struct comp_dev *dev)
@@ -346,6 +338,17 @@ static struct comp_dev *test_keyword_new(const struct comp_driver *drv,
346338
goto fail;
347339
}
348340

341+
/* build component event */
342+
ipc_build_comp_event(&cd->event, comp->type, comp->id);
343+
cd->event.event_type = SOF_CTRL_EVENT_KD;
344+
cd->event.num_elems = 0;
345+
346+
cd->msg = ipc_msg_init(cd->event.rhdr.hdr.cmd, sizeof(cd->event));
347+
if (!cd->msg) {
348+
comp_err(dev, "test_keyword_new() error: ipc notification init failed");
349+
goto fail;
350+
}
351+
349352
dev->state = COMP_STATE_READY;
350353
return dev;
351354

@@ -362,6 +365,7 @@ static void test_keyword_free(struct comp_dev *dev)
362365

363366
comp_info(dev, "test_keyword_free()");
364367

368+
ipc_msg_free(cd->msg);
365369
free_mem_load(cd);
366370
rfree(cd);
367371
rfree(dev);

src/audio/host.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <sof/drivers/ipc.h>
1515
#include <sof/lib/alloc.h>
1616
#include <sof/lib/dma.h>
17+
#include <sof/lib/mailbox.h>
1718
#include <sof/lib/memory.h>
1819
#include <sof/lib/notifier.h>
1920
#include <sof/list.h>
@@ -83,6 +84,7 @@ struct host_data {
8384

8485
/* stream info */
8586
struct sof_ipc_stream_posn posn; /* TODO: update this */
87+
struct ipc_msg *msg; /**< host notification */
8688
};
8789

8890
static inline struct dma_sg_elem *next_buffer(struct hc_buf *hc)
@@ -155,7 +157,9 @@ static void host_update_position(struct comp_dev *dev, uint32_t bytes)
155157
* (updates position first, by calling ops.position())
156158
*/
157159
pipeline_get_timestamp(dev->pipeline, dev, &hd->posn);
158-
ipc_stream_send_position(dev, &hd->posn);
160+
mailbox_stream_write(dev->pipeline->posn_offset,
161+
&hd->posn, sizeof(hd->posn));
162+
ipc_msg_send(hd->msg, &hd->posn, false);
159163
}
160164
}
161165
}
@@ -364,6 +368,15 @@ static struct comp_dev *host_new(const struct comp_driver *drv,
364368

365369
ipc_build_stream_posn(&hd->posn, SOF_IPC_STREAM_POSITION, comp->id);
366370

371+
hd->msg = ipc_msg_init(hd->posn.rhdr.hdr.cmd, sizeof(hd->posn));
372+
if (!hd->msg) {
373+
comp_err(dev, "host_new() error: ipc_msg_init failed");
374+
dma_put(hd->dma);
375+
rfree(hd);
376+
rfree(dev);
377+
return NULL;
378+
}
379+
367380
hd->chan = NULL;
368381
hd->copy_type = COMP_COPY_NORMAL;
369382
dev->state = COMP_STATE_READY;
@@ -379,6 +392,7 @@ static void host_free(struct comp_dev *dev)
379392

380393
dma_put(hd->dma);
381394

395+
ipc_msg_free(hd->msg);
382396
dma_sg_free(&hd->config.elem_array);
383397
rfree(hd);
384398
rfree(dev);

src/audio/pipeline.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313
#include <sof/drivers/ipc.h>
1414
#include <sof/drivers/timer.h>
1515
#include <sof/lib/alloc.h>
16+
#include <sof/lib/mailbox.h>
1617
#include <sof/list.h>
1718
#include <sof/math/numbers.h>
1819
#include <sof/schedule/ll_schedule.h>
1920
#include <sof/schedule/schedule.h>
2021
#include <sof/schedule/task.h>
2122
#include <sof/spinlock.h>
2223
#include <sof/string.h>
24+
#include <ipc/header.h>
2325
#include <ipc/stream.h>
2426
#include <ipc/topology.h>
2527
#include <errno.h>
@@ -41,6 +43,7 @@ static enum task_state pipeline_task(void *arg);
4143
struct pipeline *pipeline_new(struct sof_ipc_pipe_new *pipe_desc,
4244
struct comp_dev *cd)
4345
{
46+
struct sof_ipc_stream_posn posn;
4447
struct pipeline *p;
4548
int ret;
4649

@@ -63,6 +66,17 @@ struct pipeline *pipeline_new(struct sof_ipc_pipe_new *pipe_desc,
6366
pipe_desc, sizeof(*pipe_desc));
6467
assert(!ret);
6568

69+
/* just for retrieving valid ipc_msg header */
70+
ipc_build_stream_posn(&posn, SOF_IPC_STREAM_TRIG_XRUN,
71+
p->ipc_pipe.comp_id);
72+
73+
p->msg = ipc_msg_init(posn.rhdr.hdr.cmd, sizeof(posn));
74+
if (!p->msg) {
75+
pipe_cl_err("pipeline_new() error: ipc_msg_init failed");
76+
rfree(p);
77+
return NULL;
78+
}
79+
6680
return p;
6781
}
6882

@@ -241,6 +255,8 @@ int pipeline_free(struct pipeline *p)
241255
rfree(p->pipe_task);
242256
}
243257

258+
ipc_msg_free(p->msg);
259+
244260
/* now free the pipeline */
245261
rfree(p);
246262

@@ -829,7 +845,9 @@ static int pipeline_comp_xrun(struct comp_dev *current,
829845
platform_host_timestamp(current, ppl_data->posn);
830846

831847
/* send XRUN to host */
832-
ipc_stream_send_xrun(current, ppl_data->posn);
848+
mailbox_stream_write(ppl_data->p->posn_offset, ppl_data->posn,
849+
sizeof(*ppl_data->posn));
850+
ipc_msg_send(ppl_data->p->msg, ppl_data->posn, true);
833851
}
834852

835853
return pipeline_for_each_comp(current, &pipeline_comp_xrun, data, NULL,
@@ -865,6 +883,7 @@ void pipeline_xrun(struct pipeline *p, struct comp_dev *dev,
865883
posn.xrun_size = bytes;
866884
posn.xrun_comp_id = dev_comp_id(dev);
867885
data.posn = &posn;
886+
data.p = p;
868887

869888
pipeline_comp_xrun(dev, NULL, &data, dev->direction);
870889
}

src/drivers/imx/ipc.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,8 @@ void ipc_platform_complete_cmd(void *data)
112112
int ipc_platform_send_msg(struct ipc_msg *msg)
113113
{
114114
struct ipc *ipc = ipc_get();
115-
uint32_t flags;
116115
int ret = 0;
117116

118-
spin_lock_irq(&ipc->lock, flags);
119-
120117
/* can't send notification when one is in progress */
121118
if (ipc->is_notification_pending ||
122119
imx_mu_read(IMX_MU_xCR) & IMX_MU_xCR_GIRn(1)) {
@@ -134,15 +131,11 @@ int ipc_platform_send_msg(struct ipc_msg *msg)
134131
/* now interrupt host to tell it we have sent a message */
135132
imx_mu_xcr_rmw(IMX_MU_xCR_GIRn(1), 0);
136133

137-
list_item_append(&msg->list, &ipc->empty_list);
138-
139134
platform_shared_commit(msg, sizeof(*msg));
140135

141136
out:
142137
platform_shared_commit(ipc, sizeof(*ipc));
143138

144-
spin_unlock_irq(&ipc->lock, flags);
145-
146139
return ret;
147140
}
148141

src/drivers/intel/baytrail/ipc.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,8 @@ void ipc_platform_complete_cmd(void *data)
100100
int ipc_platform_send_msg(struct ipc_msg *msg)
101101
{
102102
struct ipc *ipc = ipc_get();
103-
uint32_t flags;
104103
int ret = 0;
105104

106-
spin_lock_irq(&ipc->lock, flags);
107-
108105
/* can't send notification when one is in progress */
109106
if (ipc->is_notification_pending ||
110107
shim_read(SHIM_IPCDH) & (SHIM_IPCDH_BUSY | SHIM_IPCDH_DONE)) {
@@ -123,15 +120,11 @@ int ipc_platform_send_msg(struct ipc_msg *msg)
123120
shim_write(SHIM_IPCDL, msg->header);
124121
shim_write(SHIM_IPCDH, SHIM_IPCDH_BUSY);
125122

126-
list_item_append(&msg->list, &ipc->empty_list);
127-
128123
platform_shared_commit(msg, sizeof(*msg));
129124

130125
out:
131126
platform_shared_commit(ipc, sizeof(*ipc));
132127

133-
spin_unlock_irq(&ipc->lock, flags);
134-
135128
return ret;
136129
}
137130

src/drivers/intel/cavs/ipc.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,8 @@ void ipc_platform_complete_cmd(void *data)
246246
int ipc_platform_send_msg(struct ipc_msg *msg)
247247
{
248248
struct ipc *ipc = ipc_get();
249-
uint32_t flags;
250249
int ret = 0;
251250

252-
spin_lock_irq(&ipc->lock, flags);
253-
254251
if (ipc->is_notification_pending ||
255252
#if CAVS_VERSION == CAVS_VERSION_1_5
256253
ipc_read(IPC_DIPCI) & IPC_DIPCI_BUSY) {
@@ -278,15 +275,11 @@ int ipc_platform_send_msg(struct ipc_msg *msg)
278275
ipc_write(IPC_DIPCIDR, 0x80000000 | msg->header);
279276
#endif
280277

281-
list_item_append(&msg->list, &ipc->empty_list);
282-
283278
platform_shared_commit(msg, sizeof(*msg));
284279

285280
out:
286281
platform_shared_commit(ipc, sizeof(*ipc));
287282

288-
spin_unlock_irq(&ipc->lock, flags);
289-
290283
return ret;
291284
}
292285

src/drivers/intel/cavs/sue-ipc.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ void ipc_platform_complete_cmd(void *data)
5454
int ipc_platform_send_msg(struct ipc_msg *msg)
5555
{
5656
struct ipc *ipc = ipc_get();
57-
uint32_t flags;
58-
59-
spin_lock_irq(&ipc->lock, flags);
6057

6158
/* now send the message */
6259
mailbox_dspbox_write(0, msg->tx_data, msg->tx_size);
@@ -65,12 +62,8 @@ int ipc_platform_send_msg(struct ipc_msg *msg)
6562

6663
/* now interrupt host to tell it we have message sent */
6764

68-
list_item_append(&msg->list, &ipc->empty_list);
69-
7065
platform_shared_commit(ipc, sizeof(*ipc));
7166

72-
spin_unlock_irq(&ipc->lock, flags);
73-
7467
return 0;
7568
}
7669

src/drivers/intel/haswell/ipc.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,8 @@ void ipc_platform_complete_cmd(void *data)
102102
int ipc_platform_send_msg(struct ipc_msg *msg)
103103
{
104104
struct ipc *ipc = ipc_get();
105-
uint32_t flags;
106105
int ret = 0;
107106

108-
spin_lock_irq(&ipc->lock, flags);
109-
110107
/* can't send nofication when one is in progress */
111108
if (ipc->is_notification_pending ||
112109
shim_read(SHIM_IPCD) & (SHIM_IPCD_BUSY | SHIM_IPCD_DONE)) {
@@ -124,15 +121,11 @@ int ipc_platform_send_msg(struct ipc_msg *msg)
124121
/* now interrupt host to tell it we have message sent */
125122
shim_write(SHIM_IPCD, SHIM_IPCD_BUSY);
126123

127-
list_item_append(&msg->list, &ipc->empty_list);
128-
129124
platform_shared_commit(msg, sizeof(*msg));
130125

131126
out:
132127
platform_shared_commit(ipc, sizeof(*ipc));
133128

134-
spin_unlock_irq(&ipc->lock, flags);
135-
136129
return ret;
137130
}
138131

src/include/sof/audio/pipeline.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#ifndef __SOF_AUDIO_PIPELINE_H__
99
#define __SOF_AUDIO_PIPELINE_H__
1010

11+
#include <sof/drivers/ipc.h>
1112
#include <sof/lib/cpu.h>
1213
#include <sof/trace/trace.h>
1314
#include <ipc/topology.h>
@@ -92,6 +93,7 @@ struct pipeline {
9293

9394
/* position update */
9495
uint32_t posn_offset; /* position update array offset*/
96+
struct ipc_msg *msg;
9597
};
9698

9799
/* static pipeline */

src/include/sof/drivers/ipc.h

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ struct ipc_msg;
5050
#define trace_ipc_error(format, ...) \
5151
trace_error(TRACE_CLASS_IPC, format, ##__VA_ARGS__)
5252

53-
#define MSG_QUEUE_SIZE 12
54-
5553
#define COMP_TYPE_COMPONENT 1
5654
#define COMP_TYPE_BUFFER 2
5755
#define COMP_TYPE_PIPELINE 3
@@ -97,7 +95,6 @@ struct ipc {
9795
int pm_prepare_D3; /* do we need to prepare for D3 */
9896

9997
struct list_item msg_list; /* queue of messages to be sent */
100-
struct list_item empty_list; /* queue of empty messages */
10198
bool is_notification_pending; /* notification is being sent to host */
10299

103100
struct list_item comp_list; /* list of component devices */
@@ -226,21 +223,6 @@ void ipc_free(struct ipc *ipc);
226223

227224
void ipc_schedule_process(struct ipc *ipc);
228225

229-
int ipc_stream_send_position(struct comp_dev *cdev,
230-
struct sof_ipc_stream_posn *posn);
231-
void ipc_build_comp_notification(const struct comp_dev *cdev,
232-
struct sof_ipc_comp_event *event);
233-
int ipc_send_comp_notification(const struct comp_dev *cdev,
234-
struct sof_ipc_comp_event *event);
235-
int ipc_stream_send_xrun(struct comp_dev *cdev,
236-
struct sof_ipc_stream_posn *posn);
237-
238-
void ipc_prepare_host_message(struct ipc_msg *msg, uint32_t header,
239-
void *tx_data, size_t tx_bytes);
240-
241-
int ipc_queue_host_message(struct ipc *ipc, uint32_t header, void *tx_data,
242-
size_t tx_bytes, bool replace);
243-
244226
int ipc_platform_send_msg(struct ipc_msg *msg);
245227

246228
void ipc_send_queued_msg(void);

0 commit comments

Comments
 (0)